essence

Reliable. Flexible. Delightful.

A language for the web that catches your bugs as you are writing them, fits the stack you already have, and is a joy to use.

Precise Arithmetic

Arbitrary-precision integers and rationals, so your calculations are always accurate.

0.1::add(0.2)::is(0.3) § true

§ JavaScript
§ 0.1 + 0.2 == 0.3 // false

Easy State Management

Every data type is immutable, so equality is structural and state stays predictable.

constant recordA = { items = [1, 2], ok = true }
constant recordB = { items = [1, 2], ok = true }

recordA::is(recordB) § true

No Runtime Errors

A value that might be missing does not compile until you handle the case, so undefined never reaches your users.

match items::item(at 10) -> Integer {
	case #Value(item) { <- item.price }
	case #Empty       { <- 0 }
}

§ items[10].price // undefined is not an object

Clutter-Free Syntax

Write what you mean and nothing more, so there is no ceremony to read past.

constant next = { state with { user.name = "Ada" } }

§ const next = {
§   ...state,
§   user: { ...state.user, name: "Ada" },
§ }

Batteries Included

Type checking, formatting, debugging and editor support, together with a standard library that is a pleasure to use.

  • Type Checker
  • Formatter
  • Language Server
  • Debugger
  • Standard Library
  • VS Code Extension

01 — Adoption

Start With a Single File

Rewrite nothing. Move the part that has to be right — pricing, rules, game state — and import it from the app you already have.

02 — Interop

Compiles to JavaScript

Plugins for Vite, Bun and esbuild build your .es files with everything else, and generated declarations give TypeScript real types. Hot reload keeps working.

03 — Diagnostics

Easy to Debug

Every error points at the exact span, explains it in plain words and often shows what to write instead — in your editor as you type, not just in CI.

esc