---
title: "Build from source"
description: "Build the runtime and CLI from the streamlib repository. Use it while the installers roll out, on a setup they don't cover, or to work on Tatolab itself."
type: "docs-page"
url: "https://tatolab.com/docs/install/from-source"
site: "Tatolab"
section: "Install"
---

# Build from source

> Build the runtime and CLI from the streamlib repository. Use it while the installers roll out, on a setup they don't cover, or to work on Tatolab itself.

The runtime and CLI are built from the [streamlib repository](https://github.com/tatolab/streamlib). A source build gives you the same `tatolabd` and `tatolab` the installers ship. The difference is that nothing starts the runtime for you: you run `tatolabd` in a terminal of its own.

## What you need

- **Rust**, installed with [rustup](https://rustup.rs).
- **uv**, which the build uses to run its pinned Python tools. See [Install uv](https://tatolab.com/docs/install/python#install-uv).
- **A native toolchain and a few libraries:**

  On Debian or Ubuntu:

  ```sh
  sudo apt install pkg-config protobuf-compiler libclang-dev libvulkan-dev glslc python3-dev cmake ninja-build
  ```

  On macOS, with the Xcode command line tools (`xcode-select --install`) and Homebrew:

  ```sh
  brew install shaderc cmake ninja
  ```

  `shaderc` provides `glslc`. You don't need a Vulkan SDK on macOS: the build puts a Vulkan loader and MoltenVK inside the runtime.

The platform requirements are the same as for the installers: Linux x86_64 with a Vulkan GPU driver, or an Apple silicon Mac with macOS 15 or later.

## Build

```sh
git clone https://github.com/tatolab/streamlib.git
cd streamlib
cargo xtask build-runtime --release
```

The first build takes a while. When it finishes, `target/tatolab-runtime/` is laid out like an installed copy:

```txt
target/tatolab-runtime/
├── bin/
│   ├── tatolabd        the runtime
│   └── tatolab         the CLI
└── lib/tatolab/lend/   the runtime's Python bindings, which each node's process loads from here
```

Keep `bin/` and `lib/` together: `tatolabd` finds `lib/` next to itself, and each node's process loads the runtime's bindings from there, never from your `.venv`. To move the build, copy the whole `tatolab-runtime` folder.

Put it on your `PATH`:

```sh
export PATH="$PWD/target/tatolab-runtime/bin:$PATH"
```

Add that line, with the full path, to `~/.bashrc` or `~/.zshrc` to keep it.

## Start the runtime

In a terminal of its own, run:

```sh
tatolabd
```

Leave it running. It's the runtime for the whole machine: every stream you run loads into it. It runs in the foreground until you press Ctrl-C.

In another terminal, check that it answers:

```sh
tatolab streams
```

```txt title="Output"
No streams in this runtime.
```

You're ready for the [quickstart](https://tatolab.com/docs/quickstart).

## Notes for macOS

- **Camera and microphone prompts name your terminal app**, not Tatolab, because the terminal started the runtime. Allow access for Terminal (or iTerm, or whichever you use) in **System Settings → Privacy & Security**.
- **`the machine runtime lock cannot be taken: /Library/Application Support/Tatolab … does not exist`.** The Tatolab app creates that folder on its first launch. Without the app, run the `sudo` commands the message prints, once.

## Updating

```sh
git pull
cargo xtask build-runtime --release
```

Then stop `tatolabd` with Ctrl-C and start it again. Streams you kept with `tatolab run -d` load again when it starts.

A debug build (without `--release`) builds faster and runs slower; it's useful when you're working on the runtime itself.
