Every few years someone tries to fix the thing JSX never fixed: that describing UI with JavaScript expressions — ternaries, .map(), && — gets ugly the moment your logic is real. The latest attempt is TSRX, pitched by its creator as "the spiritual successor to JSX." It's worth a serious look — and a skeptical one. Here's what TSRX actually is (verified, not vibes), how it compares to JSX and TSX in a table, the one genuinely novel idea in it, and whether you should touch it yet. Short version: real, interesting, beta — don't bet production on it.
TSRX is real — and it's beta, not a blog post
TSRX stands for TypeScript Render Extensions. Per its official site tsrx.dev, it's a TypeScript language extension for building declarative UIs, using a .tsrx file extension, and it's marked "in active beta development." The compiler ships on npm as @tsrx/core at v0.1.32, MIT-licensed ("Core compiler infrastructure for TSRX syntax").
It comes from Dominic Gannaway (@trueadm) — a former React core engineer and the creator of Inferno and Lexical — and was extracted from his Ripple framework and made framework-agnostic. So this isn't a weekend toy or official React tooling; it's a serious experiment from someone who knows the problem space, at version 0.1.x.
The 30-second mental model
- JSX — an XML-like syntax extension to JavaScript. UI is expression-based: conditionals are ternaries, lists are
.map(). (React, 2013.) - TSX — JSX with TypeScript type-checking, in
.tsxfiles. Same expression model, plus types. - TSRX — a TypeScript superset where UI is statement-based: real
@if/@else,@for(...of...),@switch,@try/@catch, in.tsrxfiles, compiled ahead of time.
That statement-vs-expression shift is the whole pitch. Where JSX makes you contort logic into expressions, TSRX gives control flow first-class template syntax.
What TSRX actually documents
Straight from tsrx.dev/features — the verified feature set, not third-party embellishment:
- Control flow:
@if / @else if / @else,@for(...of...)with index/key and an@emptybranch,@switch / @case / @default(no fall-through) - Boundaries:
@try / @catcherror boundaries (with optionalreset()), and@try / @pending / @catchfor async - Scoped styles: hash-scoped
<style>blocks with a:global()escape hatch - Ergonomics:
@{...}statement containers, lazy destructuring, prop shorthand{name}, dynamic elements<{expr}>
The shape, in practice — JSX on the left, the documented TSRX equivalent on the right:
// JSX / TSX — expression-based
{items.length === 0 ? <Empty /> : items.map(i => <Row key={i.id} item={i} />)}
// TSRX — statement-based (per tsrx.dev/features)
@for (const i of items; key i.id) {
<Row item={i} />
} @empty {
<Empty />
}
The comparison table: JSX vs TSX vs TSRX
| Dimension | JSX | TSX | TSRX |
|---|---|---|---|
| What it is | XML-like syntax extension to JS | JSX + TypeScript type-checking | "TypeScript Render Extensions" — a TS language extension |
| File extension | .jsx | .tsx | .tsrx |
| Rendering model | Expression-based (ternary, .map, &&) | Expression-based + types | Statement-based template control flow |
| Control flow | JS expressions in { } | JS expressions in { } | First-class @if, @for, @switch |
| Async / error boundaries | Via React Suspense/ErrorBoundary | Same | Syntax-level @try/@catch, @try/@pending/@catch |
| Scoped styles | External (CSS Modules, styled-…) | External | Built-in hash-scoped <style> + :global() |
| Framework targets | Mainly React (Preact/Solid via own runtimes) | Same | Emits React, Preact, Solid, Vue, Ripple |
| Build step | Yes (Babel/tsc/esbuild/swc) | Yes (tsc) | Yes — @tsrx/core is compiler-only, no runtime |
| Maturity | Stable, ~11 yrs, industry standard | Stable standard for typed React | Beta — v0.1.32 |
| Creator / origin | Facebook/React (2013) | Microsoft TS + React ecosystem | Dominic Gannaway; extracted from Ripple |
| Tooling & LLM support | Vast; every tool + LLM trained on it | Vast; first-class in TS | Early; LLMs/copilots not trained on TSRX |
| Performance vs JSX | Baseline | Same runtime output | Unverified — no public benchmarks |
Every TSRX cell maps to tsrx.dev, its features page, npm, or the Ripple-TS repo — and where something isn't documented, the table says so.
The genuinely novel part: it's a compiler, not a runtime
Most "JSX killers" are just a framework's own JSX flavor. TSRX's real idea is different: @tsrx/core is parser + AST + scope analysis + codegen, and ships no runtime. Adapters emit React, Preact, Solid, Vue, or Ripple from the same statement-based source. JSX, by contrast, is React-runtime-shaped in practice. A framework-agnostic UI dialect that targets five runtimes is the part worth watching — especially if you maintain a design system or a multi-framework codebase.
Hype vs reality
- "It replaces JSX." It's the creator's framing. TSRX is a separate
.tsrxdialect that compiles down to JSX/React (and other targets) and coexists with your.tsxfiles — it doesn't retire JSX. - "Conditional hooks — call hooks inside
if/loops freely." This is not on the official features page. Third-party guides (e.g. Better Stack) describe it as the compiler hoisting hooks to the top of the function — useful framing, but it adds indirection between what you write and what React receives. Treat it as a third-party description. - "Write once, run on five frameworks." The multi-target compiler is real; portability of real component logic across runtimes with different semantics is undocumented and unproven.
- "Faster than JSX / built for the agentic era." No reviewed source — official or otherwise — publishes a performance benchmark, and the "agentic" line is marketing. In fact, today's friction runs the other way: LLMs and copilots are trained on JSX, so they won't autocomplete TSRX's divergent syntax well yet.
Builder takeaway: should you adopt TSRX yet?
It's real, documented, and genuinely interesting — and it's beta (v0.1.32) by definition, not a production decision. Don't bet shipping code on it today: the API will move, lint/codegen tooling is thin, and the LLM/editor assists you rely on are trained on JSX, so you'll lose autocomplete and copilot leverage exactly where TSRX diverges.
What is worth your time now: read the features page, build a throwaway prototype, and evaluate the one novel idea — a runtime-free, framework-agnostic compiler that emits React, Solid, Vue, Preact, and Ripple from statement-based source with real control flow, async/error boundaries, and scoped styles. Ignore the "agentic era" marketing and the overstated "conditional hooks" claim. Revisit for production when it reaches a stable 1.0 with a settled API and real tooling.
FAQ
Is TSRX a new framework I have to migrate to? No. It's a TypeScript language extension (a .tsrx dialect) with its own parser and compiler — @tsrx/core ships no runtime. It compiles to React, Preact, Solid, Vue, or Ripple.
What's the actual difference between TSX and TSRX? TSX is JSX with TypeScript type-checking — still expression-based (?:, .map(), &&). TSRX is statement-based: it adds @if/@else, @for(...of...), @switch, and @try/@catch as first-class template control flow.
Who made it, and is it official React tooling? Dominic Gannaway (@trueadm), former React core engineer and creator of Inferno and Lexical. It is not official React tooling — it was extracted from his Ripple framework and generalized.
Can TSRX and JSX/TSX live in the same codebase? Third-party reports say yes — .tsrx files are meant to coexist with .tsx and compile to the React you already ship, consistent with the site's TypeScript/JSX-compatibility claim.
Is it production-ready in 2026? No — "active beta development," @tsrx/core v0.1.x. Use it to learn and prototype, not for production-critical work.