Git Course 0%

Dependencies, build, runtime

Beginner Core Git Git CLI ≈ 9 min

What you will learn

  • What a dependency is and why projects have hundreds of them
  • What a package manager, a manifest and a lock file do
  • What "build", "artifact" and "runtime" mean

After this lesson you can

  • I can read a requirements or package file and say what it is for
  • I understand why installed packages and build output are not committed

Why this matters

When a developer says "you need to install the dependencies first" or "the build is broken", they are describing the machinery between source code and a running program. You do not have to operate that machinery, but you will see its traces in every repository: manifests, lock files, generated folders, pipeline logs. Knowing what they are keeps them out of your commits and out of your way.

Dependencies: code you did not write

No program is written from scratch. Reading a CSV file, drawing a chart, talking to a database: someone already wrote that, published it as a library, and your project depends on it.

Libraries are distributed as packages through a package manager for each language: pip for Python, npm for JavaScript, Maven or Gradle for Java, NuGet for C#. The project lists what it needs in a manifest file:

requirements.txt (Python)
requests>=2.31
pandas>=2.2
package.json (JavaScript, excerpt)
{
  "name": "trailguide-web",
  "dependencies": {
    "express": "^4.19.0",
    "markdown-it": "^14.0.0"
  }
}

The package manager reads the manifest, downloads the packages into a folder inside the project (node_modules/, .venv/) and writes a lock file with the exact versions it chose, so that the next person gets the same ones.

The playground has zero dependencies beyond Python itself, which is why there is no requirements.txt and no install step. That is unusual and deliberate: nothing to install, nothing to break.

Build: turning source into something that runs

Some source code runs as is (Python, shell scripts). Most of the rest goes through a build: a sequence of steps that compiles, bundles, minifies or packages the source into the files that actually run or get shipped.

Build output goes into folders like build/, dist/, target/, out/. It can always be regenerated from the source, so it is listed in .gitignore and never committed. If you see it in git status, do not add it.

Runtime: what runs the program

The runtime is the software that executes a program: the Python interpreter, the Java Virtual Machine, Node.js, a browser. Runtimes have versions, and code written for one version may fail on another. This is the root of the classic sentence "it works on my machine": the developer has Python 3.12, you have 3.9, and a feature is missing.

Projects therefore pin their runtime somewhere: a line such as image: python:3.12 in .gitlab-ci.yml, a .python-version or .nvmrc file, or a note in the README. When something fails for you but not for others, compare versions first.

Scripts: the buttons developers press

Most projects define short named commands for the routine: npm run test, make build, python -m unittest. They are listed in the manifest ("scripts" in package.json), in a Makefile, or in the README. When a developer says "just run the tests", they mean one of these. The pipeline runs exactly the same commands (Section 14).

How this connects to Git

  • Manifest and lock files are committed: they are the recipe for reproducing the environment.
  • Installed packages and build output are not: .gitignore hides them (lesson 4.3).
  • A commit that changes a manifest usually changes the lock file too; reviewers expect both.
  • "The build is red" means a pipeline job failed after a push; lesson 14.3 shows how to read it.

Common mistakes

  • Committing node_modules/ or .venv/. Hundreds of megabytes, thousands of files, and the repository becomes painful for everyone. Check .gitignore before git add ..
  • Editing the lock file to make a warning go away. It is generated; run the package manager instead, or ask.
  • Reporting a bug without the runtime version. "It crashes" is not actionable; "it crashes on Python 3.9, works on 3.12" is. python3 --version, node --version and java -version print it.
  • Expecting the build output in the repository. Look for the pipeline's artifacts or a release page instead (Section 14).

Try it yourself

Goal: find the runtime version the playground pins, and compare it with yours.

  1. Open .gitlab-ci.yml in the playground and find the line starting with image: under the tests job.
  2. In a terminal, run python3 --version.
  3. Open .gitignore and find the lines that hide installed packages and generated files.

Expected result: the pipeline uses python:3.12; your local version is 3.10 or newer; .gitignore lists __pycache__/, *.pyc and .venv/.

Show solution

The pipeline runs the tests inside a container with Python 3.12, so the tests are always executed with the same runtime, whatever is installed on each person's machine. Your local version may differ; for this project anything from 3.10 works. __pycache__/ and *.pyc are files Python generates when it runs; .venv/ is where installed packages would go.

Check yourself

1. git status shows package-lock.json as modified after you ran npm install. What should you do?
2. What is an artifact?
3. "It works on my machine" is most often caused by…

Key terms

.gitignore Repository (repo)