II. Dependencies

Explicitly declare and isolate dependencies

“A twelve-factor app never relies on implicit existence of system-wide packages.” – 12factor.net

When to use

Always.

Why it matters

  • Reproducibility: New developers can verify the code works just by installing dependencies.
  • Isolation: Prevents “works on my machine” issues where one machine has a different version of a library.

Signs of Violation

  • Relying on curl or imagemagick being installed on the OS without checking.
  • No package-lock.json or composer.lock.
  • “Global” npm installs.

Explanation

Problem

If your app assumes python is installed at /usr/bin/python, it will break when moved to a server where it’s at /usr/local/bin/python or is version 2.7 instead of 3.

Solution

Declare everything. Use package managers (npm, composer, pip). Use containerization (Docker) to bundle system tools.

Real world analogy

A recipe kit (HelloFresh). It doesn’t assume you have saffron in your cupboard. It sends you exactly the packet of saffron you need for the meal.

Pros and Cons

Pros Cons
  • setup consistency
  • Environment parity
  • Heavier build artifacts (vendoring deps)
  • Comparison

    • Global Packages: The enemy of this principle.

    Code example

    Typescript

    Bad (Violation)

    Good (Adherence)

    PHP

    Bad (Violation)

    Good (Adherence)