Files
coder/docs/README.md
T
Nick Vigilante f1ed84ffab docs: author the sidebar in per-section YAML compiled to manifest.json (#30165)
## Summary

The docs sidebar is now written as YAML files under `docs/manifest/`,
one route and its direct children per file, and a new tool,
`scripts/docsmanifestgen`, compiles them into `docs/manifest.json`.
Moving two top-level sections is now a 2-line change in
`docs/manifest/index.yml` instead of a diff of hundreds of lines in a
2,600-line JSON file.
The compiled `docs/manifest.json` is byte-identical to `main`, so
coder.com, docs-preview, deploy-docs, and offlinedocs need no changes.

Refs
[DOCS-1131](https://linear.app/codercom/issue/DOCS-1131/author-the-docs-sidebar-in-per-section-yaml-compiled-to)

## Changes

- **Sources:** `docs/manifest/index.yml` holds `versions` and the
section files in sidebar order.
Each section file (`about.yml`, `admin.yml`, and so on) holds one
top-level route.
- **One level per file:** a file holds one route and its direct
children.
A child with children of its own, or with `children_from`, lives in its
own file in a directory named after the parent file, and the parent
lists it as `- include: admin/users.yml`.
For example, `get-started.yml` includes
`get-started/customize-your-template.yml`, which lists that page's
children.
  The 8 section files split into 53 source files.
- **`scripts/docsmanifestgen`:** `build` compiles the sources into
`docs/manifest.json`, `fmt` formats them, and `check` validates them.
- Keys must be known (a typo like `titel:` fails with a line number) and
appear in a fixed order in both the YAML and the JSON.
- Every `path` must exist, and every file under `docs/manifest/` must be
referenced from `index.yml`, an `include`, or a `children_from`.
- A grandchild in the same file fails with a message to move the child
into its own file, and an `include` entry can't set other keys or name a
file that is already used.
- A comment on the same line as a `title` or `description` is rejected,
because an unquoted ` #` would silently cut off the value.
- **Generated fragments:** `clidocgen` and `apidocgen` no longer rewrite
the manifest.
They write the Command Line and REST API children to
`docs/manifest/generated/*.json`, which the sources pull in with
`children_from`.
  The tool accepts fragments as YAML or JSON.
- The hand-written REST API descriptions and states moved into the YAML,
attached to generated routes by title.
A YAML entry that matches no generated route, or disagrees with one,
fails the build instead of being dropped silently.
- **Shared code:** loading, validation, and fragment merging live in
`scripts/docgenenv/sources.go`, so the generators and the tool share one
loader.
`docgenenv.Route` gains YAML tags and the source-only `ChildrenFrom` and
`Include` fields (`json:"-"`).
`LoadManifest` is removed because nothing reads the compiled JSON
anymore.
- **Makefile:**
- `docs/manifest.json` is built from the sources and fragments, which
replaces the `_gen/manifest-staging.json` handoff.
- Each fragment has its own rule, and the fragments are added to the
`.PRECIOUS`, `GEN_FILES`, and `gen/mark-fresh` lists.
  - `DOCS_MANIFEST_SOURCES` finds the source files recursively.
- New targets: `fmt/docs-manifest` (part of `fmt`), `lint/docs-manifest`
(part of `lint`), and `gen/docs-manifest`, the quick path after a
sidebar-only edit that skips regenerating the CLI and API fragments.
- **`.gitattributes`:** marks `docs/manifest.json` and
`docs/manifest/generated/*` as generated so GitHub collapses them in
diffs.
- **Guidance:** the content guidelines, the style guide,
`DOCS_STYLE_GUIDE.md`, the `write-docs` and `doc-check` skills,
`docs/README.md`, and `docs/tutorials/example-guide.md` now point to the
YAML sources instead of `docs/manifest.json`.

## Testing

- Split today's `docs/manifest.json` into the sources, rebuilt it, and
confirmed the output is byte-identical to `main`.
After splitting the sources to one level per file, the rebuilt
`docs/manifest.json` and a fresh `clidocgen` CLI fragment were still
byte-identical, and `LoadManifestSources` still finds the REST API and
Command Line routes through their includes.
After rebasing onto `main`, both commits rebuild `main`'s
`docs/manifest.json` byte for byte.
- Hand-edited `docs/manifest.json` and a YAML source, then rebuilt: the
YAML change persisted and the JSON edit was overwritten.
CI's `make -B gen` plus `check_unstaged.sh` fails on a committed hand
edit to the JSON.
- Deleted both fragments and ran `make docs/manifest.json` in a fresh
worktree, which regenerated them through swag and `clidocgen`.
`docs/manifest.json`, the fragments, and every generated CLI and API
page had no diff.
- Swapped User Guides and Administration in `index.yml`: 2 changed lines
in the source, 166 generated lines in `docs/manifest.json`.
  Swapping back restored the file exactly.
- `go test` for `scripts/docgenenv`, `scripts/docsmanifestgen`,
`scripts/clidocgen`, and `scripts/apidocgen/postprocess`.
The new tests cover merging, includes, every validation error,
idempotent formatting that keeps comments, and a check that the key
order matches the struct field order.
- `golangci-lint` on the changed packages, and the full `make
pre-commit` hook (gen, fmt, lint including `lint/docs-manifest`, and the
slim build).

## Notes

- Open PRs that edit `docs/manifest.json` will need to redo their
sidebar changes in the YAML sources after this merges.
- #30161 (merged) stopped escaping `&`, `<`, and `>` in
`docs/manifest.json`.
This PR carries that over: all manifest JSON escaping is in
`docgenenv.MarshalJSON`, which sets `enc.SetEscapeHTML(false)`, and
`Manifest.Marshal` from #30161 is gone because the generators no longer
write the manifest.
- #30129 (merged) flattened `admin/external-auth/index.md` and
`ai-coder/agents/tools/index.md` to single files, and the YAML sources
use the new paths.
- The CLI index and REST API page front matter still update only on a
full `make gen` when their sidebar metadata changes, as it did before.
That gap and the overall cost of `make gen` are tracked in
[DOCS-1141](https://linear.app/codercom/issue/DOCS-1141/reduce-the-compute-cost-of-make-gen).

<details>
<summary>Decision log</summary>

### Goal

Make the sidebar easy to reorder and hard to break, with strict key
order and YAML sources, while keeping `docs/manifest.json` as the file
downstream systems read.

### Jsonnet vs. a custom tool

Jsonnet was evaluated first and rejected, based on tests against
go-jsonnet v0.22.0:

- Jsonnet always sorts object keys alphabetically, and there's no option
to keep them in order (`preserve_order` isn't a parameter of
`manifestJsonEx` or `objectFieldsEx`).
Passing today's manifest through Jsonnet and then biome changed 2,114 of
2,478 lines.
- Unknown keys pass through silently, so a `titel:` typo ends up in the
output.
- The sources would be `.jsonnet` files, not YAML.
Reading YAML takes `std.parseYaml(importstr ...)`, and the keys still
come out sorted.
- Restoring key order would need a Go step after Jsonnet anyway, and
that step is most of this tool.

Decoding YAML into Go structs with yaml.v3 (already a dependency) gives
key order from the struct, rejects unknown keys, keeps comments, and
reproduced the current manifest byte for byte.

### Design choices

- **Ordered by `index.yml`:** reordering sections touches only the
index.
- **One route and its direct children per file:** every file stays short
and flat, so a subsection can be found, reviewed, and moved as one file.
Files nest by parent file name rather than by docs path, so the
directory tree matches the sidebar tree.
Include paths are relative to `docs/manifest/`, like `children_from`, so
every reference to a file is spelled the same way.
A child with `children_from` also gets its own file, so the rule has no
exceptions.
- **Generated subtrees in their own fragments:** the generators can't
safely rewrite hand-edited YAML, so they own separate files.
Hand-written metadata for generated routes lives in the YAML, attached
by title, so descriptions never live in a generated file.
- **Key order enforced in both sources and output:** `fmt` rewrites the
sources, `check` fails on unformatted sources, and the output order
comes from the `docgenenv.Route` field order.
- **`&` left unescaped:** the output matches `main` after #30161, which
stopped escaping `&` downstream.
- **`gen/docs-manifest` separate from `fmt`:** keeping manifest assembly
out of `fmt` means `make -j gen fmt` never has two jobs writing
`docs/manifest.json` at once.
- **YAML pitfalls:** unquoted `no` and `123` stay strings because the
fields are typed as strings, an unquoted `: ` is a parse error, and the
silent ` #` truncation is rejected by the comment check.

### Out of scope

- Replacing `&` with "and" in titles (a style question).
- Reducing the cost of `make gen` (DOCS-1141).

</details>

---

_This PR was generated by Coder Agents on behalf of @nickvigilante._
2026-09-30 21:27:14 +00:00

7.7 KiB

title, markdown_url
title markdown_url
About /docs.md

Coder is a self-hosted platform for running AI coding agents and cloud development environments on infrastructure you control. It works with any cloud, IDE, OS, Git provider, and IDP.

Coder platform showing templates and a running workspace

Coder Workspaces

Coder Workspaces are cloud development environments defined with Terraform, connected through a secure Wireguard tunnel, and automatically shut down when not in use. Agents and developers share the same workspace infrastructure.

  • Defined in Terraform: Templates describe the infrastructure for each workspace, from EC2 VMs and Kubernetes Pods to Docker containers.
  • Any architecture and OS: Support ARM and x86-64 across Windows, Linux, and macOS from a single deployment.
  • Managed by admins: Platform teams create and maintain templates that enforce approved images, resource limits, and security policies.
  • Accessed from any IDE: Connect through VS Code, JetBrains, Cursor, a web terminal, remote desktop, or SSH.
  • Automatic shutdown: Idle workspaces stop automatically to reduce cloud spend, and restart in seconds when needed.

Coder Agents

Coder Agents is a native AI coding agent built into Coder. The agent loop runs in the Coder control plane on your infrastructure, not in the workspace and not in a vendor's cloud. Developers interact with agents through the web UI or the REST API for programmatic and CI-driven workflows.

  • Self-hosted agent loop: The control plane handles planning, model calls, and tool dispatch. Workspaces have zero AI awareness.
  • No API keys in workspaces: LLM credentials stay in the control plane.
  • Any model: Anthropic, OpenAI, Google, Bedrock, or self-hosted endpoints. Switching is a configuration change.
  • Governance and cost controls: Centralized model approval, per-user spend limits, and audit logging.
  • Open source and inspectable: The full platform is available to audit and extend.

Coder Agents chat interface with git diff sidebar

IDE support

IDE icons

You can use:

Why remote development

Provisioning consistent development environments for a large engineering team is difficult. Each developer has preferences for operating systems, editors, and toolchains, and ensuring a reliable build environment across all of them is a maintenance burden. A missed step during onboarding or an unsupported local configuration can cost hours of debugging.

Remote development solves this by moving the environment off the developer's machine and into managed infrastructure. The developer's laptop becomes a portal into the actual compute where work happens. If a device is lost or replaced, access is simply revoked; no source code or credentials are stored locally.

This approach provides:

  • Speed: Server-grade hardware accelerates builds, tests, and large workloads without requiring expensive local machines.
  • Consistency: Infrastructure tools such as Terraform, nix, Docker, and Dev Containers produce identical environments for every developer.
  • Security: Source code stays on private servers. Users and groups are managed through SSO and RBAC.
  • Compatibility: Workspaces share infrastructure configurations with staging and production, reducing configuration drift.
  • Accessibility: Browser-based IDEs and remote IDE extensions let developers work from any device, including lightweight laptops, Chromebooks, and tablets.

Read more on the Coder blog, the Slack engineering blog, or from Alex Ellis at OpenFaaS.

Why Coder

The key difference between Coder and other platforms is that the entire system, agent loop, control plane, model routing, and workspace provisioning, runs on infrastructure you control.

For agents, this means platform teams can:

  • Run the entire agent loop on their infrastructure, with no SaaS dependency for orchestration.
  • Define MCP servers, skills, and system prompts centrally so every agent session starts with the same tools, policies, and context.
  • Keep LLM credentials out of workspaces entirely.
  • Tie every agent action to an authenticated user identity.
  • Support air-gapped and restricted-network deployments with self-hosted models.

For workspaces, this means admins can:

  • Support any architecture (ARM, x86-64) and operating system (Windows, Linux, macOS).
  • Modify pod/container specs, such as adding disks, managing network policies, or setting/updating environment variables.
  • Use VM or dedicated workspaces, developing with Kernel features (no container knowledge required).
  • Enable persistent workspaces, which are like local machines, but faster and hosted by a cloud service.

Pricing

Coder is free and open source under the GNU Affero General Public License v3.0. All developer productivity features are included in the open source version. A Premium license is available for enhanced support and custom deployments.

How Coder works

Coder workspaces are represented with Terraform, but you do not need to know Terraform to get started. The Coder Registry provides production-ready templates for AWS EC2, Azure, Google Cloud, Kubernetes, and other providers.

Providers and compute environmentsProviders and compute environments

Workspaces can include more than just compute. Terraform can add storage buckets, secrets, sidecars, and other resources.

See the templates documentation for details.

What Coder is not

  • Coder is not an infrastructure as code (IaC) platform.

    • Terraform is the first IaC provisioner in Coder, allowing Coder admins to define Terraform resources as Coder workspaces.
  • Coder is not a DevOps/CI platform.

    • Coder workspaces can be configured to follow best practices for cloud-service-based workloads, but Coder is not responsible for how you define or deploy the software you write.
  • Coder is not an online IDE.

    • Coder supports common editors, such as VS Code, vim, and JetBrains, all over HTTPS or SSH.
  • Coder is not a collaboration platform.

    • You can use Git with your favorite Git platform and dedicated IDE extensions for pull requests, code reviews, and pair programming.
  • Coder is not a SaaS/fully-managed offering.

    • Coder is a self-hosted solution. You must host Coder in a private data center or on a cloud service, such as AWS, Azure, or GCP.

Learn more