# Dependencies

### Dependencies

A Zig package may depend on another package.

Dependencies are declared in `build.zig.zon`. The build script then imports them by name.

A small `build.zig.zon` file looks like this:

```zig
.{
    .name = .demo,
    .version = "0.1.0",
    .dependencies = .{},
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
    },
}
```

The `.paths` field says which files belong to the package. Keep it narrow. Do not publish temporary files, build output, editor state, or local scripts by accident.

A dependency is added under `.dependencies`:

```zig
.{
    .name = .demo,
    .version = "0.1.0",
    .dependencies = .{
        .foo = .{
            .url = "https://example.com/foo-1.0.0.tar.gz",
            .hash = "...",
        },
    },
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
    },
}
```

The name `.foo` is the package name used by the build script.

Inside `build.zig`, fetch the dependency:

```zig
const foo_dep = b.dependency("foo", .{
    .target = target,
    .optimize = optimize,
});
```

Then get a module from it:

```zig
const foo_mod = foo_dep.module("foo");
```

Attach it to your executable or library:

```zig
exe.root_module.addImport("foo", foo_mod);
```

Now source code may import it:

```zig
const foo = @import("foo");
```

The import name is chosen by the build script. It does not have to match the package name, but it should unless there is a clear reason.

Dependencies are explicit at each layer.

`build.zig.zon` says where the package comes from.

`build.zig` says which dependency is used by which artifact.

The source file says which module it imports.

This avoids hidden global package state. A package does not become visible merely because it exists in a directory. The build graph must connect it.

A dependency can receive options from the parent build:

```zig
const foo_dep = b.dependency("foo", .{
    .target = target,
    .optimize = optimize,
});
```

This is the usual pattern. It builds the dependency for the same target and optimization mode as the main artifact.

A project may depend on a library but not expose it to all modules. For example:

```zig
tool.root_module.addImport("foo", foo_mod);
```

This gives `foo` only to `tool`. Other artifacts cannot import it unless they receive the same import.

That is useful. Keep dependencies local when possible.

A package may also expose several modules:

```zig
const parser = dep.module("parser");
const runtime = dep.module("runtime");
```

The names are defined by the dependency's build script.

Use the package manager for source dependencies. Use system libraries only when the project deliberately depends on the host system.

A system library is linked separately:

```zig
exe.linkSystemLibrary("sqlite3");
```

This means the build depends on a library installed on the target or host system. That is a different kind of dependency from a Zig package.

Package dependencies should be repeatable. The hash in `build.zig.zon` protects the fetched content. If the content changes, the hash no longer matches.

Do not remove the hash to make the build easier. The hash is part of the guarantee that a build uses the expected source.

A good dependency section is small and boring. Add a dependency when it saves real work or provides a stable interface. Avoid adding a package for code that would be simpler to write directly.

Exercise 15-25. Add one dependency to `build.zig.zon`.

Exercise 15-26. Import the dependency in `build.zig`.

Exercise 15-27. Attach the dependency module only to one executable.

Exercise 15-28. Explain the difference between a Zig package dependency and `linkSystemLibrary`.

