Loup — Language of Unusual Portability — is
one strongly-typed language for scripting, automation, code generation,
and embedded templating — that runs as a fast local script today and compiles to a
native binary, a browser-safe Wasm module, or a bare-metal image tomorrow. Same
source. Delivery is a build decision, not a language decision.
Most teams keep two languages: a scripting language for the glue,
and a systems language for anything that has to be fast, small, or shipped. Loup
collapses that split. A script you wrote this morning to shuffle files is the same
source that compiles to an optimized native binary this afternoon — no rewrite, no
second toolchain, no second set of idioms for your team to learn.
Script mode
loup run script.loup — JIT-compiled at load,
statement by statement. Execution starts immediately; there is no build step,
and every statement is individually addressable by a debugger.
Compiled mode
loup build — ahead-of-time compilation to an
optimized native binary, a sandboxed Wasm module, or a freestanding image
with no runtime beneath it.
No fork in the road
Features depend on where code is deployed, not on how it was
compiled. Script-mode source that avoids build-time-only features compiles
ahead-of-time without a single edit.
Six execution modes, one source
A mode declaration at the top of a file statically determines
which capabilities, standard-library modules, and language features are in scope. The
compiler, linter, completion menus, and error messages all treat it as authoritative
— a browser-targeted file cannot reach for a process-spawning API even when the
underlying runtime would permit it.
web.scripted
JIT compilation inside the browser sandbox.
web.compiled
Ahead-of-time Wasm for the browser.
host.scripted
JIT compilation in an OS process — the default for
loup run.
host.dual
One source, deliverable as either a script or a native
binary.
host.native
Native binaries via the LLVM and Cranelift backends, on
x86_64 and aarch64.
freestanding
Bare metal — no operating system and no runtime beneath the
compiled image.
Import transparency
A module's mode does not leak through its public
interface. Script-mode code may import a natively-compiled module without knowing
which pipeline produced it; the runtime bridges the boundary. Libraries ship as
source and run on machines that never installed the native compiler.
What makes Loup different
Five design decisions that a team feels on the first day, not
in year three. Memory safety gets a section of its own below.
Capability-gated runtime
Filesystem, network, and process access route through the
runtime root object and pass a permission check on every call,
against a permission set declared in the package manifest or passed at the
command line. Where code compiles to Wasm — script mode and both browser
modes — native FFI is a compile error, so that check is the only
route to the host: a dependency five levels down your import graph cannot
open a socket you did not grant. Native builds link C directly, so there the
permission set is an enforced contract between cooperating code rather than
a sandbox.
Debuggability as a language feature
The JIT pipeline keeps full source maps, so breakpoints
land on any executable line — including imports, class declarations, and
deferred cleanup registrations. Step into an import and walk its top-level
statements one at a time. The runtime supports native tracing, in-process
time-travel capture, and remotely activated debugging through named
portals.
Template fences
Loup was built for code generation. A template fence
embeds Python, TypeScript, HTML, SQL, or Loup itself directly in source, with
interpolation, control-flow directives, formatter integration, and
indentation control. Nested fences use longer delimiter runs under a strict
exact-match close rule, so a generator that emits a generator stays
readable.
Type-forward, with room to move
Primitives, classes, nominal interfaces, reified
generics, sum types, structs, union types, and reflection. Core syntax avoids
magic fallback behavior — where dynamic behavior exists, it is opt-in and
syntactically explicit.
Numerics for real technical computing
First-class complex types with a C-compatible layout for
direct interop with BLAS, LAPACK, and FFTW. Fixed-point decimals with
declared precision and scale. Multi-dimensional arrays with row- or
column-major storage, a configurable index base, and first-class array-section
slicing — so Fortran-shaped code translates without being rewritten inside
out.
Memory safety, without the compiled-mode tax
Loup provides memory-safety guarantees comparable to Rust
through a layered ownership system — and, unlike Rust, none of it is gated behind
ahead-of-time compilation. A script run with loup run is held to the
same rules as a natively-compiled binary.
Shared-XOR-mutable, at the call site
The ownership transfer verbs reads,
edits, takes, and shares sit in the
signature, so what a function does to its arguments is visible to a reviewer
without opening the body.
Borrow tracking where you want it
safe functions and safe blocks
extend enforcement to multi-statement borrow tracking, and the
modifier keyword enforces exclusive access for class mutation —
adopted per function, not imposed on the whole program.
ARC, not a garbage collector
Native builds use automatic reference counting as the
mandatory strategy — there is no GC option. Finalization is deterministic:
cleanup runs when the last strong reference drops, not whenever a collector
decides to. No collector, no pause.
No silent use-after-free
A dangling unowned reference traps with a
lifetime error in every build configuration, release builds
included — a deterministic trap, never undefined behavior.
weak references simply read back empty.
Data races caught by the compiler
synchronized classes serialize mutation under
concurrency, atomic blocks close time-of-check/time-of-use races
with compiler-enforced suspension-free regions, and the
Sendable interface enforces data-race freedom across every
target.
Aliasing you prove or declare
distinct() contracts replace unverified
aliasing assumptions with guarantees that are either statically verified or
explicitly acknowledged in the source — the assumption stops being
invisible.
The escape hatch is a written record
Every programmer-asserted safety claim in Loup goes through
one annotation, unsafe, and it takes a mandatory reason string —
omitting it is a compile error, not a warning. The reason is preserved in the
binary's debug metadata and reachable through reflection. A single grep over
a codebase therefore yields its complete unsafe surface, and every entry on that
list already carries the argument for why it is sound.
Built for regulated and compliance-driven work
Memory safety has moved from an engineering preference to a
procurement question. CISA and the NSA have both published guidance urging
organizations onto memory-safe languages and asking them to publish memory-safety
roadmaps. Loup was designed with the follow-up question in mind: not just
“is it safe?” but “can you show me?”
A memory-safety story that survives review
The guarantees above hold across scripts, services,
native binaries, and bare-metal images — one answer for the whole estate
rather than a safe language for new work and an unsafe one everywhere the
performance matters. Where safety is asserted rather than proven, the
assertion is in the source, in writing, and in the shipped binary.
An unsafe surface you can enumerate
“How much of this codebase is unsafe, and why?”
is a question most stacks answer with an investigation. In Loup it is a grep
that returns a list of locations, each with a mandatory written
justification attached — the same list an auditor would have asked you to
assemble by hand.
Least privilege you can review before you run
A program's reach into the filesystem, network, and
process table is declared in its package manifest — a reviewable artifact,
checked at build time and enforced at every capability call. In the
Wasm-backed modes that declaration is a hard boundary, because there is no
native FFI to step around it. In native builds it is an audited contract,
and the two surfaces that could step outside it — unsafe and
extern native — are themselves greppable. Either way the review
question stays answerable, which is the part that matters to an
assessor.
Deterministic behavior under scrutiny
Deterministic finalization and no garbage collector mean
resource cleanup happens at a point you can name — which matters when the
requirement is a bounded response time rather than an average one. The
freestanding target removes the runtime entirely for the environments where
the smallest trusted computing base wins the argument.
Legacy modernization where the audit trail is the asset
Loup's numeric model was built to carry
COBOL and Fortran code across without reshaping it: fixed-precision decimals
with declared precision and scale, and multi-dimensional arrays with
column-major storage and a configurable index base. Dedicated mainframe and
HPC package families are in design — talk to us if a regulated migration is
on your roadmap.
A first look
Three short listings — the smallest useful script, the capability
model in practice, and generation with template fences. The
Loup books teach the rest of the
language one mode at a time, and the
Loup example programs — familiar Unix and
Windows commands recreated in Loup, dual-mode tools, and bare-metal programs — show it
at full size.
Script mode — no build step
Write the file, run the file. The JIT pipeline
compiles each statement as it goes.
# hello.loup
from system.env import (platform);
println("hello from Loup, running on:");
println(platform());
$ loup run hello.loup
Capabilities — the reach is explicit
Deny everything, then grant back only what the job
needs. The network call below fails at the permission check, not in
production.
# report.loup
let raw = await runtime.fs.readAsync("inventory.csv");
let report = await buildReport(raw);
# Not granted below — refused before it leaves the process.
await runtime.net.requestAsync(publish(report));
$ loup run report.loup --deny-all --allow-fs
Template fences — generation as a first-class job
The fence knows it is emitting Python, so the
declared formatter runs over the result before it is ever written to
disk.
let model = ```(py):(black)
class {$ name $}:
def __init__(self):
{% for (f in fields) %}
self.{$ f.name $} = {$ f.default $}
{% end %}
```;
The toolchain
One binary, one canonical format, one test runner. The tools your
team argues about on other stacks arrive already decided.
Run & build
loup run for script execution;
loup build for ahead-of-time Wasm, native, and freestanding
targets.
Test
loup test — annotation-driven discovery,
filtering, parallel jobs, and JSON or JUnit output for your CI.
Format & document
loup fmt gives one canonical format;
loup doc generates API documentation straight from source.
C interop, both directions
loup export-headers publishes a C ABI from a
Loup module; loup import-headers generates Loup bindings from an
existing C header.
Explore & verify
loup repl for an interactive session;
loup check to type-check without producing a build.
Standard library
Path and file I/O, logging, INI/CSV/TOML/YAML/XML parsers,
networking, synchronization, a testing framework, and one reactive UI model
that targets both the browser and native desktop.
Self-hosted
Loup's compiler and all six of its developer tools are
written in Loup and compiled by Loup. A trusted bootstrap compiler builds the
toolchain once; from there it rebuilds itself, and both stages produce
byte-identical output. A language that is not good enough to write its own
compiler in is not good enough to hand to your team.
Where it fits
Automation & code generation
The original brief. Fast local scripts, capability-gated,
with generation designed into the language rather than bolted on as string
concatenation.
Shipped tools & services
The same source compiled to a single native binary or a
browser-safe Wasm module — with no runtime to install on the target
machine.
Embedded & bare metal
Freestanding images with no operating system beneath them.
Loup is the language behind Code Craft AI's Foundation Platforms
work.
Get Loup
Loup Lite — free
The public build for education and training, for macOS,
Windows and Linux. It contains no encryption or decryption functionality and
leaves out some modules and packages.
Download Loup or browse the
Loup Lite releases.
Full release
Everything in Loup Lite, plus the cryptography library and
the full set of modules and packages. Available to Code Craft AI customers.
Commercial license
Commercial use needs a seat for each developer and each
autonomous agent. Personal, educational, open-source and nonprofit use is free.
Subscriptions are non-refundable, so try Loup Lite first. During the Preview,
seats are sold online to organizations in the United States, Canada, the United Kingdom, the European Union, Australia, New Zealand and Japan.
Seat pricing
Preview release
The current Loup release is a Preview. The toolchain is
self-hosted and in daily use, but the language, the standard-library APIs and the
build outputs may still change from one release to the next. Pin the release your
project builds with, and read the release notes before you upgrade.
Use Loup at work
Buy seats for your team, or tell us what you're building and
where your current toolchain is costing you.