Ministry of Technology · Republic of Nomashae

Harmony

A small, indentation-based language for GUI apps where state and view are separated by grammar, not by convention. Compiles straight to a self-contained, runnable HTML/JS file.

Phase 1 · working compiler
Star on GitHub Clone the repo
store / action > the only place state changes component > reads state, declares layout emit > the one checked bridge between them
See It Run

Compile it, click it, that's the whole loop

This is the actual counter app from the examples folder, clone the repo and run these three lines yourself

examples/counter_app.harm
store CounterStore:
  state count: Int = 0

  action increment:
    count += 1

component CounterApp:
  bind count from CounterStore.count

  Column(padding: 16, spacing: 12):
    Text(text: f"Count: {count}", style: "heading")
    Button(label: "+", on_click: emit CounterStore.increment)

app CounterDemo:
  window(title: "Counter", width: 320, height: 200):
    mount CounterApp
$ node bin/harmony.js build examples/counter_app.harm --out counter_app.html && open counter_app.html
Why Harmony

The separation is a grammar rule

Not a convention you can forget, a shape the parser won't let you break

State Ownership Graph
The semantic analyzer maps every state field to the store that owns it, then rejects any write that doesn't come through an action.
Read-only components
There is no statement syntax reachable from inside a component. "The view mutated global state" isn't a bug you can write, even by accident.
emit, checked at compile time
The one bridge between state and view. Reference a store or action that doesn't exist and you get a SemanticError with a line number, not a runtime crash.
Pluggable codegen
The codegen backend only ever sees the validated, ownership-checked AST, never raw syntax. A second backend is additive, not a rewrite.
One self-contained file
Build output is a single runnable .html file with an embedded reactive Store (subscribe/publish), no bundler, no install step for the person running it (unless advanced mode - coming soon).
Debuggable by design
The tokens and ast CLI commands dump the lexer stream and parsed AST as JSON, so a confusing build error is easy to trace back to one node.
Under The Hood

Compiler pipeline

A from-scratch lexer, parser, AST, and semantic analyzer, feeding a pluggable codegen backend

01
Lexer
Indentation → explicit INDENT / DEDENT / NEWLINE tokens
02
Parser
Recursive-descent + Pratt expression parsing
03
Semantic
Builds the State Ownership Graph, enforces it
04
Codegen
Walks the validated AST → HTML/JS backend
05
.html
Self-contained, runnable in any browser
Where Things Stand

Phase 1 status

An early, functional slice. Not a complete language yet.

What's real

  • Full lexer with indentation and multi-line bracket continuation
  • Parser covering store / component / app, control flow, f-strings, lambdas
  • Compile-time enforcement of the state-ownership rule
  • Working HTML/JS backend with a reactive Store (subscribe/publish)
  • Verified end-to-end with simulated DOM events
01Conditional rendering + list rendering inside components
02A real VDOM diff instead of subtree replacement
03A second codegen backend (native or WASM) to prove the pluggable-backend architecture
04Multi-file module system
05Optional static type checking
Try It

Get Harmony running in under a minute

Requires Node.js 16+. No bundling, no type inference, no optimization passes, just a tree-walk over a small AST

Clone it, build the counter app, click the button

That's the whole loop the compiler is built to prove out.