{"id":543929,"date":"2026-06-19T18:33:14","date_gmt":"2026-06-19T18:33:14","guid":{"rendered":"https:\/\/www.europesays.com\/ie\/543929\/"},"modified":"2026-06-19T18:33:14","modified_gmt":"2026-06-19T18:33:14","slug":"tsrx-a-framework-agnostic-alternative-to-jsx","status":"publish","type":"post","link":"https:\/\/www.europesays.com\/ie\/543929\/","title":{"rendered":"TSRX: A Framework-Agnostic Alternative to JSX"},"content":{"rendered":"<p><a href=\"https:\/\/tsrx.dev\/\" rel=\"nofollow noopener\" target=\"_blank\">TSRX<\/a>, a new TypeScript language extension created by <a href=\"https:\/\/x.com\/trueadm?lang=en\" rel=\"nofollow\">Dominic Gannaway<\/a>, the former React and Svelte core team engineer behind Inferno, Lexical and Ripple, has been released in alpha, billing itself as a framework agnostic successor to JSX for building declarative user interfaces.<\/p>\n<p>Announced <a href=\"https:\/\/x.com\/trueadm\/status\/2046696157066264846\" rel=\"nofollow\">on X<\/a>, where Gannaway described it as the &#8220;spiritual successor to JSX&#8221; that was &#8220;extracted from Ripple, and made framework agnostic&#8221;, TSRX compiles a single .tsrx component file to multiple runtime targets. Plugins such as @tsrx\/react, @tsrx\/preact, @tsrx\/solid, @tsrx\/vue and @tsrx\/ripple walk a shared AST and emit idiomatic output for each runtime, including scoped CSS, so <a href=\"https:\/\/tsrx.dev\/\" rel=\"nofollow noopener\" target=\"_blank\">new targets<\/a> can be added as standalone compiler plugins without changing the language itself.<\/p>\n<p>The headline idea is moving common UI ergonomics from convention into syntax. TSRX introduces statement level control flow inside templates using @if, @for, @switch and @try, alongside prop shorthands, lazy destructuring and component scoped styles. A component body uses an @{ &#8230; } statement container that ends in a single rendered output.<\/p>\n<p>As documented in the <a href=\"https:\/\/tsrx.dev\/features\" rel=\"nofollow noopener\" target=\"_blank\">features guide<\/a>, scoped styles live in a  block whose selectors the compiler rewrites with a unique hash, while error and async boundaries are expressed declaratively through @try, @catch and @pending rather than wrapper components.<\/p>\n<p>On <a href=\"https:\/\/news.ycombinator.com\/item?id=47854857\" rel=\"nofollow noopener\" target=\"_blank\">Hacker News<\/a> one reader wrote:<\/p>\n<blockquote><p>&#13;<\/p>\n<p>I&#8217;m in love with everything about this.<\/p>\n<p>&#13;<br \/>\n&#13;<\/p>\n<p>An oxfmt plugin would be appreciated!<\/p>\n<p>&#13;\n<\/p><\/blockquote>\n<p>While another argued:<\/p>\n<blockquote><p>&#13;<\/p>\n<p>I think this is a step in wrong direction. We really need to move away from this XML inside\/alongside JS ugliness prevalent in the webdev ecosystem. What I really want are kotlin style builders or F# style computation expressions.<\/p>\n<p>&#13;\n<\/p><\/blockquote>\n<p>The announcement post on X drew 130 replies and 1.6k likes, and it prompted <a href=\"https:\/\/hackmd.io\/@0u1u3zEAQAO0iYWVAStEvw\/Hk2Jiv8T-l\" rel=\"nofollow noopener\" target=\"_blank\">an article<\/a> from Ryan Carniato, the creator of SolidJS, titled \u2018Why TSRX isn\u2019t just your Favourite Templating Language\u2019. In it, he summarises the implications for Vue, Svelte, React, Solid, and <a href=\"https:\/\/mitosis.builder.io\/\" rel=\"nofollow noopener\" target=\"_blank\">Mitosis<\/a> developers separately, for example, React developers might escape some of the tedious hook rules, while SolidJS users may find it at odds with the framework\u2019s transparency.<\/p>\n<p>For teams considering it, the <a href=\"https:\/\/tsrx.dev\/getting-started\" rel=\"nofollow noopener\" target=\"_blank\">getting started guide<\/a> covers Vite, Rspack, Turbopack and Bun setups, plus Prettier, ESLint and a tsrx-tsc command line type checker for CI. Adoption is per file, as a <a href=\"https:\/\/medium.com\/@aguzzimarcello\/tsrx-for-react-developers-conditional-hooks-co-located-styles-and-multi-target-uis-fe733c45afcf\" rel=\"nofollow noopener\" target=\"_blank\">Medium write up<\/a> notes: a .tsrx file compiles to a .tsx equivalent component, so it can be introduced in one place while the rest of a codebase stays untouched. That same piece cautions that the project is alpha, advising readers to &#8220;experiment, do not migrate&#8221;.<\/p>\n<p>Compared to its closest peers, TSRX is not a runtime like Solid or Vue, nor a templating dialect tied to a single compiler like Svelte. It sits closer to JSX itself, an authoring syntax that several frameworks can consume.<\/p>\n<p>TSRX is a framework-agnostic TypeScript language extension created by Dominic Gannaway, the former React and Svelte core team engineer behind Inferno, Lexical and Ripple. TSRX is open source under the MIT licence and remains in alpha, with further compiler targets promised.<\/p>\n","protected":false},"excerpt":{"rendered":"TSRX, a new TypeScript language extension created by Dominic Gannaway, the former React and Svelte core team engineer&hellip;\n","protected":false},"author":2,"featured_media":543930,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_share_on_mastodon":"0"},"categories":[267],"tags":[365,362,363,364,366,7266,18,117,19,17,37356,101758,233313,101757,19535],"class_list":["post-543929","post","type-post","status-publish","format-standard","has-post-thumbnail","category-arts-and-design","tag-arts","tag-arts-and-design","tag-artsanddesign","tag-artsdesign","tag-design","tag-development","tag-eire","tag-entertainment","tag-ie","tag-ireland","tag-javascript","tag-react","tag-tsrx-alternative-jsx","tag-typescript","tag-web-development"],"share_on_mastodon":{"url":"https:\/\/pubeurope.com\/@ie\/116778212068383928","error":""},"_links":{"self":[{"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/posts\/543929","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/comments?post=543929"}],"version-history":[{"count":0,"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/posts\/543929\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/media\/543930"}],"wp:attachment":[{"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/media?parent=543929"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/categories?post=543929"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.europesays.com\/ie\/wp-json\/wp\/v2\/tags?post=543929"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}