If you build software that runs as a service (SaaS, APIs, web apps), the Twelve‑Factor App is still one of the clearest checklists for keeping things deployable and maintainable.
In my experience, two factors quietly cause a big share of real-world pain:
- environments that drift (“staging is not prod”)
- setups that aren’t repeatable (“it works on my machine”)
This post is a short, practical intro to two factors that prevent those problems:
- Codebase — one repo, many deploys
- Dependencies — declare everything explicitly
If you want the full set of factors, the official guide is here (worth reading end-to-end):
https://12factor.net/
1) Codebase — one repo, many deploys
In plain language: your app should have a single source of truth in version control (one codebase), and that same codebase should be deployed to multiple environments.
What this looks like in practice
- One repository deployed to dev, staging, and production through the same pipeline.
- You promote the same code forward (instead of rebuilding a different app per environment).
Common failure modes I see
- A production hotfix is made directly in prod and never merged back.
- “Staging” is pointed at a different repo/branch for convenience and silently diverges.
- Teams copy/paste a shared “utils” folder into multiple repos and call it “shared code”.
The fix
- Treat envs as deploys of the same codebase.
- If multiple repos truly need shared functionality, extract a versioned dependency (package/library) instead of duplicating code.
2) Dependencies — declare everything explicitly
In plain language: the app should not rely on tools/libraries “just being installed” on a server or a developer’s laptop.
What this looks like in practice
- Dependencies are declared in a manifest (
package.json,requirements.txt,Gemfile, etc.). - CI uses a deterministic install (
npm ci, locked versions, reproducible builds). - A new developer can clone the repo and get running without guessing what to install globally.
Common failure modes I see
- Local uses one Node version; CI uses another; production uses a third.
- No lockfile / loose ranges — builds change over time without code changes.
- Global installs hide missing dependencies until deployment day.
The fix
- Pin versions where it matters, commit the lockfile, and make CI match local setup.
- Prefer repeatable install commands (e.g.
npm ciin CI).
Read the rest (highly recommended)
The original Twelve‑Factor guide is short and extremely readable:
- Codebase: https://12factor.net/codebase
- Dependencies: https://12factor.net/dependencies
- Full list: https://12factor.net/
If you want help applying this to a real codebase
If you’re building a React/TypeScript product (or inheriting a messy one) and want to tighten up your deployment + maintainability fundamentals in a focused sprint, you can find me here:
Top comments (0)