Elm on the server and command line
elm-run executes Elm natively on your server and command line.
Build secure, dependable tools with an enjoyable language.

No JavaScript glue
Run Elm without bundling a JS runtime, without polyfills, and without “server-side Elm via JS”.
Small, portable artifacts
Distribute compact bytecode that executes predictably across environments.
Designed for analysis
Keep enough structure to inspect behavior and enforce capability boundaries before execution.
Secure distribution as a first-class goal
Instead of downloading opaque native binaries—or source scripts that require heavy toolchains—ship an artifact that’s quick to verify and quick to run. Think “WebAssembly-style portability”, but with programmer's intent preserved for auditing.
Where it fits
CLI tools, automation, server workers, database extensions, game engines, and embedded runtimes.
Security First
Verify behavior, not reputation. The runtime can reject, restrict, or sandbox programs that exceed their declared capabilities.
Capability declarations
Programs declare what they intend to do; elm-run can validate that the
bytecode matches the declaration.
- Network: allow/deny outbound connections
- Filesystem: read-only, write restrictions, path whitelists
- Processes: allow/deny spawning and shell access
- Runtime limits: memory, time, and I/O quotas
Enforcement at runtime
Even if a program is malicious, the runtime boundary can prevent it from performing prohibited effects.
- Default-deny for effects you don’t permit
- Auditable policy: human-readable permission sets
- Fast “inspect then run” workflow
Readable when you want it
The compiled artifact is structured enough to be inspected and rendered back into a source-like view. You don’t need to reverse engineer a native binary to understand what it does.
No compromising on speed
Once a program passes inspection, the runtime executes it at native speeds with low overhead.
How it works
A small runtime that loads Elm bytecode, validates it, and executes it with explicit effect boundaries.
1) Compile
Elm code compiles to a compact bytecode format designed for transport and inspection.
2) Inspect
On the first run elm-run decodes the artifact and checks declared
capabilities.
3) Run
Once the code is verified and approved, all future executions are under the allowed capability policy and runtime limits, at native speeds.
It doesn't work alone
elm-run works in concert with software artifact management. In the age of
hostile
supply chain, we can't stick to just running code blindly. We're building the whole toolchain to support
the
secure distribution and execution of Elm programs outside the browser.
Answers
When do I get to use it?
When it passes the 0.2.0 gate.
Does elm-run change the Elm language?
No. It runs Elm as-is, preserving semantics, architecture patterns, and the feel of Elm programs. It's just a runtime and it will never ever impinge on Elm the language.
Is this a replacement for compiling to JavaScript?
No—it's an additional deployment target. If the browser is your target, compile to JS. If you want
Elm outside the browser, use elm-run.
What's it written in?
Itself. With a bit of C, and a bit of assembly. We bootstrapped with C, but now it builds itself.
Why didn't you just use X like the hip thing Y?
We like to make the whole cake.
Is it fast?
It is fast. Speed is the goal, but not at all costs. Security first. Watch the roadmap, we'll make precise statements about speed as we go along.
I want native binaries or nothing!
It compiles to native, but maybe not how you imagine. We want speed where it matters, too. Until we can inspect native with the same certainty, distribution will be in inspectable format.
