Roadmap
On Thu, 15 Oct 2026, by @lucasdicioccio, 794 words, 0 code snippets, 14 links, 1images.
Roadmap
No package in this repository has had a stable release yet, and the language itself is still settling — see the repository README for where the language grammar stands. This page is about something narrower: which implementations of tramaj exist, and which are wanted next.
Where things stand today
Six independent implementations target the same grammar and are checked
against a shared, language-neutral
conformance corpus —
template/context/expected-output triples that all must reproduce
byte-for-byte, per case, in both concrete and symbolic evaluation modes.
That’s a deliberately strong bar: a case belongs in the corpus only if
independently written implementations can run it identically.
| Implementation | Language | Status |
|---|---|---|
tramaj | PureScript | reference implementation, checked against the corpus; tramaj-halogen folds to Halogen, tramaj-cli is its CLI |
tramaj-hs | Haskell | independent port, checked against the same corpus |
tramaj-rs | Rust | independent port, checked against the same corpus; tramaj-cli-rs is its CLI |
tramaj-js | JavaScript / TypeScript | independent port, checked against the same corpus; tramaj-react folds to React |
tramaj-py | Python | independent port on the standard library alone, checked against the same corpus; python -m tramaj is its CLI |
tramaj-go | Go | independent port on the standard library alone, checked against the same corpus; tramaj-go is its CLI |

tramaj-purs and tramaj-halogen are on the PureScript registry (0.4.1),
tramaj-hs on Hackage (0.4.0.0), tramaj-rs and tramaj-cli-rs on
crates.io (0.2.0), tramaj-py on PyPI as tramaj (0.2.0), and
tramaj-js and tramaj-react on npm as @lucasdicioccio/tramaj-js and
@lucasdicioccio/tramaj-react (0.2.0), each with language v5. tramaj-go
and tramaj-cli are in no package registry yet, and are used as source or
git dependencies.
Each has its own changelog page and Atom feed. See Integrating tramaj for what’s
actually usable from each right now, including the fold each one does or
doesn’t ship.
The native-implementation wish list is done
Earlier versions of this page asked for native JavaScript, Python and Rust
implementations, so that hosts in those ecosystems would get what
PureScript and Haskell hosts already had: an in-process parser and
evaluator, with no subprocess and no JSON round-trip just to get a Node.
All three exist now — tramaj-js, tramaj-py and tramaj-rs — and each
passes the full corpus in both modes, v3 and v4 extensions included. A Go
port, tramaj-go, has since joined them on the same terms.
Language v5, in all six: two number types, arithmetic, sorting and number formatting
Numbers are now an integer and a float, two types, and a template can
compute with ten named arithmetic builtins, round among them. It can also
sort a list with sort-by and sort-by-descending, and write a number with
format-number. Together these are language v5,
announced here. The specification and the corpus fixtures
are written, and all six implementations have all of it:
| Implementation | Language v5 | Released in |
|---|---|---|
tramaj (PureScript), tramaj-halogen, tramaj-cli, playground | yes | tramaj-purs and tramaj-halogen 0.4.1 (PureScript registry) |
tramaj-hs | yes | 0.4.0.0 (Hackage) |
tramaj-js, tramaj-react | yes | 0.2.0 (npm) |
tramaj-rs, tramaj-cli-rs | yes | 0.2.0 (crates.io) |
tramaj-go | yes | on main, no tagged version |
tramaj-py | yes | 0.2.0 (PyPI, as tramaj) |
The corpus cases for these carry a "profiles" field, and an implementation
skips the cases that list a name it does not provide. All six provide every
name but one: the integer range, 53 bits in PureScript and TypeScript and
64 bits in the other four, so each skips the few cases written for the other
range. The number split and the arithmetic profile are no longer skippable:
a case that lists "int-float" or "arithmetic" fails in an implementation
that does not provide it. The split changes existing output:
Migrating to integers and floats
lists how.
?shape is an accepted design without normative text, and no implementation
has it. See
Two designs accepted.
Desired next: folds, and Python type definitions
- Folds. Only PureScript (
tramaj-halogen) and JavaScript (tramaj-react) ship a fold to a rendering target. A DOM fold for JS, a fold to a common Python templating output, and a fold for at least one Haskell or Rust UI or markup library are the obvious next pieces. - Type definitions for the Python modules.
tramaj-pyannotates its functions, but ships nopy.typedmarker, so a type checker treats the installed package as untyped. Shipping type definitions would let a Python host check its calls the way a TypeScript host already can. - Releases. Every registry now has a v5 release. Releases happen when there are major changes, and each package’s version tracks the language version it implements in its major digit.
This is a wish list, not a schedule: there’s no committed timeline or assigned owner for any of it.
What “done” looks like for a new implementation
tramaj-hs, tramaj-rs, tramaj-js, tramaj-py and tramaj-go are the templates to
follow, since they were added after the language had settled on a
normative spec and output format (tramaj-py is the smallest: one module
per concern, standard library only). A new implementation is considered on
par with the existing ones once it:
- implements the grammar and evaluation rules in
reference.md, including the static restrictions that make imports, action keys, andctx(...)paths analyzable without evaluation (see Properties); - encodes and decodes the
NodeAST exactly pernode-json.md, including the round-trip guarantee (decode(encode(n)) == n); - passes every case in the
conformance corpus,
in both
concreteandsymbolicmode, byte-for-byte againstexpected.json; - optionally, but ideally: a fold analogous to
tramaj-halogen’sfoldToHalogenfor at least one popular rendering target in that ecosystem (e.g. a DOM fold for JS, a common Python templating output for Python).
The v3 (?/!, v3-symbols.md) and v4
(%, v4-types.md) extensions are both
shipped and part of the same conformance bar — a new implementation isn’t
considered complete while targeting only the v2 core.
Contributing an implementation
If you’re taking on one of these, the corpus is the fastest way to find out what you got wrong: it’s meant to be run against a from-scratch implementation just as it’s run against the six that exist, and a case that byte-for-byte matches all of them today is a strong signal your evaluation semantics agree with theirs. Open an issue on the repository before investing heavily in one — coordinating on which language is being worked on avoids duplicate effort.