Lesson 1: What is Nix?

Understanding the core problem Nix solves

The Problem: The Reproducibility Crisis

You've probably experienced this:

Scenario: Your app works perfectly on your machine. You send it to a colleague, and they get different behavior. Or you come back to a project 6 months later and it doesn't build anymore. Or you have Python 3.9 installed, but the project needs 3.11.

Root cause: Your machine's state isn't documented. Dependencies are global and scattered. When you run pip install or npm install, you're modifying the global state of your machine in ways that are hard to reproduce elsewhere.

The Core Insight

Nix asks a radical question: What if all software dependencies and configurations were treated like code? Not just stored in version control, but genuinely reproducible, testable, and composable.

Nix's Promise: "Given the same inputs, Nix will always produce the exact same output, on any machine, at any time." This is achieved through a purely functional approach to package management.

Imperative vs. Declarative

The difference between traditional package managers and Nix is fundamental:

Imperative (apt, brew, npm)

You tell the system HOW to install things:

apt-get install nodejs npm install -g typescript python3 -m pip install pandas

Problems:
• Global state (what version exists depends on when you ran the command)
• Hard to replicate (colleague runs same commands, gets different versions)
• No easy rollback
• "Works on my machine" syndrome

Declarative (Nix)

You describe WHAT you want, Nix figures out HOW:

{ pkgs, ... }: { buildInputs = with pkgs; [ nodejs_20 typescript python311 ]; }

Benefits:
• Locked versions (exact versions in flake.lock)
• Reproducible everywhere
• Easy rollback (commit history)
• Same config = same setup

How Nix Achieves This

Three key ideas work together:

1. Pure Functions

Every package in Nix is defined as a pure function: same inputs → same output, no side effects. This is the foundation of reproducibility.

2. Content-Addressed Store

All packages are stored in /nix/store with names based on their content hash. If two builds produce the same result, they're deduplicated. If something changes, the hash changes.

3. Hermetic Builds

Builds are isolated—they can't accidentally depend on global system state. They only see explicitly declared inputs.

Why You Should Care

For the use case you mentioned (system configuration & reproducibility):

What You'll Learn in This Course

We're building toward reproducible, shareable development environments. Here's the arc:

Progression:
Nix fundamentals → Nix language basics → Creating a simple derivation → Writing a flake.nix → Sharing environments with others → Advanced patterns

Your First Experiment

Let's verify that Nix is installed on your system and get a feel for how it works.

Open your terminal and check Nix is installed:
nix --version

You should see something like nix (Nix) 2.18.1

Try a simple nix command to list packages:
nix search nixpkgs hello

This searches the nixpkgs repository for a package called "hello"

Run the hello package without installing it:
nix run nixpkgs#hello

This downloads and runs the "hello" package in an isolated environment. Notice: no global installation, no ~/.local/bin/ pollution.

✨ You just used Nix! You ran a package without installing it globally. It's isolated, reproducible, and ephemeral.

Reflection

Take a moment to think about these questions (no need to answer—just reflect):

Next Steps

Once you've completed the experiment above, you're ready for Lesson 2, where we'll write your first Nix expression and understand the language syntax.