DEV Community

Sem Gebresilassie
Sem Gebresilassie

Posted on • Edited on

The Twelve‑Factor App: Codebase + Dependencies (practical intro)

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 ci in CI).

Read the rest (highly recommended)

The original Twelve‑Factor guide is short and extremely readable:


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:

https://akukulu.com

Top comments (0)