Skip to content
Development
Skill

/gen-devcontainer

Codespaces hostRequirements.storage (e.g. `16gb`, `32GiB`). Default unset.

From plugin
nyann
641 skills41 commands3 hooks
Install
$ npx -y skills add thettwe/nyann --skill gen-devcontainer --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/gen-devcontainer

Context preview

The summary Claude sees to decide when to auto-load this skill.

Codespaces hostRequirements.storage (e.g. `16gb`, `32GiB`). Default unset.

SKILL.md

gen-devcontainer.SKILL.md
name: gen-devcontainer
description: >
  Generate a `.devcontainer/devcontainer.json` keyed to the project's
  primary language so `gh codespace create` (or VS Code's "Reopen in
  Container") gives anyone on the team a ready-to-go env with the
  right runtime, GH CLI, git-lfs, and language-tier VS Code
  extensions pre-installed. Preview-by-default; idempotent on apply
  (no-op on identical bytes, diff-and-refuse on divergence unless
  `--force-overwrite`).
  TRIGGER when the user says "add a devcontainer", "set up
  codespaces", "scaffold devcontainer.json", "reopen in container",
  "configure dev environment", "containerized dev env", "make this
  work in codespaces", "add VS Code container", "wire up
  devcontainer", "/nyann:gen-devcontainer". Also trigger when a user
  asks "how do I run this in Codespaces" and there's no
  `.devcontainer/` directory yet.
  Do NOT trigger on "build a Docker image for production" — that's
  a Dockerfile concern outside devcontainer scope. Do NOT trigger on
  "fix my devcontainer build" — that's debugging an existing setup,
  not generating one (read the file with the user instead).
arguments:
  - name: language
    description: Primary language — one of node, python, go, rust, dart, java, dotnet, php, ruby, swift, elixir, cpp. Maps from StackDescriptor.primary_language (typescript/javascript → node, csharp → dotnet).
  - name: name
    description: Devcontainer display name (surfaced in 'Open in Container' picker). Default is the repo basename when --target is supplied, otherwise `<language>-devcontainer`.
    optional: true
  - name: target
    description: Path to the repo. Required only when `--apply` is set.
    optional: true
  - name: apply
    description: Write the devcontainer.json to `<target>/.devcontainer/devcontainer.json`. Default is preview-to-stdout.
    optional: true
  - name: force-overwrite
    description: Overwrite an existing devcontainer.json whose content differs. Without it, the script prints a diff and exits 3.
    optional: true
  - name: port
    description: Repeatable. Forward a port from the container to the host (1-65535). Common picks - 3000/4200/5173 web dev, 8000/8080 APIs.
    optional: true
  - name: feature
    description: Repeatable. Extra devcontainer feature ref to merge onto the base set (gh CLI, git-lfs, common-utils). Always include a version pin.
    optional: true
  - name: extension
    description: Repeatable. Extra VS Code extension ID (`publisher.extension` format) to merge onto the per-language base set.
    optional: true
  - name: post-create-command
    description: Override the default per-language postCreateCommand. Empty string disables postCreateCommand entirely.
    optional: true
  - name: cpus
    description: Codespaces hostRequirements.cpus (2-32). Default unset (lets Codespaces pick).
    optional: true
  - name: memory
    description: Codespaces hostRequirements.memory (e.g. `4gb`, `8GiB`). Default unset.
    optional: true
  - name: storage
    description: Codespaces hostRequirements.storage (e.g. `16gb`, `32GiB`). Default unset.
    optional: true

gen-devcontainer

Wraps `bin/gen-devcontainer.sh`. Emits a devcontainer.json; preview- by-default; idempotent on apply.

When to trigger

  • User wants a Codespaces-ready repo and there's no `.devcontainer/`

directory yet.

  • User wants to refresh an existing devcontainer.json after upgrading

nyann (base image tags + extension lists shift with the `snapshot_version` comment in the file).

  • User wants to add forwarded ports / cpus / memory to an existing

devcontainer (use `--port 3000 --cpus 4 --memory 8gb`).

When NOT to trigger

  • User wants a **production Dockerfile** — that's an entirely

different concern; devcontainer.json is dev-environment only.

  • User wants to **debug** a broken devcontainer build — open the

existing file with them; this skill generates fresh, not diagnoses.

  • User is on a non-Codespaces, non-VS Code editor — the file still

works under JetBrains' Dev Containers plugin and `devcontainer open` (CLI), but flag the broader VS Code-first defaults.

Picking the language

Read `StackDescriptor.primary_language` from `bin/detect-stack.sh`:

| StackDescriptor.primary_language | --language | |---|---| | `typescript` / `javascript` | `node` | | `python` | `python` | | `go` | `go` | | `rust` | `rust` | | `dart` | `dart` | | `java` / `kotlin` | `java` | | `csharp` / `dotnet` | `dotnet` | | `php` | `php` | | `ruby` | `ruby` | | `swift` | `swift` | | `elixir` | `elixir` | | `cpp` / `c` | `cpp` |

For polyglot monorepos (`workspaces[]` present), pick the language of the most-important workspace OR ask the user — running multiple devcontainers from a single repo is uncommon and confusing.

Preview, then apply

Always preview first. Show the rendered JSON; wait for confirmation:

bin/gen-devcontainer.sh --language python --name my-app

Then on confirmation:

bin/gen-devcontainer.sh --language python --name my-app \
  --target . --apply

If the destination already matches: log "unchanged" and exit. If it differs: print the unified diff to stderr, exit 3, prompt the user before re-running with `--force-overwrite`.

Output shape

`.devcontainer/devcontainer.json` containing:

  • `$schema` pointing at the official devcontainer spec
  • `$comment` tagging the nyann snapshot version
  • `name` (display name in 'Open in Container' picker)
  • `image` (per-language, pinned to a major:minor tag)
  • `features` (gh CLI, git-lfs, common-utils — version-pinned)
  • `customizations.vscode.extensions` (per-language pack + gitlens + git-graph)
  • `postCreateCommand` (per-language dep install — `npm ci`, `uv sync`, `cargo fetch`, etc.)
  • `forwardPorts` (when `--port` flag(s) supplied)
  • `hostRequirements` (when `--cpus` / `--memory` / `--storage` supplied)

Defaults explained

  • **Base image**: Microsoft devcontainers/<lang> images where they

exist (well-maintained, security-scanned, multi-arch). Vend

Read more
Ships withnyann

ငြမ်း is Burmese for scaffolding. Nyann is the Claude Code plugin that picks expert git defaults for your stack — branching, working hooks (Husky / pre-commit.com / lefthook), commits, releases, CI, docs — then keeps the repo on those rails through every PR

Get the whole plugin

Other skills on nyann.