Ruff is a small programming language and runtime implemented in Rust. It is built for local scripting, automation, runtime experiments, and benchmarking work where a compact language with a Rust-hosted standard library is useful.
The project is currently at 0.10.0 in Cargo.toml, with active 0.11.0 work focused on async static-site-generation benchmark throughput and VM scheduler reliability. Ruff is usable from source today, but the language and runtime APIs are still evolving. Treat the repository tests, examples, and native-function dispatch tests as the source of truth for current behavior.
- Ruff builds from source with Cargo. Prebuilt binary/package-manager installation is not the current path.
ruff runuses the bytecode VM by default.ruff run --interpreterruns the tree-walking interpreter fallback.- The runtime includes a broad native standard library for strings, collections, files, data formats, HTTP, databases, crypto, process/system helpers, concurrency, and network primitives.
- Optional type annotations are parsed. In the CLI, type-checking warnings are emitted on the interpreter path; VM execution does not currently enforce a static type gate before running.
- Some advanced language surfaces are experimental or have runtime-mode gaps. See Known Boundaries.
Ruff currently installs by building this repository.
git clone https://github.com/rufflang/ruff.git
cd ruff
cargo build --release
./target/release/ruff --versionFor development, use the debug build through Cargo:
cargo run -- --help
cargo run -- run examples/hello.ruffTo install the local checkout into Cargo's binary directory:
cargo install --path .
ruff --versionSee INSTALLATION.md for platform notes and troubleshooting.
Create hello.ruff:
func total(values) {
let sum := 0
for value in values {
sum := sum + value
}
return sum
}
let scores := [8, 13, 21]
let report := {"name": "build", "total": total(scores)}
if report["total"] > 40 {
print("ok: " + report["name"] + " = " + to_string(report["total"]))
} else {
print("too low")
}
Run it:
ruff run hello.ruffExpected output:
ok: build = 42
The current CLI exposes these subcommands:
| Command | Purpose |
|---|---|
ruff run <file> |
Run a .ruff script with the default VM. |
ruff run --interpreter <file> |
Run a .ruff script with the tree-walking interpreter. |
ruff repl |
Start the interactive REPL. |
ruff test |
Run .ruff files under tests/; --update regenerates expected-output snapshots. |
ruff test-run <file> |
Run tests declared with Ruff's test "name" { ... } syntax. |
ruff bench [path] |
Run benchmark scripts. |
ruff bench-cross |
Compare Ruff parallel_map against a Python ProcessPoolExecutor benchmark. |
ruff bench-ssg |
Run the async SSG benchmark, with optional Python comparison and measurement controls. |
ruff profile <file> |
Profile a Ruff script for CPU, memory, and JIT stats. |
Useful environment variables:
| Variable | Effect |
|---|---|
DISABLE_JIT=1 |
Disables JIT support in the VM path. |
DEBUG_AST=1 |
Prints the parsed AST before VM execution. |
RUFF_SCHEDULER_TIMEOUT_MS=<ms> |
Overrides the VM cooperative scheduler completion timeout. The default is 120000. |
Ruff source files use the .ruff extension. The implemented syntax includes:
- Numeric, string, boolean,
null, array, and dictionary values. let,mut, andconstbindings with:=assignment syntax.- Optional annotations on variables and functions, such as
let x: int := 42andfunc add(a: int, b: int) -> int. - Functions declared with
func, including anonymous function expressions andasync func. if/else,while,loop,for ... in,break, andcontinue.- Arrays and dictionaries with indexing and standard library helpers.
- String interpolation with
${...}inside double-quoted strings. ResultandOptionvalues throughOk(...),Err(...),Some(...), andNone.match/casestatements, including cases that bindOk(value),Err(error), andSome(value)in interpreter mode.try/exceptblocks andthrow(...)for runtime error flow.awaitexpressions and promise-returning async/native operations.spawn { ... }syntax and native concurrency helpers.structdeclarations, field access, and struct instance literals.test,test_setup,test_teardown, andtest_groupdeclarations for the test runner.#,//,/* ... */, and///comments.
A small async example:
async func fetch_label(id) {
return "item-" + to_string(id)
}
let first := fetch_label(1)
let second := fetch_label(2)
print(await first)
print(await second)
Native functions are registered in src/interpreter/mod.rs and dispatched through src/interpreter/native_functions/. The current categories include:
- I/O and debugging:
print,input,debug, assertions. - Math:
abs,sqrt,pow,floor,ceil,round,min,max, trigonometry,PI,E. - Strings and regex: length, case conversion, trimming, splitting/joining, padding, slug/case helpers, regex match/find/replace/split.
- Collections: array helpers, higher-order functions, dictionaries, sets, queues, stacks, ranges.
- Type conversion and introspection:
parse_int,parse_float,to_string,to_bool,type,is_*helpers,bytes. - Filesystem and binary I/O: text files, binary files, metadata, random access reads/writes, copy/truncate helpers, path helpers, OS helpers.
- Data formats: JSON, TOML, YAML, CSV, and Base64.
- System utilities: environment variables, CLI args, time/date helpers, sleep, process execution, process spawning, command piping.
- HTTP and auth: HTTP client calls, streaming/binary HTTP helpers, response helpers, JWT helpers, OAuth2 helpers, parallel HTTP.
- Database helpers: SQLite, Postgres, MySQL-oriented connection/query APIs, pools, transactions, last-insert-id helpers.
- Async and concurrency: sleep/timeout promises, async file/HTTP operations, task handles,
Promise.allaliases,parallel_map, shared state, channels, task-pool sizing. - Media/archive/crypto/network: image loading, zip/unzip, SHA/MD5, bcrypt, AES, RSA, TCP, and UDP helpers.
The standard library is broad, but not all functions have polished reference documentation yet. When adding user-facing docs for a specific API, verify the handler contract in src/interpreter/native_functions/ and the corresponding regression tests.
Ruff has two testing layers.
Run the Rust test suite:
cargo testRun repository .ruff snapshots:
cargo run -- test
cargo run -- test --updateRun Ruff tests declared in a specific file:
cargo run -- test-run tests/testing_framework.ruffExample Ruff test file:
test "array length" {
let values := [1, 2, 3]
assert_equal(len(values), 3)
}
test "string predicate" {
assert_true(starts_with("ruff", "ru"))
}
Ruff includes benchmark tooling because performance work is a first-class part of the project, especially for the VM, async scheduler, and native SSG benchmark path.
cargo run -- bench examples/benchmarks
cargo run -- bench-cross
cargo run -- bench-ssg --runs 5 --warmup-runs 1
cargo run -- bench-ssg --compare-python --profile-async
cargo run -- profile examples/benchmark.ruffbench-ssg supports repeated runs, warmups, percentile reporting, measurement-quality warnings, optional Python comparison, optional stage profiling, and a throughput gate via --throughput-gate-ms.
These are intentional caveats for production readers rather than fine print:
- Ruff is source-built today. Do not assume official release binaries or package-manager taps are available.
- VM execution is the default, but the tree-walking interpreter still matters for some language surfaces and diagnostics.
- Static typing is optional and not a VM-enforced compile-time contract in the current CLI path.
import/exportsyntax and a module loader exist, butsrc/module.rscurrently resolves/parses modules without executing them and collecting exports. Treat the module system as incomplete.- Struct fields and instance literals exist. Struct method behavior is still a moving target across runtime paths, so avoid documenting it as a stable production feature without a fresh test.
- Spread literals and destructuring syntax exist, but behavior is uneven across runtime modes. Verify them against the exact execution path before documenting them as stable.
spawn { ... }is parsed and executed as fire-and-forget work; do not rely on spawned output or shared state without using the explicit concurrency/native async APIs.Result/Optionvalues are implemented, but richer pattern-binding behavior should be verified against the runtime mode you intend to use.- Benchmark numbers are environment-sensitive. Prefer
bench-ssg --runs <N> --warmup-runs <N>and read the measurement warnings before drawing conclusions.
- INSTALLATION.md: build and installation notes.
- CHANGELOG.md: release and unreleased changes.
- ROADMAP.md: planned work.
- CONTRIBUTING.md: contribution workflow.
- docs/CONCURRENCY.md: async/concurrency model notes.
- docs/PERFORMANCE.md: benchmark and profiling notes.
- docs/VM_INSTRUCTIONS.md: bytecode VM instruction reference.
- docs/EXTENDING.md: adding native functionality.
Some older docs may lag the current VM-default execution path. Prefer the code and tests when behavior differs.
Ruff is licensed under the MIT License. See LICENSE.