run-rs 0.6.4

Run a subset of Rust as an interpreted script
run-rs-0.6.4 is not a library.

RustScript

Crates.io CI Marketplace Licence

Linux macOS Windows

Write your helper scripts in Rust and run them like shell scripts, no compile step. RustScript interprets a practical subset of the language, so a script starts instantly. rust check validates the same file with the real rustc.

docs/interpreter.md explains how it works inside.

Install

cargo install run-rs

This installs a binary named rust.

First script

#!/usr/bin/env rust

use std::fs;

fn main() -> anyhow::Result<()> {
    let text = fs::read_to_string("notes.txt")?;
    println!("{} lines", text.lines().count());
    Ok(())
}

Make it executable and run it:

chmod +x notes.rs
./notes.rs

Usage

rust FILE.rs         interpret the script
rust -e 'CODE'       run a snippet, arguments after CODE go to it
rust check FILE.rs   validate without running
rust build FILE.rs   compile, cache, and run a native binary
rust supported       list every bridged method per receiver
rust clean           clear cached checks and builds
rust update [VER]    install a release, the newest one by default
rust --version       show version and build information

Arguments after the file go to the script.

A script run directly cannot use rust build, so the word cmp as the first argument does the same thing. ./tool.rs cmp one two compiles the script and runs the binary with one two. Because of this a script must not treat its own first argument as cmp, that word is reserved.

What works

Functions, closures, structs, enums, patterns, loops, iterators, Vec, strings, maps, sets, Option, Result, ?, formatting, modules, local path crates, and async with #[tokio::main], spawned tasks, timers, and HTTP. Traits with default methods, user Display, Debug, Drop, operator, and Iterator impls, associated consts, u128 and i128, mem::swap and its siblings, and real sharing through Rc, Arc, RefCell, Cell, and Mutex. Values copy on write, so clones and Copy assignments mutate independently, exactly like compiled Rust.

The standard library bridge covers files, paths, stdin and stdout, processes, TCP sockets, environment, time, and collections. Bridged crates include anyhow, serde, serde_json, reqwest, regex, tokio, chrono, rand, and more. Windows builds also bridge winreg, windows-service, and wmi.

The full generated list of bridged methods is in docs/supported.md. Every feature has a working example under crates/examples/examples.

Limitations

  • Crates without a bridge stop with an unsupported crate error.
  • std::thread is not supported, use tokio tasks.
  • static mut is rejected. Plain statics behave like constants.
  • Lifetimes are accepted but mean nothing at runtime. Generic bounds dispatch by the value's runtime type.
  • Glob imports from script modules are not supported.
  • HashMap iterates in insertion order. Real Rust's order is arbitrary and unpromised, so a correct script cannot observe the difference, but an interpreted run is deterministic where a compiled one is not.

Modules and local crates

mod name;, nested modules, and crate::, self::, super:: imports work as in normal Rust. A script inside a Cargo project can use local library crates declared as path dependencies in the nearest Cargo.toml. See docs/multifile.md for layout rules and a complete example.

Caching

Checks, compiled binaries, and shared Cargo dependencies live under ~/.cache/rustscript. Entries are keyed by source hash and interpreter version, unused ones are swept after 30 days. rust clean removes everything at once.

GitHub Actions

The repository is also a GitHub Action:

- uses: VladasZ/rustscript@v0.2
  with:
    script: tools/release.rs
    args: --dry-run

It downloads a checksum verified prebuilt binary, so setup takes seconds instead of compiling the crate. Linux, macOS, and Windows on x86_64 and arm64. See docs/github-actions.md.

Benchmarks

RustScript is compared with native Rust, Node, and Python on equivalent programs. See the benchmark guide for methodology and results, and the profiling guide for finding interpreter hot spots. The roadmap tracks the wall-clock goal, beat both interpreted rivals on every case, startup included.

Licence

Dual licensed under either MIT or Apache-2.0, at your option.