DevContainer/Feature/Concept/Features vs Templates
Properties
DevContainer Features vs Templates
Overview
- DevContainer Features and DevContainer/Templates are two complementary building blocks in the Dev Containers ecosystem. Features define a pluggable, reusable way to define a container's functionality, while Templates define full development environments, including VSCode/Extensions, etc, typically in such a way that relies on features.
Context
Key Principles
Mechanism
DevContainer Features
- Are modular extensions added under the
featureskey indevcontainer.json. - Contain installation logic (usually
install.sh) and adevcontainer-feature.jsondescriptor. - Can be published to container registries (e.g.,
ghcr.io/devcontainers/features/node:1). - Applied during build time to modify the base image.
- Are modular extensions added under the
DevContainer/Templates
- Provide full environment scaffolds that include a Dockerfile,
devcontainer.json, extensions, and Features. - Defined by a
devcontainer-template.jsonfile that describes the setup and references required Features. - Used when initializing new repositories or Codespaces.
- Serve as opinionated starting points for teams or language stacks.
- Provide full environment scaffolds that include a Dockerfile,
Examples
DevContainer Feature #Example
DevContainer/Template #Example
TypeScript Node Template
- Scaffolds a Node + TypeScript project environment:
- Template Configuration
- json
{ "id": "typescript-node", "version": "4.0.2", "name": "Node.js & TypeScript", "description": "Develop Node.js based applications in TypeScript. Includes Node.js, eslint, nvm, yarn, and the TypeScript compiler.", "documentationURL": "https://github.com/devcontainers/templates/tree/main/src/typescript-node", "publisher": "Dev Container Spec Maintainers", "licenseURL": "https://github.com/devcontainers/templates/blob/main/LICENSE", "options": { "imageVariant": { "type": "string", "description": "Node.js version (use -bookworm, -bullseye variants on local arm64/Apple Silicon):", "proposals": [ "22-bookworm", "22-bullseye", "20-bookworm", "18-bookworm", "20-bullseye", "18-bullseye" ], "default": "22-bookworm" } }, "platforms": [ "Node.js", "TypeScript" ], "optionalPaths": [ ".github/*" ] }
- DevContainer Configuration
- json
// For format details, see https://aka.ms/devcontainer.json. For config options, see the // README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node { "name": "Node.js & TypeScript", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "image": "mcr.microsoft.com/devcontainers/typescript-node:1-${templateOption:imageVariant}" // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "yarn install", // Configure tool-specific properties. // "customizations": {}, // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. // "remoteUser": "root" }
- Template Configuration
- Scaffolds a Node + TypeScript project environment:
Misconceptions
Related
Conceptual Overview — DevContainer Features vs Templates
🧩 Core Idea
🔍 Conceptual Difference
Aspect Features Templates Purpose Add or configure tools in a dev container Define and scaffold full dev environments Granularity Micro — one capability per module Macro — full environment definition Timing Applied during container build Applied when initializing a new repo or Codespace Analogy Like installing packages ( apt install node)Like generating a new project ( cookiecutter node-template)Scope Inside the container image Repository + workspace structure Visibility Used under the featureskeyUsed via the Dev Container Template UI or CLI
⚙️ What You Can Do with Templates That Features Can't
🧠 Conceptual Model
✅ Practical Example
- A team template might include:
- json
{ "name": "TypeScript Course Environment", "features": { "ghcr.io/company/team-devcontainers/pnpm": {}, "ghcr.io/company/team-devcontainers/postgres": {} }, "customizations": { "vscode": { "extensions": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"] } } } - This defines a consistent environment across all TypeScript course repos, while each Feature handles a modular install task.
📎 Summary