DevContainers Are Becoming the Default Way to Start Coding a New Project

Every software project eventually produces the sentence "it works on my machine." The root cause is always the same: development environments are local, invisible, and nearly impossible to fully document. You might commit a requirements.txt or a package.json, but you can't commit the Python version, the specific version of a C library linked by a native extension, the environment variables set in your shell profile, or the system tools installed globally. The gap between what's checked in and what's actually running is where debugging goes to die.
Dev Containers are a specification-backed approach to making development environments reproducible, portable, and version-controlled alongside the code. The spec, originally developed by Microsoft for VS Code but now maintained as an open standard under the devcontainers GitHub organization, defines a .devcontainer/devcontainer.json file that describes the full environment: which Docker image or Dockerfile to use, which VS Code extensions to install, which ports to forward, which lifecycle commands to run on startup, and which environment variables to inject.
How It Works
When you open a project with a .devcontainer configuration in VS Code, the IDE prompts you to reopen in a container. It builds or pulls the specified Docker image, runs the container, and mounts your project directory into it. Your editor then operates as if it were running locally, but its language servers, linters, formatters, and debuggers are all executing inside the container against the exact environment specified in the config file. On another developer's machine — or on GitHub Codespaces, or in a CI pipeline — the same container builds and runs identically.
The devcontainer.json format has grown into a reasonably complete environment DSL. You can specify a base image (mcr.microsoft.com/devcontainers/python:3.12, a team's internal image, or a local Dockerfile), install additional system packages via features — small composable environment add-ons maintained by Microsoft and the community for things like Docker-in-Docker, the GitHub CLI, Terraform, or Node.js — and specify post-create commands that run automatically when the container starts. The VS Code customizations.vscode.extensions field ensures every developer opens the project with the same set of extensions installed, without manually coordinating which version of which linter everyone is running.
GitHub Codespaces and the Cloud Dev Environment
GitHub Codespaces is the largest-scale deployment of the Dev Container specification. When you open a Codespace on any GitHub repository — including a fork you've never touched — GitHub builds a container from the repository's devcontainer.json (or a sensible default if none exists) and gives you a fully configured browser-based VS Code connected to it. The development environment is available in about 30 seconds.
For open source contribution, the impact on onboarding is significant. The traditional path to contributing to a project involved cloning, reading a CONTRIBUTING.md, installing language runtimes, figuring out which version of a dependency conflicts with something else on your system, and spending 45 minutes before you'd written a line. A Codespace-enabled repository collapses that to: click "Code," click "Open in Codespace," wait 30 seconds, start coding. For maintainers trying to reduce the contribution barrier, that's a meaningful change.
For organizations, Codespaces offers a different value: developer onboarding time. The first day of a new engineer at a company typically involves hours configuring a local development environment — installing the right version of every tool, getting credentials configured, running setup scripts that half-work. A properly configured devcontainer reduces that to opening a browser. GitHub reports that organizations using Codespaces regularly see onboarding time cut from days to hours.
Beyond VS Code: The Open Specification
The Dev Container spec is no longer VS Code-exclusive. JetBrains IDEs (IntelliJ, WebStorm, PyCharm, GoLand) support devcontainer configurations natively. The devcontainer CLI allows building and running containers from the command line without any IDE. And because the spec is Docker-based, any CI system that can run Docker can use the same container for testing that developers use for development — eliminating the class of "passes locally, fails in CI" bugs that come from environment divergence.
Daytona, Coder, and several other companies have built managed remote development environment platforms on top of the Dev Container spec, targeting enterprises that want Codespaces-like functionality without GitHub dependency. The open standard means the tooling ecosystem isn't locked to any one vendor.
When DevContainers Are Worth the Overhead
DevContainers are not the right tool for every project. The overhead is real: container startup time (typically 5-30 seconds depending on image size and hardware), the cognitive layer of "am I inside the container right now," and the engineering time to write and maintain a good devcontainer.json. For a solo project on a stable, simple stack, a virtual environment and a README may be sufficient.
Where DevContainers clearly pay for themselves: projects with complex native dependencies (database drivers, image processing libraries, ML frameworks with CUDA requirements), teams with significant OS heterogeneity (Windows, macOS, Linux developers on the same project), projects with long onboarding paths, and any project where "it worked yesterday, I updated my Homebrew today" is a recurring conversation. The more complex and team-dependent the environment, the stronger the case.
The CI parity argument is separately compelling regardless of team size. Running tests in the same container you develop in eliminates one of the most frustrating debugging patterns in software: a test that passes locally due to an ambient dependency (a globally installed tool, a file in the home directory, a specific locale setting) and fails in CI because the CI environment is cleaner.
The Practical Starting Point
The easiest path to trying DevContainers is a project that already has a Dockerfile or uses Docker Compose. Add a .devcontainer/devcontainer.json that points at your existing Dockerfile, specify the extensions your team uses, and commit it. The VS Code Dev Containers extension (free, 30M+ downloads) handles the rest. Microsoft's devcontainer templates — available at containers.dev — provide starting points for most common stacks: Node.js, Python, Go, Rust, Java, .NET, Ruby, PHP, and more.
The "works on my machine" problem is not fully solved by DevContainers — runtime configuration, production database state, and network topology differences still exist. But for the layer of the problem that lives in toolchain versions and system dependencies, the specification has matured enough that "add a devcontainer" is now reasonable advice for most projects that aren't trivially simple.