A small Brainfuck toolchain written in Rust: a command-line interpreter, a compiler, a terminal REPL, and a browser playground built with WebAssembly.
Brainfuck was created by Urban Müller in 1993.
| Path | Purpose |
|---|---|
. / bf |
The bf command-line application |
crates/compiler |
Brainfuck → Rust source → native executable |
crates/interpreter |
Portable, resumable interpreter with no platform I/O dependencies |
crates/repl |
Interactive terminal REPL |
crates/web |
wasm-bindgen bindings used by the playground |
web |
TypeScript/Vite static playground, managed with pnpm |
The interpreter validates brackets before execution, uses 30,000 wrapping 8-bit cells, reads 0 at end of input, and supports instruction budgets so non-terminating programs can be paused safely.
The flake provides the CLI and one complete web output. Run these from the repository root:
nix developInside the development shell:
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cd web
pnpm install
pnpm dev # http://localhost:5173Outside the shell:
nix build .#bf # CLI; also the default package
nix build .#web # Wasm bindings + static site in ./result
nix run .#web # serve the built site on http://localhost:4173
nix flake check # packages, tests, Clippy, formatting
nix fmt # format Nix files with nixfmtnix flake check runs these checks: bf, web, rustfmt, clippy, tests, nixfmt, web-check, and smoke.
nix run .#web serves the bundled files with nixpkgs' static-server; it does not start a Vite dev server. To use another port:
PORT=8080 nix run .#webThe dev shell uses the stable Rust toolchain from rust-overlay with Clippy, rustfmt, and the wasm32-unknown-unknown target. It also provides Node.js 26, pnpm 12, wasm-pack, wasm-bindgen-cli, lld, nixfmt, and Biome.
Nix and untracked files: a flake only sees files tracked by Git. Run
git addfor new crates or web files beforenix build/nix flake check. While iterating on untracked files you can usenix build path:.#webinstead.
The flake uses the standard Nixpkgs pnpm path:
fetchPnpmDepsfetches exactlyweb/package.json,web/pnpm-lock.yaml, andweb/pnpm-workspace.yamlinto a fixed-output store.pnpmConfigHookinstalls those dependencies offline during the build.- Crane builds the Wasm bindings and the Vite bundle as one
webderivation. There is no separatewasmflake output. - Only a lockfile or manifest change requires updating the
pnpmDepshash inflake.nix.
Other reasonable workflows, depending on what you need:
| Workflow | Command | Trade-off |
|---|---|---|
| Hermetic Nix build | nix build .#web |
Reproducible, but needs a hash update when pnpm deps change |
| Fast UI iteration | nix develop, then pnpm dev |
No Nix rebuild; uses the normal pnpm store |
| CI / Cloudflare Pages | pnpm install --frozen-lockfile && pnpm wasm && pnpm build |
No Nix required; depends on the CI-provided Rust/Wasm toolchain |
| Plain static output | pnpm wasm && pnpm build |
Produces web/dist; serve it with any static file server |
The flake deliberately does not vendor node_modules, run an impure network install during a Nix build, or use buildNpmPackage (which expects an npm lockfile).
bf run hello.bf
bf build hello.bf
bf build hello.bf --save # Keep the generated Rust source
bf repl # Type exit to leave the REPLThe example in hello.bf prints Hello World!:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.Install the CLI with Nix or Cargo:
nix profile add github:4ster-light/bfcompiler
# or
cargo install --git https://github.com/4ster-light/bfcompiler.gitSee web/README.md for browser tests and Cloudflare Pages details. Pushes to main that touch the playground deploy to https://bfcompiler.pages.dev through .github/workflows/pages.yml.
nix develop -c cargo fmt --all --check
nix develop -c cargo clippy --workspace --all-targets -- -D warnings
nix develop -c cargo test --workspace
cd web
nix develop -c pnpm install --frozen-lockfile
nix develop -c pnpm test
nix develop -c pnpm wasm && pnpm buildFor a Nix-only verification, run nix flake check. Format the flake with nix fmt.
MIT