A small language for work that is not.
Built for jobs where a failure costs money. A mistake stops at the line that made it, or before the program starts, and every error is a value your code can catch.
Apple Silicon only. The Linux curl command works here too.
Unpack, put ecko.exe on your PATH, done.
Why Ecko?
Four reasons, starting with the one we can measure.
No warm-up tax
-
ecko
2.5ms
-
python
9.9ms
-
node
19.4ms
-
ruby
46.3ms
Median of 100 runs; the 10 runs before them were discarded. Ecko v0.62.0, python 3.12.3, node 24.4.0, ruby 3.2.3, on an AMD Ryzen 9 5950X under Linux.
Against AOT-compiled languages the gap is smaller. But they ask for a build step and a linker before you’ve written a line. Ecko skips both.
A bytecode compiler and a stack VM, with no tier that has to get hot. The thousandth run costs what the first one did. CLIs, serverless handlers and dev reloads are up before your finger leaves the key.
-
No garbage-collection pauses
Memory is freed when the last reference goes away. Nothing stops the process to sweep, so a request at the tail isn’t waiting on a collector pass.
fn handle(body) { n = len(body) n } # body drops at return - no GC pause laterreference counted · freed at scope exit
-
Concurrency without the ceremony
Parallel work is something you write, not something you configure. Each worker gets its own snapshot, so a batch job can fan out across a dataset with no shared state to get wrong.
amounts = [1250, 900, 3400] fees = pmap(amounts, fn(a) a * 3 / 100)channel() · async fn · await · pmap()
-
Checked before it runs
Every program is checked before its first side effect, including one a model wrote. An undefined name or a wrong argument count stops the run instead of letting it half-finish.
ai[T]validates the reply against the type you declared, and with no API key it answers from a deterministic offline mock.type Lead = Hot { company: String, seats: Int } | Demo lead = ai[Lead] "Acme wants 40 seats"ai[T]· checked against your types · mock mode offline
The language server ships with it.
It is ecko lsp, inside the same binary you
install. Diagnostics, completion, hover and go-to-definition in any editor
that speaks LSP. First-party extensions for VS Code, Cursor and
JetBrains; everything else points at the same server.
// Zed - settings.json
{
"lsp": {
"ecko": { "binary": { "path": "ecko", "arguments": ["lsp"] } }
},
"languages": {
"Ecko": { "language_servers": ["ecko"] }
}
}
// JetBrains, without the plugin: LSP4IJ, command ecko, argument lsp
Keep ecko on your PATH - or give the
absolute path. Highlighting works without it; diagnostics,
completion and hover wait for the server. Full editor setup →
Install it in one command.
A mistake stops the same way in a billion-row batch job as in a single request. One binary, four platforms, nothing else to install. If it turns out not to be for you, it is one file to delete.
Homebrew: brew install ecko-lang/tap/ecko ·
binaries and checksums →