# Your first project

> Create a Brine project with brine new, then run, check, test and format it, with the files it creates and the output of each command.

Source: https://docs.brinelang.org/getting-started/first-project/

`brine new` creates a project with a program, a test, and an `AGENTS.md` for coding agents. From then on the loop is: edit, `brine check`, `brine run`, `brine test`. This page walks through each command with the output it prints. You need Brine [installed](/getting-started/installation/) first.

## Create and run a project

[Section titled “Create and run a project”](#create-and-run-a-project)

1. Create the project:

   ```sh
   brine new hello
   ```

2. Go into it and run it:

   ```sh
   cd hello
   brine run
   ```

   ```text
        Built hello v0.1.0 [dev] in 2.04s
      Running target/dev/hello.exe
   Hello, brine!
   [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
   ```

   The first build also compiles Brine’s runtime, so it takes a couple of seconds. Later builds reuse it. (On Linux and macOS the binary is `target/dev/hello`, with no `.exe`.)

3. Run it again without changing anything:

   ```sh
   brine run
   ```

   ```text
        Fresh hello v0.1.0 [dev] in 0.02s
      Running target/dev/hello.exe
   Hello, brine!
   [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
   ```

   `Fresh` means nothing changed, so Brine ran the binary it already had.

The `Built`, `Fresh` and `Running` status lines go to stderr; your program’s output goes to stdout. Add `-q` to hide the status lines.

## What’s in a project

[Section titled “What’s in a project”](#whats-in-a-project)

```text
hello/
├── .gitignore
├── AGENTS.md
├── README.md
├── brine.toml
└── src/
    └── main.br
```

`brine new` also runs `git init` in the folder, unless it’s already inside a git repository. To turn an existing folder into a project, run `brine init` in it; it creates the same files and skips any that already exist.

### brine.toml

[Section titled “brine.toml”](#brinetoml)

brine.toml

```toml
[package]
name = "hello"
version = "0.1.0"
```

The file marks the project root. brine commands look for it in the current folder and its parents, so you can run them from anywhere inside the project. The program starts at `src/main.br`. See [Projects](/tooling/projects/) for the other settings, such as `[check] typed = true`.

### src/main.br

[Section titled “src/main.br”](#srcmainbr)

src/main.br

```brine
# Welcome to brine! Run this program with `brine run`.


fn greet(name: str) -> str:
    return f"Hello, {name}!"


fn main():
    print(greet("brine"))


    # parallel by default: this runs across all your cores
    let squares = par [i * i for i in 0..10]
    print(squares)


test "greeting":
    assert greet("you") == "Hello, you!"
```

`fn main()` is where the program starts. `par [...]` builds the list of squares on every core. The `test` block at the end is a test, which `brine run` ignores and `brine test` runs.

### AGENTS.md

[Section titled “AGENTS.md”](#agentsmd)

Instructions for coding agents working in the project: the commands to run and the rules that most often trip up someone who knows Python. Many coding agents read `AGENTS.md` on their own when they start work in a folder. See [AGENTS.md and common mistakes](/agents/agents-md/) for its full text and an explanation of each rule.

### .gitignore and README.md

[Section titled “.gitignore and README.md”](#gitignore-and-readmemd)

`.gitignore` holds one line, `/target`: builds and the build cache go in `target/` (`target/dev/`, `target/release/`, `target/cache/`). `README.md` is a short stub for you to fill in.

## Check, run, test, format

[Section titled “Check, run, test, format”](#check-run-test-format)

| Command       | What it does                                                              |
| ------------- | ------------------------------------------------------------------------- |
| `brine check` | type-check and prove, without building; the fastest feedback              |
| `brine run`   | build `src/main.br` and run it                                            |
| `brine test`  | build and run every `test "...":` block, in parallel                      |
| `brine fmt`   | rewrite every source file in the standard format                          |
| `brine build` | build a binary into `target/dev/` (or `target/release/` with `--release`) |

### brine check

[Section titled “brine check”](#brine-check)

```sh
brine check
```

```text
   Checked hello in 0.00s — 0 runtime checks proven unnecessary, 1 remain (see --report)
```

`check` parses, type-checks, and runs the prover. It doesn’t build anything, so it’s the command to run after every edit. The second half of the line counts the safety checks (array bounds, overflow, division by zero) that the prover removed and those that stay in the program as runtime checks. `--report` lists the ones that remain:

```sh
brine check --report
```

```text
src/main.br:10:24: overflow check `i * i`
   Checked hello in 0.00s — 0 runtime checks proven unnecessary, 1 remain
```

The prover handles linear arithmetic, so it can’t show that `i * i` stays in range; the program checks it at runtime instead. A remaining check is not an error. See [Runtime checks](/proofs/runtime-checks/).

### brine test

[Section titled “brine test”](#brine-test)

```sh
brine test
```

```text
     Built tests [dev] in 0.10s
test greeting ... ok


test result: ok. 1 passed; 0 failed; finished in 0.02s
```

Each test runs in its own process. `brine test shout` runs only the tests whose names contain `shout`. See [Testing](/language/testing/).

### brine fmt

[Section titled “brine fmt”](#brine-fmt)

```sh
brine fmt
```

```text
1 file checked, 0 reformatted
```

There’s one standard format (4-space indentation, spaces around operators), so code always looks the same. `brine fmt --check` changes nothing and exits with status 1 if a file needs formatting, for CI. See [Formatting](/tooling/formatting/).

## The edit-run loop

[Section titled “The edit-run loop”](#the-edit-run-loop)

Here is one round of changes: add a function and a test, make a mistake, and fix it.

1. Add a `shout` function and a test for it to `src/main.br`. Write it carelessly, and pass it a number by mistake:

   src/main.br

   ```brine
   # Welcome to brine! Run this program with `brine run`.


   fn greet(name: str) -> str:
       return f"Hello, {name}!"


   fn shout(name:str)->str:
     return greet(name).upper()


   fn main():
       print(greet("brine"))
       print(shout(42))


       # parallel by default: this runs across all your cores
       let squares = par [i * i for i in 0..10]
       print(squares)


   test "greeting":
       assert greet("you") == "Hello, you!"


   test "shouting":
       assert shout("you") == "HELLO, YOU"
   ```

2. Check it:

   ```sh
   brine check
   ```

   ```text
   error[E0301]: mismatched types
     --> src/main.br:11:17
      |
   11 |     print(shout(42))
      |                 ^^ expected `str`, found `int`
      |
      = help: convert with `str(...)` or use an f-string like f"{x}"
      = run `brine explain E0301` for more about this error
   error: could not compile due to 1 error
   ```

   Every error has a code, the exact place, and a hint. `brine explain E0301` explains the code at length. Change the call to `shout("brine")`.

3. Format the file:

   ```sh
   brine fmt
   ```

   ```text
    Formatted src/main.br
   1 file checked, 1 reformatted
   ```

   `fn shout(name:str)->str:` is now `fn shout(name: str) -> str:`, and its body is indented by 4 spaces.

4. Run the tests:

   ```sh
   brine test
   ```

   ```text
        Built tests [dev] in 0.09s
   test greeting ... ok
   test shouting ... FAILED


   ---- shouting ----


   panic: assertion failed: shout("you") == "HELLO, YOU"
     --> src/main.br:21:5


   test result: FAILED. 1 passed; 1 failed; finished in 0.03s
   ```

   The expected string is missing its `!`. Fix the test to compare with `"HELLO, YOU!"` and run `brine test` again:

   ```text
        Built tests [dev] in 0.09s
   test greeting ... ok
   test shouting ... ok


   test result: ok. 2 passed; 0 failed; finished in 0.02s
   ```

5. Run the program:

   ```sh
   brine run
   ```

   ```text
        Built hello v0.1.0 [dev] in 0.09s
      Running target/dev/hello.exe
   Hello, brine!
   HELLO, BRINE!
   [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
   ```

## Single files and release builds

[Section titled “Single files and release builds”](#single-files-and-release-builds)

You don’t need a project to try something. Every command also takes a file:

```sh
brine run scratch.br
brine check scratch.br
brine test scratch.br
brine run scratch.br -- first second    # arguments after `--` go to the program
```

`brine run --release` and `brine build --release` optimize through the C compiler. They take longer to build and run faster:

```sh
brine build --release
```

```text
     Built hello v0.1.0 [release] in 2.59s
    Output target/release/hello.exe
```

## Next

[Section titled “Next”](#next)

* [A tour of Brine](/getting-started/tour/): the rest of the language in one page.
* [Coming from Python](/getting-started/from-python/): what’s the same and what isn’t.
* [The brine command](/tooling/cli/): every command and flag.
