Grasm v1.0.0 Get started
v1.0.0 Now available — read the status

Code that can’t overstep.

Grasm is a systems language where a dependency cannot reach further than its manifest allows. Overstep, and it is a compile error.

mathlib/grasm.toml
[package] name = "mathlib" version = "1.0.1" capabilities = []
read_file("/etc/passwd") performs [io], permits [] build failed
511programs, every engine identical
85.7 KBhello-world, statically linked
660libraries, all written in Grasm
113gates, judged by exit code alone
Interactive

Sneak one past the compiler.

A trusted math library ships a patch release. Add the line that reads a file, loosen the manifest, and watch four toolchains react.

mathlib
grasm.toml
[package]
name = "mathlib"
version = "1.0.1"
capabilities = []
src/lib.gr
fn add(a: i64, b: i64) -> i64 {
    a + b
}

grasm build · and the same patch elsewhere

app — grasm build

Open the full playground →

The same attack, four toolchains

A trusted pure library’s 1.0.1 starts reading /etc/passwd. scripts/security_bench.sh runs it against four toolchains on every green build. Three of them ship it.

GrasmCOMPILE ERRORinferred effects (io) exceed the declared ceiling ([])
Rustbuilds cleanstd::fs is ambient; no capability is recorded
Gobuilds cleanos.ReadFile is importable by any package
Pythoncompiles cleanopen() needs no import and no declaration

This is the reason the language exists. xz-utils, event-stream, SolarWinds: the attack is always the same shape, and the answer everywhere else is a runtime sandbox or a human reading the diff. Here it is a type error.

Three ideas. One language.

They were built to compose. Each one closes a hole the other two leave open.

An effect reaching the ceiling a package declared, and stopping there

Capabilities

A package states the effects it may perform. Exceed it, and the build fails in every consumer. Not in review. Not at run time.

Three tiers of ownership, stacked

Ownership in tiers

Values by default. A region when a scope owns its allocations. A generational reference when a graph needs one. No lifetime annotations, anywhere.

Four engines converging on one answer

Four engines, one answer

Interpreter, bundle, ahead-of-time native, and wasm. Instant feedback while you build, a binary when you ship, the same program in a browser.

Checked on every green build

Four engines.
One answer.

Develop against the interpreter, ship a native binary, run the same program in a browser. The interpreter is normative; the other three have to match it byte for byte.

One programhello.gr
fn main() {
    print("hello from grasm")
}
+ 511 more in the corpus, every run
Interpretergrasm run hello.gr normative
Bundlegrasm build hello.gr one file
Nativegrasm build --native 85.7 KB
Wasm--target wasm32 no OS
One answer
$ stdout ×4hello from grasm
0mismatches, across every
engine and both architectures
difftestcrosstestwasmtest
511programs, interpreter and native and bundle identical
511of them again, cross-compiled to x86_64
415identical in the browser engine
44whole applications, agreeing on every engine

Effects live in the type.

You never write the row. The compiler infers it from the body and checks it against what you declared. Touch the network, and the function stops compiling — along with every caller that was not given the same permission.

! MathError A failure the caller must handle.
/ {io} A permission the caller must have.
effects.gr
fn safe_div(a: i64, b: i64) -> i64 ! MathError { if b == 0 { fail(DivByZero) } a / b } fn load(path: str) -> str ! IoError / {io} { try read_file(path) }

Honest numbers.

11 measurable goals, 13 rows once 2 of them split in half. 9 are met, 2 are over by 4% and 2%, and 2 cannot be read at all without users. The scorecard puts every qualification beside its number rather than underneath it.

85.7 KBhello-world, static, down from 351.1 KB
1,000,000tasks in 22 s, natively
0.965×of Rust, geomean — not ahead of it
535klines a second, front end

Start building.

Install, first program, first package. Ten minutes.

Terminal
$ cargo build --release --workspace $ ./target/release/grasm run examples/hello.gr hello from grasm