This guide covers installing OtterLang on various platforms. The easiest way is using Nix, but manual installation is also supported.
First, clone the OtterLang repository:
git clone https://github.com/jonathanmagambo/otterlang.git
cd otterlangNow you're ready to build OtterLang. Choose one of the installation methods below.
If you plan to use Nix (recommended), you'll need to install it first. Nix is a package manager that provides a reproducible development environment.
The easiest way to install Nix is using the official installer:
# Run the Nix installer
sh <(curl -L https://nixos.org/nix/install) --daemonAfter installation, restart your terminal or run:
. ~/.nix-profile/etc/profile.d/nix.shOn Windows, you can use Nix through WSL2 (Windows Subsystem for Linux) or use NixOS in a virtual machine. Alternatively, you can follow the manual installation instructions below.
For more detailed installation instructions, visit the official Nix installation guide.
After installing Nix, verify it's working:
nix --versionYou should see the Nix version number. If you encounter any issues, refer to the Nix troubleshooting guide.
Nix provides a reproducible development environment with all dependencies:
# Enter the development environment
nix develop
# Build the compiler (nightly toolchain is set as default in Nix)
cargo build --releaseThe Nix flake automatically provides:
- Rust nightly toolchain
- LLVM 18 with WebAssembly support
- All required system dependencies
This is the recommended approach for development and ensures consistent builds across different systems.
If you prefer not to use Nix, you can install dependencies manually.
- Rust nightly: Required for FFI features
- LLVM 18: For code generation and WebAssembly support
# Clone the repository (if you haven't already)
git clone https://github.com/jonathanmagambo/otterlang.git
cd otterlang
# Install LLVM 18
brew install llvm@18
# Set environment variables
export LLVM_SYS_181_PREFIX=$(brew --prefix llvm@18)
export LLVM_SYS_180_PREFIX=$LLVM_SYS_181_PREFIX
export PATH="$LLVM_SYS_181_PREFIX/bin:$PATH"
# Install Rust nightly
rustup toolchain install nightly
# Build OtterLang
cargo +nightly build --release# Clone the repository (if you haven't already)
git clone https://github.com/jonathanmagambo/otterlang.git
cd otterlang
# Install LLVM 18
sudo apt-get update
sudo apt-get install -y llvm-18 llvm-18-dev clang-18
# Set environment variables
export LLVM_SYS_181_PREFIX=/usr/lib/llvm-18
export LLVM_SYS_180_PREFIX=$LLVM_SYS_181_PREFIX
# Install Rust nightly
rustup toolchain install nightly
# Build OtterLang
cargo +nightly build --release# Clone the repository (if you haven't already)
git clone https://github.com/jonathanmagambo/otterlang.git
cd otterlang
# Install LLVM 18
sudo dnf -y install llvm18 llvm18-devel clang18
# Set environment variables
export LLVM_SYS_181_PREFIX=/usr/lib64/llvm18
export LLVM_SYS_180_PREFIX=$LLVM_SYS_181_PREFIX
# Install Rust nightly
rustup toolchain install nightly
# Build OtterLang
cargo +nightly build --releaseThe included Powershell script setup.ps1 prepares your environment to build Otter. Namely it does the following:
- Inits the Visual Studio dev shell, which includes needed environment variables.
- Downloads LLVM 18.
- Installs the Ninja build tool required by vcpkg.
- Downloads libxml2.
- Sets up PATH and other environment variables so the compiler knows where to find llvm, libxml2, and ninja.
LLVM, ninja, and libxml2 are installed in the contrib folder, which is created by this script. Keep in mind that this script needs to be run in any new powershell instance before building, as it's changes are not permanent.
# Clone the repository (if you haven't already)
git clone https://github.com/jonathanmagambo/otterlang.git
cd otterlang
# Install Rust nightly
rustup toolchain install nightly
# Run setup script
./setup.ps1
# Build OtterLang
cargo +nightly build --releaseOnce the build completes successfully, the otter binary will be available at target/release/otter.
# Run a program directly
./target/release/otter run examples/basic/hello.ot
# Or using cargo
cargo +nightly run --release --bin otter -- run examples/basic/hello.ot# Build a standalone executable
./target/release/otter build examples/basic/hello.ot -o helloOtterLang can compile programs to WebAssembly (WASM) for running in web browsers or other WASM runtimes.
Basic WebAssembly (no WASI):
otter build program.ot --target wasm32-unknown-unknown -o program.wasmWebAssembly with WASI support:
otter build program.ot --target wasm32-wasi -o program.wasmTarget Differences:
-
wasm32-wasi- WebAssembly System Interface- Best for: Server-side WASM, command-line tools, WASI-compatible runtimes
- Full WASI support: Direct access to stdio, filesystem, networking, and other system APIs
- Runtime compatibility: Works in any WASI-compatible runtime (wasmtime, WasmEdge, etc.)
-
wasm32-unknown-unknown- Bare WebAssembly- Best for: Web browsers, embedded systems, custom host environments
- Minimal imports: Only requires a few host functions for I/O
- Smaller binaries: No WASI runtime overhead
- Browser compatible: Can run directly in web browsers with appropriate host
Requirements:
- LLVM 18 with WebAssembly target support
clangandwasm-ldin your PATH (included with LLVM installations)
Limitations:
- Garbage Collection: WASM modules use OtterLang's built-in GC, which may have different performance characteristics than native execution
- FFI: Foreign function interface is limited in WASM environments
- File I/O: Direct filesystem access requires WASI or host-provided APIs
- Concurrency: Task spawning works but may have limitations in constrained environments
- Many stdlib modules (
io,net,task) are unavailable in WASM targets
Examples:
# Build examples for WebAssembly
otter build examples/basic/hello.ot --target wasm32-unknown-unknown -o hello.wasm
otter build examples/basic/fibonacci.ot --target wasm32-wasi -o fibonacci.wasm
# Run with wasmtime (WASI)
wasmtime fibonacci.wasm# Run the test suite
cargo +nightly test --release
# Run specific tests
cargo +nightly test --release test_nameNix builds with libffi errors: If you get "libffi.so.8" errors when running outside Nix, use the Nix environment:
nix develop
./target/release/otter run program.otWindows path issues: Ensure you're using the Visual Studio Developer Command Prompt with proper MSVC environment variables.
OtterLang provides a comprehensive CLI tool for running, building, and managing OtterLang programs.
otter [COMMAND] [OPTIONS] [FILE]Run an OtterLang program directly.
otter run program.ot [options]Options:
--debug- Enable debug mode with additional logging--quiet- Suppress non-error output--lib-path <PATH>- Add directory to library search path
Examples:
otter run hello.ot
otter run --debug myprogram.otCompile an OtterLang program to a native executable or WebAssembly.
otter build program.ot [options]Options:
-o, --output <FILE>- Output file path--target <TARGET>- Compilation target (native,wasm32-unknown-unknown,wasm32-wasi)--release- Enable release optimizations
Examples:
otter build hello.ot
otter build program.ot -o myapp
otter build app.ot --target wasm32-unknown-unknown -o app.wasmFormat OtterLang source code according to standard style guidelines.
otter fmt [files...] [options]Options:
--check- Check if files are formatted correctly (don't modify)
Examples:
otter fmt source.ot
otter fmt --check *.otExecute unit tests and integration tests.
otter test [options] [pattern]Profile program execution for performance analysis.
otter profile <SUBCOMMAND> program.ot [options]Subcommands: memory, cpu, alloc
Start the OtterLang Language Server Protocol (LSP) server for editor integration.
otter lsp [options]Create a new OtterLang project with standard directory structure.
otter new <NAME> [options]Check program for type errors without running it.
otter check program.ot [options]These options can be used with any command:
-h, --help- Show help information-V, --version- Show version information--verbose- Enable verbose output--quiet- Suppress informational output
All commands that execute Otter code accept GC tuning flags:
--gc-strategy <strategy>– choose betweenrc,mark-sweep,generational, ornone.--gc-threshold <fraction>– override the heap usage threshold (0.0–1.0) that triggers a collection.--gc-interval-ms <ms>– force a periodic GC cycle; set to0to disable interval-based cycles.--gc-disabled-max-bytes <bytes>– cap allocations allowed while GC is disabled.
Passing these flags is equivalent to setting the matching OTTER_GC_* environment variables for the spawned program. See docs/GC_GUIDE.md for a deeper discussion of collectors, root registration, and arenas.
OTTER_LOG- Set logging levelOTTER_FFI_CACHE- FFI bridge cache directoryOTTER_LIB_PATH- Additional library search pathsOTTER_GC_STRATEGY- Same as--gc-strategyOTTER_GC_THRESHOLD- Same as--gc-thresholdOTTER_GC_INTERVAL- Same as--gc-interval-msOTTER_GC_DISABLED_MAX_BYTES- Same as--gc-disabled-max-bytes
LLVM not found:
Verify that LLVM_SYS_181_PREFIX points to the correct LLVM installation directory and that LLVM binaries are in your PATH.