npmrunseb
FR EN
← All writing

Dev Containers Only Made Sense the Day I Contributed to Open Source

I remember it fairly well. I had cloned the Bitwarden server repository intending to submit a small contribution. .NET server, a handful of microservices, MSSQL, a local mail server. The kind of setup that usually means a full day of configuration before writing a single useful line.

Except the repository had a .devcontainer.json file. I opened VS Code, clicked “Reopen in Container”. Less than an hour later, I had a working environment: the right SDKs installed, environment variables configured, extensions activated. I could focus on the actual reason I was there.

That’s when I understood what Dev Containers actually solve, and why I hadn’t seen their value until then.

In short: Dev Containers don’t shine on solo projects. Their value is asymmetric; it grows with the complexity of the project and the number of people who need to work on it. The best way to evaluate them: land on an unfamiliar codebase and measure how long it takes before you write your first useful line.

What a Dev Container actually does

A Dev Container is a development environment defined as code and shipped inside the repository. A .devcontainer/devcontainer.json file describes what that environment should contain: the runtime, CLI tools, VS Code extensions, environment variables, ports to expose.

VS Code reads that file and builds a local Docker container that acts as the development machine. The code stays on the host machine, but execution, linting, and debugging all happen inside the container.

The concept is formalized by the open devcontainers.io specification, maintained by Microsoft and the community. GitHub Codespaces uses the same format; a Codespace is really just a Dev Container hosted in the cloud.

{
  "name": "My project",
  "image": "mcr.microsoft.com/devcontainers/typescript-node:20",
  "features": {
    "ghcr.io/devcontainers/features/git:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
    }
  }
}

The concept solves the classic “works on my machine” problem. Except in this case, every machine shares the same environment definition, stored in the repository alongside the code itself.

On my personal projects, one more tool for not much gain

Before Bitwarden, I had tried Dev Containers. On two or three personal projects, I created the configuration file, followed the documentation, got a working result. And yet, a few weeks later, I would always drift back to my regular local environment.

Not because it didn’t work. Because the benefit wasn’t tangible in that context.

When you work alone on a project you initialized yourself, you are already the reference environment. The version of Node installed on your machine is the project’s version. Your editor extensions are exactly what’s needed. There’s no gap to close, no other developer to standardize the experience for.

The entry cost — configuring the file, waiting for the container build, debugging the first volume mounting issues — far outweighs the benefit on a side-project of a few hundred lines. It’s entirely rational not to use it in that context.

What I hadn’t anticipated: that reasoning completely falls apart the moment you change context.

What changes when you land on an unfamiliar codebase?

The environment is a solved precondition, not a problem to solve. That’s what changes when a repository ships a Dev Container. On Bitwarden: clone, reopen in container, wait for the build, start reading code. Nothing else.

Without a Dev Container, the same operation takes a minimum of one hour in the best case. Bitwarden’s contribution documentation is remarkably thorough: you still need to configure the MSSQL password, start the right containers in the right order, verify the Identity service responds on the correct port. Half a day if you hit a version conflict.

Contributing to a real-scale open source project is a particular experience: the codebase has a history, established conventions, precise dependency requirements. The core team develops with specific tool versions. The setup documentation is usually written with the best intentions, but it inevitably lags behind reality. A Dev Container is the only form of setup documentation that can’t lie.

According to the Coder and SlashData State of Development Environments 2025 (accessed 2026-05-16), only 7% of organisations can provision a development environment in under an hour; 21% spend more than two days on it. A Dev Container attacks that floor directly: the environment isn’t reinstalled, it’s rebuilt identically.

This connects directly to what I explored in my piece on IDE strategy in enterprise environments: on day one, a developer should be writing code, not spending hours figuring out why their terminal behaves differently from everyone else’s. Dev Containers are the natural extension of that principle, applied to the full codebase.

According to the Docker State of App Development 2025 report (accessed 2026-05-16), 71% of engineering leaders say onboarding a new developer takes at least two months. Dev Containers don’t eliminate that timeline; but they remove the most avoidable part of it: environment setup.

Why Dev Container value is asymmetric

A Dev Container’s value isn’t proportional to how well it’s configured. It’s proportional to the gap between the expected environment and the available environment for whoever is joining the project.

On a solo project where you’ve been the only developer from the start: gap is zero, value is near zero.

On a team project with different machines (macOS, Windows, Linux): significant gap, real value.

On an open source repository where anyone in the world might want to contribute, with any local configuration imaginable: maximum gap, structural value.

Projects like Supabase, NestJS, and Vite have adopted Dev Containers precisely for this reason: to reduce entry friction for external contributors. It’s not a comfort feature; it’s a lever for ecosystem health.

Container terminal — photo by Daniel Miksha / Unsplash Aerial view of a maritime container terminal

According to that same Docker State of App Development 2025 report (accessed 2026-05-16), 64% of developers used non-local environments as their primary setup in 2025, up from 36% the year before. Dev Containers are one of the most concrete expressions of this shift: the environment becomes something you describe, share, and rebuild, not something you configure once and hope never to touch again.

Should you add one to every project?

No. The honest answer is that it depends on context.

For a side-project you work on alone with no intention of sharing it: the cost-benefit ratio probably doesn’t justify the upfront investment. Your local environment is enough.

The calculus changes when any of the following applies.

Multiple developers on the same repository, even two. “Works on my machine” is a latent problem from the very first onboarding.

An open source project, even a modest one. Someone might want to contribute someday, and every hour removed from the setup process is one less obstacle between a good intention and a submitted PR.

Your future self in six months: this is the most overlooked scenario. Reopening a project after a long break and finding a ready environment is a form of documentation that doesn’t lie.

The warning signal: finding yourself writing a long, fragile “Installation” section in the README. That’s often a sign that a Dev Container would solve the problem structurally rather than just document it. The same instinct applies to your deployment stack: when your production setup fits in a reproducible VPS configuration, you’ve crossed the same kind of maturity threshold.

FAQ

Do Dev Containers work with editors other than VS Code?

Yes. The .devcontainer.json format is standardized by the open devcontainers.io specification. JetBrains added Dev Container support to IntelliJ and its other IDEs. GitHub Codespaces uses the same format for cloud environments. Adoption extends well beyond VS Code, even if it’s the editor that popularized the concept.

Does a Dev Container replace an existing Docker Compose setup?

Not necessarily; the two often coexist. Docker Compose manages the application’s services (database, cache, workers); the Dev Container defines the environment the developer works in. The devcontainer.json file can reference an existing docker-compose.yml to start associated services when the container opens.

Where do you start if you want to add a Dev Container to an existing project?

VS Code offers a “Dev Containers: Add Dev Container Configuration Files” command in the command palette, which generates a base configuration based on the detected language. The official templates library covers most common stacks: Node, Python, .NET, Go, Rust. It’s a solid starting point to refine from there.

Can Dev Containers work in CI/CD pipelines?

Yes. Because a Dev Container is just a Docker image with a configuration file, the same environment can be reused in GitHub Actions or any other CI runner that supports Docker. The benefit is consistency: your tests run in the exact same runtime as your development environment. The devcontainers CLI makes this straightforward for most pipelines.