Compiles to bytecode, runs on its own stack-based virtual machine. 36 opcodes, call frames, lexical scope chains.
HTTP server, routing with URL params, middleware chain, JSON responses — all first-class, zero npm installs.
No annotations, no interfaces. Strings, numbers, bools, arrays, objects, and functions — all inferred at runtime.
Hand-crafted lexer, recursive descent parser, and AST with 24 typed node kinds. Real .om files, real language.
Inspect every stage: ometer lex, ometer parse, ometer compile.
Full transparency, no black boxes.
The entire language — lexer, parser, compiler, VM — is written in TypeScript. Typed, readable, hackable from day one.
Raw .om source is scanned character-by-character into a typed token stream with precise line and column metadata.
lexer.tsA recursive descent parser consumes tokens and produces a fully typed AST — 24 node kinds covering every construct.
parser.ts + ast.tsThe AST is walked depth-first and flattened into bytecode Chunk objects — one per function scope. Jump back-patching for loops.
compiler.tsA stack-based virtual machine executes bytecode with call frames, lexical scopes, native stdlib, and the web framework.
vm.tsOmeter's built-in web module means zero config, zero dependencies. Import web, define routes, listen. Ship.
import web let app = web.create() let users = [] app.get("/users", fn(req, res) { res.json(users) }) app.get("/users/:id", fn(req, res) { let id = req.params.id res.json({ id: id }) }) app.post("/users", fn(req, res) { let user = req.body arr.push(users, user) res.status(201).json({ created: true }) }) app.listen(8080)
Grab Ometer from GitHub and enter the directory.
$git clone https://github.com/Ometer/ometerOnly TypeScript and ts-node are needed.
$npm installCreate hello.om
and start coding.
Execute your program with the Ometer CLI.
$npx ts-node src/cli.ts run hello.om// Your first Ometer program fn greet(name) { return "Hello, " + name + "!" } print(greet("World")) // Web server import web let app = web.create() app.get("/", fn(req, res) { res.send(greet("Ometer")) }) app.listen(3000) // → Hello, World! // → 🚀 Server on :3000
Ometer is open source and actively developed. Contributions welcome.
→ Get Started