Looking at the GitHub dependency graph or the .lockfile for most modern applications provides a view into the complex relationships of the open-source libraries, frameworks, or tools involved.
As a fully-remote software development team supporting dozens of production applications, LinkORB employs a thoughtful and proactive approach to dependency management. Doing so ensures a consistent and efficient development experience for team members as well as enabling rapid delivery for customers and end users.
LinkORB's approach begins with defining project versus environmental dependencies.
Project dependencies are required to run the application itself and found in all environments. Basic examples are servers (PHP, Node.js), REST API libraries, database connection helpers, or front-end libraries like Bootstrap. Project dependencies are defined in project declaration files like package.json or composer.json.
Environmental dependencies are non-production resources such as linters, testing frameworks, command line tools, and other development resources. At LinkORB, we define these dependencies outside of the project declaration file (package.json, composer.json).
The primary reason LinkORB separates dependencies is to remove environmental dependencies from the already-complicated project dependency chain.
Additionally, while some environmental dependencies are based on organizational standards and therefore required for use by all team members, other dependencies are simply recommended. In these cases, we want to provide team members the option to use their tooling of choice.
As a large number of LinkORB's applications are PHP-based, we've created the php-tools repository to provide a one-stop-shop for the most common environmental dependencies used for those projects.
When bundling of environment dependencies is not possible or desirable, we add them through global installers, GithHub actions, or scripts.
Whether doing local development or working in a Codespace, LinkORB wants team members working on code and not configuration. As such, we leverage Docker's multi-stage builds and devcontainers to initiate installation of both project and environmental dependencies.
Our end goal is that by executing
docker run all project and environmental dependencies are installed, the server is initiated, and any team member can immediately begin developing, testing, or writing documentation.