mojito is a small Rust implementation of an evolving subset of Mojo. It is not Mojo and does not pretend to the reach of Mojo's production compiler, but resembling that compiler's own shape is a goal it works toward: it is a compact implementation for studying, and step by step reproducing, the structure of a modern systems programming language compiler. Mojo was chosen as a target because it is a rich language, with value semantics, ownership/borrowing, ASAP destruction, generics, overloading, and compile-time execution — interesting features associated with C++, Rust, and Zig. Those semantics are enforced as explicit compiler analyses over a small MIR, with a register VM as the executable semantic oracle, and the goal is honest subset semantics: features are usually parsed before they are fully supported, and unsupported semantics fail cleanly instead of producing a wrong answer.
- Parse all of current Mojo and report syntax errors
- Approach semantic parity with a single-threaded, CPU-first subset of current Mojo. All mojito programs should be runnable by Mojo, though platform-specific Mojo programs stay outside the current target. The most primitive concurrency is expected eventually, and GPU is a stretch goal; parallelism, distributed execution, and Python interoperability are not intended
- Close the architectural distance to Mojo's own implementation, in stages
(
docs/architecture.md) - Keep the register VM as the executable semantic oracle while adding a stable textual MIR/VM assembly format and, later, native backends — Pliron and Cranelift first, with a possible C or C++ backend
The feature matrix is the authoritative record of what is
executable, checked-only, parse-only, or unsupported. The
project overview narrates the current status, the
deliberate gaps relative to Mojo, and the development direction. Mojito
currently tracks the pinned Mojo nightly recorded in
docs/mojo-nightly.md.
source
-> lex
-> parse
-> module link
-> comptime elaboration
-> check
-> HIR region tree
-> MIR
-> ownership / borrow / liveness analysis
-> drop elaboration
-> elaboration to concrete MIR (native::mono)
-> register VM / native backend
The Compiler driver owns this ordering for whole-program use; individual
stage APIs remain available for syntax tools and compiler development. See
the architecture guide for phase design and
the symbol map for code navigation.
cargo build
cargo test
cargo clippy --all-targetsIf your environment sets RUSTC_WRAPPER to a tool that cannot write its cache,
prefix commands with env RUSTC_WRAPPER=.
Run a compiler stage over a file, -, or standard input:
cargo run -- <command> [FILE]| Command | What it does |
|---|---|
lex |
print the token stream, one token per line |
parse |
print the parsed AST |
check |
parse and type-check |
own |
parse, type-check, and run ownership analysis |
run |
compile and execute on the register VM |
emit-mir |
compile and print canonical executable MIR |
exec |
execute a verified textual MIR artifact |
opt |
run named MIR passes (--pass NAME) over a textual artifact and print it |
For example:
echo 'def main(): print("Hello from mojito")' | cargo run -- run
cargo run -- run assets/ok/list_and_struct.mojo
cargo run -- emit-mir assets/ok/defines_main.mojo | cargo run -- exec -The supported Pliron backend lowers Mojito's verified MIR through Pliron's
LLVM dialect. It currently requires Linux and LLVM 23.1. The recommended way to
get a native executable is a single --emit exe call, which drives the pinned
LLVM optimization and linking tools and links the Mojito runtime behind the
scenes:
cargo build --release -p mojito-runtime
cargo run --release --features backend-pliron -- compile program.mojo \
--backend pliron --emit exe --native-opt release -o program
./program--print-toolchain reports the resolved opt and clang tools and the
runtime archive.
To inspect the intermediate LLVM IR instead, emit an .ll file:
cargo run --features backend-pliron -- compile program.mojo \
--backend pliron --emit ll -o program.llThe emitted IR includes the synthesized C main wrapper, so you can also run
the same LLVM 23.1 optimization and linking machinery by hand — the final link
must include Mojito's native runtime:
opt-23 -passes='default<O1>' program.ll -o program.bc
clang-23 --target=x86_64-unknown-linux-gnu --no-default-config \
program.bc target/release/libmojito_runtime.a \
-lm -Wl,--build-id=none -o program
./programUse the LLVM 23 executable names provided by your installation if they differ
from opt-23 and clang-23.
Use --emit bc or --emit obj when an intermediate LLVM bitcode or object
artifact is more useful. Pliron supports only the native subset recorded in the
feature matrix; unsupported programs fail with a diagnostic
instead of falling back to the VM. The native ABI and toolchain contract are
documented in the native ABI guide.
See usage for module-root options, how to write and run programs, the fixture workflow, differential conformance against Mojo, and the Rust library API.
docs/usage.md— building, CLI usage, writing programs, fixtures, conformance runs, and the library APIdocs/overview.md— status snapshot, gaps relative to Mojo, pipeline tour, and development directiondocs/features.md— authoritative feature support matrixdocs/architecture.md— pipeline invariants and phase designdocs/symbol-map.md— symbol-level ownership and navigation mapdocs/grammar.md— accepted surface syntaxdocs/vm-instruction-set.md— VM transition and instruction modeldocs/mir-text-format.md— textual MIR artifact formatdocs/roadmap.md— current direction and pending workdocs/non-goals.md— deliberate limits and deferred optionsassets/README.md— test fixture rulesCHANGELOG.md— user-visible history
Mojo Language ReferenceMojo ManualMojo By Example- an excellent quick tutorial