Two speeds

Developing and shipping are different jobs. Fennec gives each its own path: development builds optimize for your time, and release builds optimize for runtime.

While you work

The goal for development builds is that a change runs in moments.

When you ship

Release builds take as long as they need to produce the fastest code.

Values without references

Fennec code never handles references, but the compiler uses them behind the scenes wherever it’s safe:

You write What the compiler does
describe(player) Passes a hidden read-only reference; no copy
apply_damage(mut player, 10) Passes a hidden exclusive reference
b = a, and a isn’t used again Moves it, for free
b = a, and both are used Shares the memory until one of them changes, then copies once
Small values like Vec3 Copies them in registers, for free

The cost of sharing is a reference count on large data, mostly optimized away, and a copy the first time shared data changes. That copy isn’t written in the code, so three things keep it in check: the compiler warns when a change inside a loop might copy, noalloc code rejects it outright, and the profiler reports hidden copies by name.

Libraries can’t change silently

Return types and errors are inferred, so a library could change what a function returns or how it fails without any visible edit to its signature. When a package is published, Fennec compares the inferred signatures of everything it exports, including the errors each function can fail with, against the previous version, and flags every change.

The engines

Engine Starts running Runtime speed Used for
Interpreter Instantly Several times slower than native First run of changed code, compile-time evaluation, tests
Fast compiler Quickly, per function Close to native Hot code in development builds
Optimizing compiler Slowly Full speed Release builds

Why builds stay fast

Fast builds come from design decisions, not just a fast compiler.

The performance target

Release builds should land within a few percent of hand-tuned native code. That’s a promise we intend to check, not just make:

What costs nothing

These features exist only at compile time and have no runtime cost: mut, type inference, ?, ?. and else, optional types, error handling, enums and match, interfaces and generics, generators, tuples, with, capabilities, and noalloc.