v0.1.0 — Now Running

BUILD THE WEB. YOUR WAY.

Ometer is a dynamically typed language with its own lexer, parser, compiler, bytecode VM, and built-in web framework — crafted from scratch in TypeScript.

4
Pipeline Layers
36
Bytecode Opcodes
.om
File Extension
server.om
// A full HTTP server in Ometer
import web

let app = web.create()

app.use(fn(req, res, next) {
  print(req.method + " " + req.path)
  next()
})

app.get("/", fn(req, res) {
  res.send("Hello from Ometer")
})

app.post("/api/users", fn(req, res) {
  let body = req.body
  res.json({
    created: true,
    name: body.name
  })
})

app.listen(3000)
fn greet(who) { return "Hello, " + who } let app = web.create() app.get("/api", fn(req, res) { res.json({ ok: true }) }) import web for (item in list) { print(item) } app.listen(3000) let x = 10 ** 2 → 100 res.json({ status: 200, ok: true }) fn greet(who) { return "Hello, " + who } let app = web.create() app.get("/api", fn(req, res) { res.json({ ok: true }) }) import web for (item in list) { print(item) } app.listen(3000) let x = 10 ** 2 → 100 res.json({ status: 200, ok: true })
// Why Ometer
Everything built-in.
Nothing bolted on.
01

Custom VM

Compiles to bytecode, runs on its own stack-based virtual machine. 36 opcodes, call frames, lexical scope chains.

02

Web Framework

HTTP server, routing with URL params, middleware chain, JSON responses — all first-class, zero npm installs.

03

Dynamic Typing

No annotations, no interfaces. Strings, numbers, bools, arrays, objects, and functions — all inferred at runtime.

04

Own Syntax

Hand-crafted lexer, recursive descent parser, and AST with 24 typed node kinds. Real .om files, real language.

05

Debug Pipeline

Inspect every stage: ometer lex, ometer parse, ometer compile. Full transparency, no black boxes.

06

TypeScript Core

The entire language — lexer, parser, compiler, VM — is written in TypeScript. Typed, readable, hackable from day one.

// How It Works
Source to execution
in four stages.
01
Lexer

Raw .om source is scanned character-by-character into a typed token stream with precise line and column metadata.

lexer.ts
02
Parser

A recursive descent parser consumes tokens and produces a fully typed AST — 24 node kinds covering every construct.

parser.ts + ast.ts
03
Compiler

The AST is walked depth-first and flattened into bytecode Chunk objects — one per function scope. Jump back-patching for loops.

compiler.ts
04
VM

A stack-based virtual machine executes bytecode with call frames, lexical scopes, native stdlib, and the web framework.

vm.ts
// Web Server

A server in
ten lines.

Ometer's built-in web module means zero config, zero dependencies. Import web, define routes, listen. Ship.

  • GET, POST, PUT, DELETE routing with URL params
  • Middleware chain with next() support
  • res.json(), res.send(), res.status(), res.html()
  • req.body, req.params, req.query, req.headers
  • Runs on Node's http module under the hood
api.om
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)
// Get Started
Up and running
in minutes.
1

Clone the repository

Grab Ometer from GitHub and enter the directory.

$git clone https://github.com/Ometer/ometer
$cd ometer
2

Install dependencies

Only TypeScript and ts-node are needed.

$npm install
3

Write your first .om file

Create hello.om and start coding.

$touch hello.om
4

Run it

Execute your program with the Ometer CLI.

$npx ts-node src/cli.ts run hello.om
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

Start building.
Right now.

Ometer is open source and actively developed. Contributions welcome.

→ Get Started