elm-run
Elm runtime

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.