Development
Most users should install a prebuilt binary; see Quick start. This page is for building from source and working on Betamax itself.
Build from source
Section titled “Build from source”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.
git clone https://github.com/joshka/betamaxcd betamaxmise installmise run install-localTo install from crates.io without a checkout, put Zig 0.15.2 on PATH first:
zig version # should print 0.15.2cargo install betamax --lockedIf the build fails, see Build troubleshooting and, on macOS Tahoe, Building on macOS Tahoe.
Render the examples
Section titled “Render the examples”The checked-in tapes under examples/ are smoke tests and documentation examples. The
Examples page explains what each one demonstrates.
mise run render-examplesRenders land under examples/output and are copied to target/betamax-examples for inspection.
Checks
Section titled “Checks”Run the same broad check as CI before opening a pull request:
pnpm installmise run checkmise run docs-site-checkUseful Rust commands:
mise run fmt-checkmise run clippymise run testmise run docmise run validatemise run packageDocs site commands:
mise run docs-site-devmise run docs-site-checkmise run docs-site-buildContributing
Section titled “Contributing”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.
Build troubleshooting
Section titled “Build troubleshooting”Cargo finds Zig 0.16
Section titled “Cargo finds Zig 0.16”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:
mise installmise exec -- sh -c 'command -v zig; zig version'mise run cargo-checkmise run install-localThe 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.
Building on macOS Tahoe
Section titled “Building on macOS Tahoe”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:
xcode-select -p/usr/bin/xcrun --sdk macosx --show-sdk-pathls /Library/Developer/CommandLineTools/SDKsIf you have a compatible SDK installed, copy the tracked mise.local.toml.example from the
checkout root to mise.local.toml:
cp -i mise.local.toml.example mise.local.tomlIf 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:
mise exec -- sh -c 'zig version; xcrun --sdk macosx --show-sdk-path'mise run testmise run install-localThe 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:
env -u __MISE_DIFF -u __MISE_SESSION -u __MISE_ORIG_PATH mise run testTo 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.
Internal docs links
Section titled “Internal docs links”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.