Public release v1.10.0 · Spec v0.2.0-draft · Star on GitHub
Crisp

Crisp v1.10.0 · public release

High-performance prototypes. Implicit types. Native code.

Explicit on demand, implicit by default. Write compact .crp quickly; crisp emits ordinary Rust so the binary is native.

  • Implicit typing — plus inferred ownership and errors — so you can code directly
  • High-performance output: native binaries via rustc (the soundness boundary)
  • 37% more compact than the Rust it emits (GPT-4 tokens) — less context for LLM agents
  • reveal shows the types and borrows you left unwritten

Install now → Start the tutorial →

cargo install crisp-lang --locked
crisp run .
Hello worldexamples/hello
shape Named = {
    name: str
}

type Guest = {
    name: str = "world"
}

id(x: T) = x

greet(who: Named) = "hello {who.name}"

pub main() = {
    world := Guest {}
    print(id(greet(world)))
}
Output "hello world"

Why Crisp?

High-performance prototyping: skip type and borrow ceremony while you iterate, then keep a native rustc binary. Annotate when APIs need precision. Emit stays auditable Rust.

Implicit typing

Types, borrows, lifetimes, and error sets are inferred globally when the source stays silent. You write the algorithm; the compiler fills the signatures. Annotations become hard constraints when you add them.

Native performance

Crisp is a front end that produces Rust. There is no VM or GC in the run path. Memory safety and data races remain rustc’s job — not a parallel soundness story.

Reveal what was inferred

reveal reconstructs signatures, ownership modes, lifetime overlays, and the error slice a function can produce — so fast writing stays inspectable.

Fewer tokens for agents

Same programs, 37% fewer GPT-4 tokens than the Rust crisp emits (v1.10.0 examples/, cl100k_base). LLM agents read and generate less, so they iterate quicker. Typical crate as written: 28% fewer (median). Details: llms.txt.

Use Crisp for

High-performance prototypes in popular Rust domains — CLI tools, services, pipelines — with implicit types and native emit.

Browse use cases → Learning paths →

Language features

Compact snippets from the repo examples — more in the tutorial.

Enums + matchexamples/enums
type Color =
    | Red
    | Green
    | Custom(int, int, int)

describe(color) = match color {
    Color.Red -> "red"
    Color.Custom(r, g, b) -> "rgb({r},{g},{b})"
    _ -> "other"
}
Inherent methodsexamples/vec2_methods
type Vec2 = {
    x: float
    y: float
}

impl Vec2 = {
    pub new(x: float, y: float) = Vec2 {
        x: x
        y: y
    }
    pub magnitude(self) =
        (self.x ** 2.0 + self.y ** 2.0) ** 0.5
}

pub main() = {
    v := Vec2.new(3.0, 4.0)
    log("mag={v.magnitude()}")
}
Traitsexamples/show_trait
trait Show = { show(self) -> str }

type Point = {
    x: int
    y: int
}

impl Show for Point = {
    show(self) = "({self.x},{self.y})"
}

label(x: T) = x.show()

pub main() = {
    p := Point { x: 3, y: 4 }
    log("p={p.show()} l={label(p)}")
}
Shapesexamples/shapes
shape HasPosition = {
    x: float
    y: float
}

distance(a: HasPosition, b: HasPosition) -> float = {
    dx := a.x - b.x
    dy := a.y - b.y
    dx * dx + dy * dy
}
Genericsexamples/generics_implicit
type Pair = { left: A, right: B }
id(x: T) = x
first(p: Pair<A, B>) = p.left

shape HasPosition = { x: T, y: T }
distance(a: HasPosition<T>, b: HasPosition<T>) = {
    dx := a.x - b.x
    dy := a.y - b.y
    dx * dx + dy * dy
}
Rust crate importexamples/rust_import
-- crisp.toml: serde_json = { version = "1", rust = true }
use serde_json { from_str, to_string }

pub main() = {
    v := from_str("[1, true, \"crisp\"]")
    print(to_string(v))
}
Fallible + catchexamples/fallible
parse_port(s) ! = {
    if s == "" then throw "empty"
    -- …
}

pub main() = {
    p := parse_port("8080") catch { e => 0 }
    log("port={p}")
}
Loopsexamples/loops
sum_to(n) = {
    total mut:= 0
    i mut:= 0
    while i < n {
        i = i + 1
        total = total + i
    }
    total
}

countdown_stop(start, stop) = {
    n mut:= start
    loop {
        if n == stop then break n
        if n <= 0 then break 0
        n = n - 1
    }
}
Asyncexamples/async_hello
pub main() = async {
    sleep_ms(1)
    print("async-ok")
}

Full tutorial → Language summary →

Pipeline

Source → CIR → Rust → native. The emitted crate is an ordinary Cargo project under target/rust/.

.crp → resolve → typeck → ownership → CIR → Rust → rustc → native

Install and run hello →