lattish
React-style JSX, hooks and a DOM runtime for Tish, with an automatic JSX runtime and hot reload through Vite
- BPM
- 140
- GRADE
- SSS
- LEVEL
- 8
- RELEASES
- 14
- YEARS
- 2026–2026



JSX For Tish
Thirteen days after tish existed, it needed a way to draw things. So on March 21, 2026 I made lattish: JSX and a React-like micro framework for tish, with useState, createRoot, h and Fragment. It went up on npm the same day, and the next morning I republished it under the @tishlang scope too.
Building a renderer two weeks into a language was also a great way to test the compiler. JSX pushed the parser to handle a tricky syntax, the module system to auto-import, and me to care about how functions get named in the output. Lattish ended up being the toughest test suite tish had at that point.
JSX, But In Tish
Lattish started on March 21, 2026, and the first npm package went out the same day, version 1.0.8 under the plain name lattish, with the scoped @tishlang/lattish a day later.
It's hooks and DOM helpers so you can write JSX in Tish: useState, createRoot, h, Fragment. A component returns markup and a button increments a counter, the usual stuff, except the function keyword is fn and the compiler underneath is mine. Tish 2.12 and up auto-imports h and Fragment for JSX modules, so most files don't import anything.
It moved fast after that. A docs site two days later. Multi-backend rendering in April, pluggable host config for non-DOM targets in June, then 2.0 to go with Tish 2.0, then 3.1 and 4.0 within a week of each other in mid-June, then a fix in August so the JSX runtime suite runs natively under tish test. I've built my own framework in pretty much every era of my career, and this is the first one where the language underneath is mine too.
Following The Compiler To Two
lattish 2.0.0 came out on June 12, 2026, and the major bump was because of the compiler, not lattish. The release note says it: build on @tishlang/tish ^2.0.0. Tish went to 2, so lattish did too. Both the lattish package and the scoped @tishlang/lattish went to 2.0.0 the same day.
The releases right before it had the substance. v1.2.0 in early June fixed a package-naming bug. v1.3.0 on the 11th added pluggable host config for non-DOM render targets, which is what made scii's terminal renderer possible.
Three months earlier lattish's first release was called "release fixes." Now my projects and other people's depended on it.
Two Versions In One Day
On June 19, 2026 lattish went to 3.1.0 and then 4.0.0 on the same day, both the bare package and the scoped one. A week earlier it had been 2.0.0.
The change in v4.0.0 was small: compile the HMR runtime during tests without needing npm run build. The breaking changes in these versions were about how lattish gets built and loaded, not the API. Hooks, createRoot and h have looked the same since March. Tish kept changing how modules resolved and how JSX auto-imported, and lattish had to keep up that week or the examples stopped compiling.
After that it slowed down: v4.0.2 in July, pinning npm to 11.x, and v4.0.3 in August, running the jsx-runtime suite natively under tish test.
Lattish is the React-shaped layer for Tish: JSX, hooks and a small DOM runtime, so a Tish UI reads like the React code people already know — useState, createRoot(...).render(App), components as functions.
It supports both JSX shapes. The classic factory exports h and Fragment, and with Tish's ESM output the compiler imports them for you when a module uses JSX. The modern automatic runtime is there as well — lattish/jsx-runtime and lattish/jsx-dev-runtime exporting jsx, jsxs and Fragment — so setting the compiler's jsxImportSource to lattish is enough.
Hot reload comes through Vite with @tishlang/vite-plugin-tish. A separate lattish/hmr-runtime entry keeps a registry of mounted roots and their mount arguments, so when a module is re-evaluated it remounts in place and hook state survives the edit; rendering into an already-mounted root patches it rather than starting over. The HMR pieces are opt-in entries, so production bundles carry only the core runtime.
It is the default UI layer for tish-desktop apps and what learn.tishlang.com and tish.sh are built with, and it publishes on npm as both lattish and @tishlang/lattish.
before this
- tish2026the language its JSX and hooks run on