# Examples

### Examples

Examples are small programs kept inside the project.

They show how the code is meant to be used. They also check that public APIs still compile.

A common layout is:

```text
project/
├── build.zig
├── src/
│   └── root.zig
└── examples/
    ├── hello.zig
    └── copy.zig
```

An example is an ordinary Zig program:

```zig
const std = @import("std");
const mylib = @import("mylib");

pub fn main() !void {
    std.debug.print("{s}\n", .{mylib.message()});
}
```

The build file creates an executable for it:

```zig
const example = b.addExecutable(.{
    .name = "hello-example",
    .root_module = b.createModule(.{
        .root_source_file = b.path("examples/hello.zig"),
        .target = target,
        .optimize = optimize,
    }),
});
```

If the example imports the project library, attach the module:

```zig
const lib_mod = b.createModule(.{
    .root_source_file = b.path("src/root.zig"),
    .target = target,
    .optimize = optimize,
});

example.root_module.addImport("mylib", lib_mod);
```

Now `examples/hello.zig` can use:

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

Add a named step:

```zig
const examples_step = b.step("examples", "Build examples");
examples_step.dependOn(&example.step);
```

Run it:

```sh
zig build examples
```

For several examples, use a helper function or a loop:

```zig
const example_names = [_][]const u8{
    "hello",
    "copy",
};

const examples_step = b.step("examples", "Build examples");

for (example_names) |name| {
    const path = b.fmt("examples/{s}.zig", .{name});

    const exe = b.addExecutable(.{
        .name = b.fmt("{s}-example", .{name}),
        .root_module = b.createModule(.{
            .root_source_file = b.path(path),
            .target = target,
            .optimize = optimize,
        }),
    });

    exe.root_module.addImport("mylib", lib_mod);
    examples_step.dependOn(&exe.step);
}
```

Examples should stay short. Each one should show one use case.

Good examples have names like:

```text
hello
copy-file
parse-json
serve-http
```

Bad examples have names like:

```text
test1
demo2
misc
stuff
```

An example can also have a run step:

```zig
const run_example = b.addRunArtifact(example);

const run_example_step = b.step("run-example", "Run hello example");
run_example_step.dependOn(&run_example.step);
```

Then:

```sh
zig build run-example
```

builds and runs it.

For many examples, it is usually enough to build them. Running them may require files, ports, network access, or command-line arguments. Keep automatic example steps deterministic.

Examples are not a substitute for tests. Tests check exact behavior. Examples show intended use.

A good project usually has both.

Exercise 15-21. Create an `examples/hello.zig` file.

Exercise 15-22. Add an `examples` build step.

Exercise 15-23. Make the example import a module from `src/root.zig`.

Exercise 15-24. Add a second example and build both with one command.

