Files
coder/docs/about/contributing/templates.md
T
Nick Vigilante c84aa564ba docs: normalize code-fence languages for Shiki compatibility (#27161)
Normalizes non-standard code-fence language tags across `docs/**` so a
strict highlighter (Shiki, used by Fumadocs) won't fail the build on an
unrecognized language, and unifies redundant synonym tags onto one
canonical form per language. The current renderer (Speed-Highlight)
detects the language from the code content, not the fence label, so this
drift wasn't visible until now.

## Changes

- `hcl` -> `tf` (199 fences, including indented ones nested in
numbered/bulleted lists). Shiki ships `hcl` and `terraform` as two
distinct grammars (not aliases); every `hcl`-tagged fence in `docs/**`
is actually Terraform resource/data/provider syntax, so the more
specific `terraform` grammar is correct for all of them. `tf` is Shiki's
own alias for that grammar, and it's also what GitHub's own markdown
renderer resolves to the same HCL/Terraform highlighting.
- `pwsh`/`powershell` -> `ps1`. Both `ps` and `ps1` are registered
PowerShell aliases in Shiki, but on GitHub's renderer only `.ps1` is a
registered file extension (`.ps` isn't), so `ps1` renders identically to
`powershell` there today while bare `ps` would silently lose
highlighting.
- `env` -> `dotenv` (a dedicated Shiki grammar for `KEY=VALUE` files)
- `text`/`output`/`none`/`url` -> `txt`. Same built-in plain-text
fallback either way, just shorter.
- `Dockerfile` -> `dockerfile` (lowercase)
- `bash`/`shell` -> `sh` (732 fences). Shiki and GitHub both alias all
three to a single shell grammar; this was already the style guide's
stated preference, just not enforced across the existing corpus until
now.
- `markdown` -> `md` (4 fences). Alias of the same grammar in both Shiki
and GitHub.
- `jsonc` -> `json` (1 fence). The block has no comments or trailing
commas, so it doesn't need the comments-capable grammar.
- `ts` -> `tsx` (2 fences, `docs/about/contributing/frontend.md`).
Verified the actual content tokenizes identically under both grammars,
and a sibling block in the same file already needs `tsx` for real JSX,
so unifying to one tag is safe for this file. Documented a caveat: `tsx`
mis-tokenizes the legacy angle-bracket type-assertion syntax
(`<Type>value`), which is invalid in real `.tsx` files anyway, so use
`value as Type` instead.
- `yml` -> `yaml` (1 fence)
- Updated `docs/.style/style-guide/formatting.md` to document all
canonical tags

`promql` (2 fences) and `caddyfile` (2 fences) are left as-is. Shiki
doesn't bundle a grammar for either, so they need a custom grammar
registration when the site adopts Shiki, rather than degrading to `txt`.
Tracked as follow-up work under DOCS-118 and
[DOCS-544](https://linear.app/codercom/issue/DOCS-544/vendor-a-local-promql-grammar-for-shiki-syntax-highlighting)
(promql).

Does not touch `offlinedocs/`.

Linear:
[DOCS-476](https://linear.app/codercom/issue/DOCS-476/normalize-docs-code-fence-languages-de-risk-shikifumadocs)

<details>
<summary>How the fence tags were verified</summary>

Each tag was tested against a real `shiki@latest` highlighter instance
(`codeToHtml`/`codeToTokens`) and cross-checked against GitHub's
`@wooorm/starry-night` grammar sources (the renderer that actually
displays these `.md` files today, in repo browsing and PR diffs), since
that's what determines whether brevity is safe before Shiki adoption:

```text
FAIL  env        -- Language `env` is not included in this bundle.
FAIL  Dockerfile -- Language `Dockerfile` is not included in this bundle.
FAIL  promql     -- Language `promql` is not included in this bundle.
FAIL  caddyfile  -- Language `caddyfile` is not included in this bundle.
FAIL  pwsh       -- Language `pwsh` is not included in this bundle.
FAIL  output     -- Language `output` is not included in this bundle.
```

`hcl` doesn't error in Shiki, since it's a real grammar, but that's
exactly the trap: it was silently rendering every fence with the generic
HCL grammar instead of the Terraform-specific one. Every `hcl`-tagged
fence in `docs/**` was manually checked against `origin/main` and is
genuinely Terraform content.

For `ts`/`tsx`, tokenizing the actual doc content confirmed identical
output under both grammars; a synthetic test with the legacy
angle-bracket cast syntax confirmed `tsx` degrades on that specific
construct, which the style guide now calls out.

The first normalization pass only matched fence tags at column 0
(`^```tag$`), missing tags indented inside numbered/bulleted lists. A
follow-up pass caught the remaining occurrences at any indentation
level.

</details>


---

*This PR description and the underlying changes were prepared with Coder
Agents assistance.*
2026-07-15 14:07:09 -04:00

14 KiB

Contributing templates

Learn how to create and contribute complete Coder workspace templates to the Coder Registry. Templates provide ready-to-use workspace configurations that users can deploy directly to create development environments.

What are Coder templates

Coder templates are complete Terraform configurations that define entire workspace environments. Unlike modules (which are reusable components), templates provide full infrastructure definitions that include:

  • Infrastructure setup (containers, VMs, cloud resources)
  • Coder agent configuration
  • Development tools and IDE integrations
  • Networking and security settings
  • Complete startup automation

Templates appear on the Coder Registry and can be deployed directly by users.

Tip

If you use an AI coding assistant, the coder-templates agent skill from the Coder Registry can guide you through creating and updating templates with best practices built-in.

Prerequisites

Before contributing templates, ensure you have:

Setup your development environment

  1. Fork and clone the repository:

    git clone https://github.com/your-username/registry.git
    cd registry
    
  2. Install dependencies:

    bun install
    
  3. Understand the structure:

    registry/[namespace]/
    ├── templates/       # Your templates
    ├── .images/         # Namespace avatar and screenshots
    └── README.md        # Namespace description
    

Create your first template

1. Set up your namespace

If you're a new contributor, create your namespace directory:

mkdir -p registry/[your-username]
mkdir -p registry/[your-username]/.images

Add your namespace avatar by downloading your GitHub avatar and saving it as avatar.png:

curl -o registry/[your-username]/.images/avatar.png https://github.com/[your-username].png

Create your namespace README at registry/[your-username]/README.md:

---
display_name: "Your Name"
bio: "Brief description of what you do"
github: "your-username"
avatar: "./.images/avatar.png"
linkedin: "https://www.linkedin.com/in/your-username"
website: "https://your-website.com"
support_email: "support@your-domain.com"
status: "community"
---

# Your Name

Brief description of who you are and what you do.

Note

The linkedin, website, and support_email fields are optional and can be omitted or left empty if not applicable.

2. Create your template directory

Create a directory for your template:

mkdir -p registry/[your-username]/templates/[template-name]
cd registry/[your-username]/templates/[template-name]

3. Build your template

Create main.tf with your complete Terraform configuration:

terraform {
  required_providers {
    coder = {
      source = "coder/coder"
    }
    docker = {
      source = "kreuzwerker/docker"
    }
  }
}

# Coder data sources
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

# Coder agent
resource "coder_agent" "main" {
  arch                   = "amd64"
  os                     = "linux"
  startup_script_timeout = 180
  startup_script = <<-EOT
    set -e

    # Install development tools
    sudo apt-get update
    sudo apt-get install -y curl wget git

    # Additional setup here
  EOT
}

# Registry modules for IDEs and tools
module "code-server" {
  source   = "registry.coder.com/coder/code-server/coder"
  version  = "~> 1.0"
  agent_id = coder_agent.main.id
}

module "git-clone" {
  source   = "registry.coder.com/coder/git-clone/coder"
  version  = "~> 1.0"
  agent_id = coder_agent.main.id
  url      = "https://github.com/example/repo.git"
}

# Infrastructure resources
resource "docker_image" "main" {
  name = "codercom/enterprise-base:ubuntu"
}

resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = docker_image.main.name
  name  = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"

  command = ["sh", "-c", coder_agent.main.init_script]
  env     = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]

  host {
    host = "host.docker.internal"
    ip   = "host-gateway"
  }
}

# Metadata
resource "coder_metadata" "workspace_info" {
  count       = data.coder_workspace.me.start_count
  resource_id = docker_container.workspace[0].id

  item {
    key   = "memory"
    value = "4 GB"
  }

  item {
    key   = "cpu"
    value = "2 cores"
  }
}

4. Document your template

Create README.md with comprehensive documentation:

---
display_name: "Ubuntu Development Environment"
description: "Complete Ubuntu workspace with VS Code, Git, and development tools"
icon: "../../../../.icons/ubuntu.svg"
verified: false
tags: ["ubuntu", "docker", "vscode", "git"]
---

# Ubuntu Development Environment

A complete Ubuntu-based development workspace with VS Code, Git, and essential development tools pre-installed.

## Features

- **Ubuntu 24.04 LTS** base image
- **VS Code** with code-server for browser-based development
- **Git** with automatic repository cloning
- **Node.js** and **npm** for JavaScript development
- **Python 3** with pip
- **Docker** for containerized development

## Requirements

- Docker runtime
- 4 GB RAM minimum
- 2 CPU cores recommended

## Usage

1. Deploy this template in your Coder instance
2. Create a new workspace from the template
3. Access VS Code through the workspace dashboard
4. Start developing in your fully configured environment

## Customization

You can customize this template by:

- Modifying the base image in `docker_image.main`
- Adding additional registry modules
- Adjusting resource allocations
- Including additional development tools

## Troubleshooting

**Issue**: Workspace fails to start
**Solution**: Ensure Docker is running and accessible

**Issue**: VS Code not accessible
**Solution**: Check agent logs and ensure code-server module is properly configured

Template best practices

Design principles

  • Complete environments: Templates should provide everything needed for development
  • Platform-specific: Focus on one platform or use case per template
  • Production-ready: Include proper error handling and resource management
  • User-friendly: Provide clear documentation and sensible defaults

Infrastructure setup

  • Resource efficiency: Use appropriate resource allocations
  • Network configuration: Ensure proper connectivity for development tools
  • Security: Follow security best practices for your platform
  • Scalability: Design for multiple concurrent users

Module integration

Use registry modules for common features:

# VS Code in browser
module "code-server" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/code-server/coder"
  version  = "1.3.0"
  agent_id = coder_agent.example.id
}

# JetBrains IDEs
module "jetbrains" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/jetbrains/coder"
  version  = "1.0.0"
  agent_id = coder_agent.example.id
  folder   = "/home/coder/project"
}

# Git repository cloning
module "git-clone" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/git-clone/coder"
  version  = "1.1.0"
  agent_id = coder_agent.example.id
  url      = "https://github.com/coder/coder"
  base_dir = "~/projects/coder"
}

# File browser interface
module "filebrowser" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/filebrowser/coder"
  version  = "1.1.1"
  agent_id = coder_agent.example.id
}

# Dotfiles management
module "dotfiles" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/dotfiles/coder"
  version  = "1.2.0"
  agent_id = coder_agent.example.id
}

Variables

Provide meaningful customization options:

variable "git_repo_url" {
  description = "Git repository to clone"
  type        = string
  default     = ""
}

variable "instance_type" {
  description = "Instance type for the workspace"
  type        = string
  default     = "t3.medium"
}

variable "workspace_name" {
  description = "Name for the workspace"
  type        = string
  default     = "dev-workspace"
}

Test your template

Local testing

Test your template locally with Coder:

# Navigate to your template directory
cd registry/[your-username]/templates/[template-name]

# Push to Coder for testing
coder templates push test-template -d .

# Create a test workspace
coder create test-workspace --template test-template

Validation checklist

Before submitting your template, verify:

  • Template provisions successfully
  • Agent connects properly
  • All registry modules work correctly
  • VS Code/IDEs are accessible
  • Networking functions properly
  • Resource metadata is accurate
  • Documentation is complete and accurate

Contribute to existing templates

Types of improvements

Bug fixes:

  • Fix setup issues
  • Resolve agent connectivity problems
  • Correct resource configurations

Feature additions:

  • Add new registry modules
  • Include additional development tools
  • Improve startup automation

Platform updates:

  • Update base images or AMIs
  • Adapt to new platform features
  • Improve security configurations

Documentation improvements:

  • Clarify setup requirements
  • Add troubleshooting guides
  • Improve usage examples

Making changes

  1. Test thoroughly: Always test template changes in a Coder instance
  2. Maintain compatibility: Ensure existing workspaces continue to function
  3. Document changes: Update the README with new features or requirements
  4. Follow versioning: Update version numbers for significant changes
  5. Modernize: Use latest provider versions, best practices, and current software versions

Submit your contribution

  1. Create a feature branch:

    git checkout -b feat/add-python-template
    
  2. Test thoroughly:

    # Test with Coder
    coder templates push test-python-template -d .
    coder create test-workspace --template test-python-template
    
    # Format code
    bun fmt
    
  3. Commit with clear messages:

    git add .
    git commit -m "Add Python development template with FastAPI setup"
    
  4. Open a pull request:

    • Use a descriptive title
    • Explain what the template provides
    • Include testing instructions
    • Reference any related issues

Template examples

Docker-based template

# Simple Docker template
resource "docker_container" "workspace" {
  count = data.coder_workspace.me.start_count
  image = "ubuntu:24.04"
  name  = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"

  command = ["sh", "-c", coder_agent.main.init_script]
  env     = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
}

AWS EC2 template

# AWS EC2 template
resource "aws_instance" "workspace" {
  count         = data.coder_workspace.me.start_count
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type

  user_data = coder_agent.main.init_script

  tags = {
    Name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"
  }
}

Kubernetes template

# Kubernetes template
resource "kubernetes_pod" "workspace" {
  count = data.coder_workspace.me.start_count

  metadata {
    name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"
  }

  spec {
    container {
      name  = "workspace"
      image = "ubuntu:24.04"

      command = ["sh", "-c", coder_agent.main.init_script]
      env {
        name  = "CODER_AGENT_TOKEN"
        value = coder_agent.main.token
      }
    }
  }
}

Common issues and solutions

Template development

Issue: Template fails to create resources Solution: Check Terraform syntax and provider configuration

Issue: Agent doesn't connect Solution: Verify agent token and network connectivity

Documentation

Issue: Icon not displaying Solution: Verify icon path and file existence

Platform-specific

Issue: Docker containers not starting Solution: Verify Docker daemon is running and accessible

Issue: Cloud resources failing Solution: Check credentials and permissions

Get help

Next steps

After creating your first template:

  1. Share with the community: Announce your template on Discord or social media
  2. Gather feedback: Iterate based on user suggestions and issues
  3. Create variations: Build templates for different use cases or platforms
  4. Contribute to existing templates: Help maintain and improve the ecosystem

Your templates help developers get productive faster by providing ready-to-use development environments. Happy contributing! 🚀