# Project Structure

### Project Structure

So far, we have used single-file programs.

A single-file Zig program looks like this:

```text
hello.zig
```

You can run it with:

```bash
zig run hello.zig
```

This is good for learning small examples. But real programs usually need more structure. They may have source files, tests, dependencies, documentation, generated files, and build settings.

A Zig project gives those pieces a predictable place.

#### A Small Zig Project

A simple Zig project often looks like this:

```text
my_project/
  build.zig
  build.zig.zon
  src/
    main.zig
```

Each part has a job.

| File or folder | Purpose |
|---|---|
| `build.zig` | Build script for the project |
| `build.zig.zon` | Package metadata and dependencies |
| `src/` | Source code folder |
| `src/main.zig` | Main program file |

The exact layout can vary, but this is a common starting point.

#### The Project Folder

The outer folder is the project root:

```text
my_project/
```

This is the main directory for the program.

When you run project commands such as:

```bash
zig build
```

you usually run them from this folder.

The project root is important because Zig looks for `build.zig` there.

#### The Source Folder

The `src` folder contains your Zig source code:

```text
src/
  main.zig
```

The file `main.zig` is commonly the entry point for an executable program.

A simple `src/main.zig` may look like this:

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

pub fn main() void {
    std.debug.print("Hello from a Zig project!\n", .{});
}
```

This is similar to the earlier `hello.zig`, but now it lives inside a project.

#### The Build File

The file `build.zig` describes how to build the project.

For small single-file programs, we used:

```bash
zig build-exe hello.zig
```

For projects, we usually use:

```bash
zig build
```

The `zig build` command reads `build.zig`.

A simple build file tells Zig:

```text
Build an executable from src/main.zig.
```

You do not need to understand every line of `build.zig` yet. For now, understand its role: it is the project’s build recipe.

#### The Package File

The file:

```text
build.zig.zon
```

stores package metadata and dependency information.

ZON means Zig Object Notation. It is a data format used by Zig.

This file can describe things such as:

| Field | Meaning |
|---|---|
| Project name | The package name |
| Version | The package version |
| Dependencies | Other Zig packages used by the project |
| Paths | Files included in the package |

Beginners do not need to edit this file often at first, but it becomes important when using dependencies.

#### Creating a New Project

Zig can create a starter project for you.

Make a new folder:

```bash
mkdir my_project
cd my_project
```

Then run:

```bash
zig init
```

This creates a basic project structure.

You should see files similar to:

```text
build.zig
build.zig.zon
src/
```

Now run:

```bash
zig build
```

This builds the project.

Depending on the generated template, you may also be able to run:

```bash
zig build run
```

The exact generated files may change between Zig versions, but the core idea is the same: `zig init` creates a starting project.

#### Single File vs Project

Both styles are useful.

| Style | Example | Best for |
|---|---|---|
| Single file | `hello.zig` | Small experiments |
| Project | `build.zig` plus `src/` | Real programs |

When learning a new syntax feature, single files are faster.

When building an actual program, use a project.

A good rule:

```text
Use zig run for experiments.
Use zig build for projects.
```

#### Splitting Code into Multiple Files

As programs grow, one file becomes too large.

You can place helper code in another file.

Example project:

```text
my_project/
  build.zig
  src/
    main.zig
    math.zig
```

The file `src/math.zig` might contain:

```zig
pub fn add(a: i32, b: i32) i32 {
    return a + b;
}
```

Then `src/main.zig` can import it:

```zig
const std = @import("std");
const math = @import("math.zig");

pub fn main() void {
    const result = math.add(2, 3);
    std.debug.print("{}\n", .{result});
}
```

Output:

```text
5
```

The word `pub` in `math.zig` matters:

```zig
pub fn add(a: i32, b: i32) i32
```

It makes the function visible to other files.

Without `pub`, `main.zig` cannot call it.

#### Imports Are File-Based

This line:

```zig
const math = @import("math.zig");
```

imports another Zig file.

The imported file becomes a namespace. That means you access its public declarations through its name:

```zig
math.add(2, 3)
```

This keeps code organized.

You can think of `math.zig` as a small module.

#### Keeping Files Small

A beginner mistake is to put everything in `main.zig`.

That works for tiny programs, but it becomes difficult to read.

A better habit is to separate code by responsibility.

For example:

```text
src/
  main.zig
  config.zig
  parser.zig
  server.zig
  database.zig
```

Each file should have a clear purpose.

| File | Purpose |
|---|---|
| `main.zig` | Program entry point |
| `config.zig` | Configuration loading |
| `parser.zig` | Parsing input |
| `server.zig` | Network server logic |
| `database.zig` | Database access |

The goal is not to create many files for no reason. The goal is to keep related code together.

#### Where Tests Go

Zig tests can live in the same file as the code they test.

Example:

```zig
pub fn add(a: i32, b: i32) i32 {
    return a + b;
}

test "add two numbers" {
    try @import("std").testing.expect(add(2, 3) == 5);
}
```

This is common in Zig.

You can also create separate test files for larger projects, but colocated tests are simple and useful.

A test near the function it checks is easy to find and easy to update.

#### Build Output

When you run:

```bash
zig build
```

Zig creates build output directories.

You may see folders such as:

```text
zig-out/
.zig-cache/
```

Their roles are different.

| Folder | Purpose |
|---|---|
| `zig-out/` | Final build outputs |
| `.zig-cache/` | Cached intermediate build data |

Usually, you do not edit these folders by hand.

Your source code lives in `src/`.

Your build outputs are generated by Zig.

#### What to Commit to Git

If you use Git, commit your source and build files:

```text
build.zig
build.zig.zon
src/
```

Usually, do not commit generated build output:

```text
zig-out/
.zig-cache/
```

A simple `.gitignore` may include:

```gitignore
zig-out/
.zig-cache/
```

This keeps the repository clean.

#### A Practical Starting Layout

For most beginner projects, this layout is enough:

```text
my_project/
  build.zig
  build.zig.zon
  src/
    main.zig
```

When the program grows, add more files:

```text
my_project/
  build.zig
  build.zig.zon
  src/
    main.zig
    cli.zig
    config.zig
    app.zig
```

Avoid designing a huge folder structure before the program needs it.

Start simple, then split code when it becomes hard to read.

#### What You Should Remember

A Zig project usually has a project root, a `build.zig` file, a `build.zig.zon` file, and a `src/` folder.

Use single files for experiments.

Use a project structure for real programs.

The most important project command is:

```bash
zig build
```

The most important source file at the beginning is:

```text
src/main.zig
```

As your program grows, split code into small files with clear responsibilities.

