I am delighted to be able to share my new Elm compiler project with you today.
eco - Elm Compiler Optimized - is a new optimizing compiler infrastructure for Elm. Here is eco - introduction
eco is fully open sourced today - GitHub - eco-lang/eco-compiler: eco compiler for elm · GitHub
Some things about eco that may interest you:
- Self-compiling “boot strapped” compiler.
- Front-end in Elm, back-end in C++. No Javascript and no Haskell.
- Generates x86 native code via MLIR and LLVM (arm64 for Mac soon)
- Generational Garbage Collector
- Aims to be 100% Elm compatible (core, json, bytes, http, regex, url, parser, time, already implemented)
- Can run existing Platform.Worker + NodeJS programs with Elm.init and ports in Javascript linking to a native binary for the Elm program.
- Int compiles to native 64-bit integers
- There are > 150,000 elm-test tests against the front-end compiler pipeline.
What are the long-term goals here ?
- A multi-threaded Elm runtime with parallel Tasks and TEA Actors
- Support for servers with high core counts and large RAM - eco supports 8TB address space.
- Throughput and latency to match C++/Rust/zig
- Ref counting and optimistic mutation optimizations to replace GC.
- Keep the gradual migration path from existing 0.19 Elm programs on NodeJS
- Potential pathway to compiling web apps to WASM.
Ok, those are some grand claims and there is a long way still to go to achieve them, but I wanted to share my vision for what I believe will be possible.
The version being made public today is 0.1.0 alpha.
Please note that the alpha label is a suggestion that you should interpret this work as experimental today. There will be bugs, possibly even severe ones. Please find some bugs and tell me about them in the GitHub issues. This is the whole point of making an alpha release and starting the journey of the code from my computer to meet the real world.
Some limitations of eco 0.1.0 alpha:
- Single threaded, including the whole compiler pipeline, the compiler is not fast.
- Runtime performance is moderate - roughly the same as running under NodeJS.
- Minimal IO API (to support the compiler).
- GC pause times are significant, it is single threaded, your program thread does the collection work.
- “hello world” binary is 8MB in size - mostly debug symbols. Needs debug stripping and not linking unused kernel code - should be around 100KB after that.
- 0.1.0-alpha release only supports Linux x86. Windows and Mac builds will follow very soon.
It is risky to make an early release such as this if people are expecting higher performance because it compiles to native. Please be understanding of the early version number and experimental nature of this project at this time.
I am confident that performance can be greatly improved, all the techniques are known, it is just a question of putting in the work to implement them. Right now there are so many levers to pull on to make it faster, the harder choice is choosing the correct levers to pull first.
eco has its compiler front end implemented in Elm. This part started its life as the Guida elm-in-elm compiler. eco adds a new pipeline to that codebase for an optimizing compiler pass that generates native machine code. The back-end code generation part of eco is implemented in C++ and built on top of LLVM and MLIR. There is a well defined bytecode at the boundary between front-end and back-end, called the “eco dialect”.
The compiler is already capable of self compiling. This is a 160K LOC codebase, some of which makes heavy use of continuation passing style. There are over 150,000 tests applied to the code, and over 1000 end-to-end Elm test programs that try to cover many corner cases of the language itself. So you should find that the compiler is well tested and capable of handling large and complex programs.
I began working on eco in November last year. Since this is the second elm-to-native compiler you are hearing about in just a few short weeks! It is worth mentioning that eco is an entirely separate and independant project. eco builds a new compiler pipeline that branches off at the type checking phase to enable more high level optimisations that operate at the language level and make use of type information - such as monomorphization.
Full disclosure - most of the code is implemented by AI, Claude Code specifically. It is not “vibe coded”, there is a strong software engineering and design element to drive that code generation. Without AI this project could have taken 2 or 3 years to implement at least. The structure of the code is good and not a mess. My current feeling is that I should use less AI during a tidy up phase of the code, in order to ensure that the kinds of mistakes that AI can make get reviewed out. But I want to be transparent about this in case you are against AI - you might not like what you find here!


