1. Introduction and Goals
denver (Development Environment Starter) starts a complete development environment from one file.
One command — denver run <env> — turns a denver.yml into a working shell:
Python venv, native toolchain, Zephyr workspace, container. Whatever the file
declares, in the order it declares it. Same on a laptop and on CI.
1.1 Requirements overview
The problem:
Every project writes its own entry script (
devshell.sh,run.sh, a Makefile).Each new project copies the last one and re-adapts a few hundred lines of bash.
Setup logic and environment description are mixed. Nothing is reusable.
The only way to see what an environment does is to read the script.
denver splits that in two:
denver.ymlsays what an env is: which stages, which files, which versions. No logic.Providers know how:
uv,conan,zephyr,docker,download,git,nix,custom. Generic — every project detail comes from config.
Functional requirements:
# |
Requirement |
|---|---|
R1 |
Start a complete environment with one command; hand it to a shell or to a given command. |
R2 |
Run the same stack in a container or directly on the host ( |
R3 |
Share config between envs by inheritance (whole file, or one section) instead of copy-paste. |
R4 |
Show what an env would do before it does it ( |
R5 |
Re-run cheaply — unchanged input, no expensive work. |
R6 |
Add a new kind of step without changing the orchestrator, and add a project’s own provider without forking denver. |
1.2 Quality goals
Ranked by how much each one actually drove decisions (chapter 9 has the decisions).
# |
Goal |
Why |
|---|---|---|
1 |
Transparency |
No hidden defaults, no guessed paths. |
2 |
Reproducibility |
Same config plus same inputs, same environment — laptop, CI, container, later. |
3 |
Speed on re-runs |
First run may be slow. Second must not be. Stages fingerprint their inputs and skip themselves; |
4 |
Extensibility |
New provider = one file + one registry entry. From outside the repo: one file in an |
5 |
Testability |
A provider reaches the world through two |
6 |
Least duplication in config |
Shared setup written once, inherited or stacked. A derived env states only the difference. |
7 |
No Docker lock-in |
Every env must run directly on the host. The container is a wrapper stage, not a precondition. |
1.3 Stakeholders
Role |
Concern |
|---|---|
Environment user |
Runs |
Environment author |
Writes the |
CI |
Runs denver non-interactively. Needs deterministic behavior and no prompt — denver refuses to guess a command when none is given and the terminal is not interactive. |
denver maintainer |
Adds providers, keeps the gates green (coverage, complexity, lint, types). Wants chapters 5 and 8 to stay small enough to hold in one head. |