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
curlorimagemagickbeing installed on the OS without checking. - No
package-lock.jsonorcomposer.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 |
|---|---|
Comparison
- Global Packages: The enemy of this principle.
Code example
Typescript
Bad (Violation)
Good (Adherence)
PHP
Bad (Violation)
Good (Adherence)