Skip to content

Development

Most users should install a prebuilt binary; see Quick start. This page is for building from source and working on Betamax itself.

Betamax needs Rust and Cargo from rustup, and Zig 0.15.2. Betamax uses the safe libghostty-vt Rust wrapper; its libghostty-vt-sys dependency fetches a pinned Ghostty source commit and runs Zig to build the native VT library. Upstream Ghostty supports Zig 0.16, but the published Rust bindings still pin an older revision, so Betamax needs Zig 0.15.2 until a libghostty-rs release includes the update.

In a checkout, mise installs the pinned toolchain, and mise run ... commands use it. pnpm is only needed for the docs site. Other toolchain managers can work too, including Nix or a manually installed Zig 0.15.2 on PATH.

Terminal window
git clone https://github.com/joshka/betamax
cd betamax
mise install
mise run install-local

To install from crates.io without a checkout, put Zig 0.15.2 on PATH first:

Terminal window
mise install [email protected]
export PATH="$(mise where [email protected])/bin:$PATH"
zig version # should print 0.15.2
cargo install betamax --locked

If the build fails, see Build troubleshooting and, on macOS Tahoe, Building on macOS Tahoe.

The checked-in tapes under examples/ are smoke tests and documentation examples. The Examples page explains what each one demonstrates.

Terminal window
mise run render-examples

Renders land under examples/output and are copied to target/betamax-examples for inspection.

Run the same broad check as CI before opening a pull request:

Terminal window
pnpm install
mise run check
mise run docs-site-check

Useful Rust commands:

Terminal window
mise run fmt-check
mise run clippy
mise run test
mise run doc
mise run validate
mise run package

Docs site commands:

Terminal window
mise run docs-site-dev
mise run docs-site-check
mise run docs-site-build

CONTRIBUTING.md covers the project layout, checks, documentation style, and pull requests. Maintainer notes, including module design and release steps, are in the repository’s docs/ directory. Ask questions in Discussions.

An error such as Your Zig version v0.16.0 does not meet the required build version of v0.15.2 means Cargo found an incompatible compiler. mise install installs tools; mise run and mise exec select them for a command. Cargo’s --locked option pins Rust dependencies, not Zig.

In a checkout, use:

Terminal window
mise install
mise exec -- sh -c 'command -v zig; zig version'
mise run cargo-check
mise run install-local

The version check should print 0.15.2. For a custom command, use mise exec -- cargo run -- run examples/basic.tape instead of invoking Cargo outside mise. If a terminal or IDE still selects system Zig, check its inherited PATH and mise activation; opening a fresh shell can help isolate stale activation state.

For a crates.io source install without a checkout, see Build from source.

To build Betamax on macOS Tahoe, use the pinned Zig 0.15.2 with a compatible macOS SDK. If your default SDK comes from Xcode 26.4 or newer, select an older installed SDK using the local mise configuration below. This is a build-toolchain requirement; Betamax can run on Tahoe.

With an incompatible SDK, the build can fail with undefined symbols such as __availability_version_check, _abort, or _bzero while linking Zig’s build runner, before Ghostty or Betamax code compiles. The upstream Ghostty report tracks this SDK incompatibility. Keep Zig at 0.15.2 until the published Rust bindings support Zig 0.16.

Inspect the selected developer tools and available SDKs:

Terminal window
xcode-select -p
/usr/bin/xcrun --sdk macosx --show-sdk-path
ls /Library/Developer/CommandLineTools/SDKs

If you have a compatible SDK installed, copy the tracked mise.local.toml.example from the checkout root to mise.local.toml:

Terminal window
cp -i mise.local.toml.example mise.local.toml

If you already have local mise settings, merge the example’s entries into that file instead, preserving any existing _.path entries. mise.local.toml is ignored by version control; the example is tracked but is not loaded by mise. Use only one local filename (mise.local.toml or .mise.local.toml), since mise supports both.

Set the absolute path to a compatible SDK already installed on your machine. macOS SDK 15.2 has been verified with the pinned Ghostty build on Tahoe:

[env]
BETAMAX_MACOS_SDK = "/Library/Developer/CommandLineTools/SDKs/MacOSX15.2.sdk"
_.path = ["tools/macos-sdk"]

Verify the selected compiler and SDK, then build or install normally:

Terminal window
mise exec -- sh -c 'zig version; xcrun --sdk macosx --show-sdk-path'
mise run test
mise run install-local

The version should be 0.15.2, and the SDK path should match your local configuration. The tools/macos-sdk/xcrun wrapper overrides only the SDK lookup used by Zig and Ghostty, and forwards other commands to /usr/bin/xcrun. It leaves the machine-wide Xcode selection unchanged. SDKROOT alone does not override this lookup, and zig build --sysroot alone does not override Ghostty’s separate SDK discovery. No Zig wrapper or additional linker flags are needed.

If an IDE or agent still selects the wrong tools because it inherited stale mise activation, retry from a fresh shell, or clear that activation state for the command:

Terminal window
env -u __MISE_DIFF -u __MISE_SESSION -u __MISE_ORIG_PATH mise run test

To stop using the override, remove these entries from mise.local.toml. If you have no compatible SDK installed, use a compatible developer-tool installation or Betamax’s prebuilt binaries. DEVELOPER_DIR can select another installation for a command, but only helps if that installation’s default macOS SDK is compatible.

The docs site is published under Astro’s /betamax base path. Starlight-generated navigation, sidebar, and pagination links are already base-aware, but links authored directly in MDX are emitted as written.

Use normal relative Markdown links between docs pages. The site config canonicalizes the slashless base route, /betamax, to /betamax/ before users can follow those links. Without that redirect, links such as ./quick-start/ would resolve to /quick-start/ from /betamax instead of staying under /betamax/.

Releases are managed by release-plz and crates.io Trusted Publishing. The release workflow installs mise tools because package verification builds libghostty-vt-sys. Its published version still requires Zig 0.15.2, although upstream Ghostty supports Zig 0.16. Adoption awaits a libghostty-rs release containing the updated Ghostty source.