As I was reading an update on an issue in github an user suggested me to read the '12factor' principles. While I was reading it I started having some questions on some concepts written in the Dependency Management section.

The quote goes like this:

Twelve-factor apps also do not rely on the implicit existence of any system tools. Examples include shelling out to ImageMagick or curl. While these tools may exist on many or even most systems, there is no guarantee that they will exist on all systems where the app may run in the future, or whether the version found on a future system will be compatible with the app. If the app needs to shell out to a system tool, that tool should be vendored into the app.

Source: https://12factor.net/dependencies

While I do understand that you must handle dependencies in your own project and not assume that the system has already installed dependencies, I'm very curious about to which extent I should do it. As I understand you shouldn't rely on any kind of installed binary or resource when deploying your application but here is my question. What does 'any system tools' actually include?. For example, I use Java for developing. Do I have to include the mvn binary in my project? and the required Java version too? If I'm using Node I should include the npm binary? And for Python should I include pip and the required python version too? And what about the database, should it come bundled too?

I just would like to know the nature of the written manifest, because unfortunately it's very short on examples.

  • Things like the Python version are part of your dependencies, and not managing this dependency somehow can cause problems during deployment. In practice, containers (e.g. Docker) have proven really helpful to manage dependencies, without affecting whatever versions are installed on the host system.
    – amon
    Nov 26 '19 at 19:07

It's about Deployment

If your product needs any system dependencies that are not a core component of the operating system, then your product needs to include it as part of the installation package. That can be done in many ways, from setting up package dependencies to embedding the installer into your application's installer.

NOTE: if your product is a library or package for a larger system (i.e. it is a Maven or NPM dependency), then it needs to declare all dependencies so those also get pulled and your package just works.

It's not about compile/test

Any dependencies that are only needed to compile or test your application are not part of the deployment. They are part of your infrastructure.

NOTE: if your product is a library or package for a larger system (i.e. it is a Maven or NPM dependency), then you can declare these dependencies as scoped for build or test. That way they are only pulled when needed, and not included in the end user's final product.


This is a long winded way to say your install target should be a clean system. Pack what you need with you. Don't make users install what you need.

This is an old idea that works perfectly fine. Sharing dll's creates dll hell. Sharing packages creates package hell. Aim at a clean system and accept that it means your distribution will be a bit fatter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.