@ui5-community/jsx-runtime
A plugin-based JSX runtime for UI5: views are written as .tsx files with per-control typing, and the JSX compiles to plain new Control(settings) calls.
A UI5 view written as .view.xml is parsed at runtime and its attributes are strings the TypeScript compiler never sees. This runtime takes the same view as a .tsx file, where the compiler checks every control's props against that control's own type, and turns the _jsx calls Babel emits into plain new Control(settings) calls: no React, no VDOM, no reconciler, with reactivity still coming from UI5 bindings. Above the core directives (jsx, <Fragment>, <For>, <If>) sits a plugin SPI of five extension points, Renderer, IntrinsicHandler, PropertyApplier, ChildrenProcessor and Scope, and the shipped <Switch>/<Case>/<Default> plugin is its worked example. In a project it is a library dependency plus three pieces of configuration: transformJSX in ui5.yaml, jsx and jsxImportSource in tsconfig.json, and ui5.community.jsx.runtime in manifest.json. XML and TSX views coexist in one app because both produce sap.ui.core.mvc.View instances, so a conversion can go one view at a time. The documentation site labels the project Incubation, and the requirements spec, marked a draft proposal, puts the TypeScript floor at 5.0 and newer.
Facts
Where it sits
Who is behind it
In the atlas: maintains 69@ui5-communitymaintainerPeter MuessigContributes to this
In the atlas: maintains 14, contributes to 80, wrote 1@petermuessig1 contributor
Before choosing this
Conditions
PracticalFunctional boundary
Lowercase HTML tags such as <div> typecheck but throw: the default renderer constructs UI5 controls, and the HTML-aware renderer plugin is described as planned. withScope restores the previous scope on a synchronous return only, so an await inside its callback leaks the scope on runtimes without AsyncLocalStorage. A view that has to stay adaptable through UI5 flexibility has no path here yet: the project's Devtoberfest sessionUI5 Views, Reimagined: Type-Safe TSX for a Modern Dev ExperienceA Devtoberfest 2026 session on @ui5-community/jsx-runtime, the incubation project that lets a UI5 view be written as TSX: XML-like markup that the TypeScript compiler checks against the control's own types and a Babel plugin turns into the constructor calls UI5 already makes. The edge to the runtime rests on the session's own description, which gives the project's documentation site as the session's documentation. The TypeScript support edge holds because that is the session's subject — per-property checking, completion on every attribute, renames that carry through a view, and typed event objects that remove the casts — alongside what stays unchanged: string and expression bindings, controllers, routing and i18n, and XML views living beside TSX ones in the same app. The build edge rests on the setup, where ui5-tooling-transpile is given the JSX transform in ui5.yaml; the walkthrough then builds a bookshop app on a CAP OData service and names what is still missing, UI flexibility and native HTML among it.published 2026-10-09 states that flexibility support is not built in yet.
What it declares
Every artifact
- Type
- Package
- Origin
- By a community org
As a package
- Where it runs
- does not say
- Distributed through
- npm
Parts and add-ons
Parts 2
Connections
Writing UI5 apps and libraries in TypeScript
Scaffolded UI5 TypeScript app consuming the JSX runtime
Showcase and documentation app of @ui5-community/jsx-runtime
Babel's JSX transform. It compiles the JSX in a UI5 project's .tsx files into the _jsx and _jsxs calls that @ui5-community/jsx-runtime@ui5-community/jsx-runtimeA plugin-based JSX runtime for UI5: views are written as .tsx files with per-control typing, and the JSX compiles to plain new Control(settings) calls.community org, ui5 turns into UI5 control constructors, and is installed as an optional peer at version 7.
Framework core: module loader, MVC runtime, binding, routing, theming
UI5 CLI extension transpiling code during the UI5 build
Scaffolded UI5 TypeScript app consuming the JSX runtime
Showcase and documentation app of @ui5-community/jsx-runtime
Download
Install
npm add @ui5-community/jsx-runtimeDerived from the package name. No recipe recorded; the README has the configuration.
Learn more
- UI5 Views, Reimagined: Type-Safe TSX for a Modern Dev ExperienceUI5 Views, Reimagined: Type-Safe TSX for a Modern Dev ExperienceA Devtoberfest 2026 session on @ui5-community/jsx-runtime, the incubation project that lets a UI5 view be written as TSX: XML-like markup that the TypeScript compiler checks against the control's own types and a Babel plugin turns into the constructor calls UI5 already makes. The edge to the runtime rests on the session's own description, which gives the project's documentation site as the session's documentation. The TypeScript support edge holds because that is the session's subject — per-property checking, completion on every attribute, renames that carry through a view, and typed event objects that remove the casts — alongside what stays unchanged: string and expression bindings, controllers, routing and i18n, and XML views living beside TSX ones in the same app. The build edge rests on the setup, where ui5-tooling-transpile is given the JSX transform in ui5.yaml; the walkthrough then builds a bookshop app on a CAP OData service and names what is still missing, UI flexibility and native HTML among it.published 2026-10-09Peter Muessig, YouTube — SAP Developers playlists
Where it sits in your app
Download
transformJSX option switches on the Babel JSX plugin and assembles the rest of the pipeline from tsconfig.json and browserslist, so no hand-written .babelrc.json is needed. Version 3.12 or later..tsx files into the _jsx and _jsxs calls the runtime consumes. The package README states version 7, because the v8 major changed the plugin API, and the requirements spec puts the floor at 7.20 with runtime: "automatic".sap.ui.core and sap.ui.base, its modules load under the ui5.community.jsx.runtime namespace, and what happens after a JSX expression is UI5's: metadata, applySettings, bindings, aggregations and events. The requirements spec, marked a draft proposal, states UI5 1.130 LTS and newer.README
quoted from ui5-community/jsx-runtime under Apache-2.0, read@ui5-community/jsx-runtime
A plugin-based JSX runtime for UI5, write UI5 views as .tsx files with per-control TypeScript typing. No React, no VDOM, no reconciler. JSX expressions compile to plain new Control(settings) calls.
import Page from "sap/m/Page";
import Button from "sap/m/Button";
import View from "sap/ui/core/mvc/View";
export default class Hello extends View {
createContent() {
return (
<Page title="Hello">
<Button text="Click me" press=".onPress" />
</Page>
);
}
}
Install
pnpm add @ui5-community/jsx-runtime
pnpm add -D @babel/plugin-transform-react-jsx@^7
Pin the Babel plugin to v7 (@^7) — the v8 major changed the plugin API and the JSX transform fails against it. It's an optional peer dependency that ui5-tooling-transpile (≥ 3.12) loads for you.
Enable the JSX transform in ui5.yaml — no .babelrc.json needed. ui5-tooling-transpile assembles the TypeScript/UI5/env presets from your tsconfig.json + browserslist, and transformJSX adds the JSX plugin:
customConfiguration:
config-ui5-tooling-transpile: &cfgTranspile
transformJSX:
runtime: automatic
importSource: "ui5/community/jsx/runtime"
Configure TypeScript:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "ui5/community/jsx/runtime",
"types": ["@openui5/types", "@ui5-community/jsx-runtime"]
}
}
Declare the library in your app's manifest.json:
{
"sap.ui5": {
"dependencies": {
"libs": {
"ui5.community.jsx.runtime": {}
}
}
}
}
Finally, make sure UI5's loader can find the runtime's modules. When
the UI5 tooling serves your app it resolves them automatically. If you
bootstrap UI5 from a CDN, add an explicit resource root pointing
the ui5.community.jsx.runtime namespace at wherever you serve the
package's dist/resources:
<script id="sap-ui-bootstrap"
src="https://sdk.openui5.org/resources/sap-ui-core.js"
data-sap-ui-libs="sap.m,ui5.community.jsx.runtime"
data-sap-ui-resource-roots='{
"ui5.community.jsx.runtime": "./resources/ui5/community/jsx/runtime/"
}'
data-sap-ui-compat-version="edge"></script>
What you get
Three layers of API surface:
- Core:
jsx,jsxs,Fragment,<For>,<If>. Always available. - Plugin SPI: five extension points (
Renderer,IntrinsicHandler,PropertyApplier,ChildrenProcessor,Scope) let plugins add directives, intrinsics, and output adapters without touching the core. - Sample plugin:
<Switch>/<Case>/<Default>insrc/plugins/switch/demonstrates the SPI on a non-trivial example.
Read the full concept documentation for the walkthrough.
Example: opting a plugin in
import { withScope } from "ui5/community/jsx/runtime";
import { Switch, Case, Default, switchProcessor } from "ui5/community/jsx/runtime/plugins/switch";
createContent() {
return withScope({ childrenProcessors: [switchProcessor] }, () => (
<VBox>
<Switch on={kind}>
<Case when="info"><Title text="Info" /></Case>
<Case when="warn"><Title text="Warning" /></Case>
<Default> <Title text="—" /></Default>
</Switch>
</VBox>
));
}
License
History
Fixes 1
Notes
Patch Changes
- #17
6b026c2Thanks @petermuessig! - Fix<If condition={binding}>throwing "expected boolean" when the bound model path resolves to a non-boolean value (e.g. a string). TheifProcessornow injectsformatter: Booleaninto the binding info so any truthy/falsy model value is coerced tobooleanbefore UI5 setsvisibleon child controls.
Fixes 1
Notes
Patch Changes
-
#15
b473e5cThanks @petermuessig! - Fix string-syntax data binding for<For each>and<If condition>.Previously, using a binding string like
each="{/items}"on<For>threw"requires a binding info", andcondition="{/flag}"on<If>was silently treated as a literal truthy value instead of bindingvisible. Both now accept the idiomatic UI5 string form alongside the existing object form (each={{ path: "/items" }}), using the sameBindingParser.complexParserpattern introduced in the aggregation-binding fix (commit 28f2e36).
-
Fixes 2
Notes
Patch Changes
-
#10
2e704f8Thanks @petermuessig! - Fix: auto-prefix-id no longer prefixes UI5-generated ids (closes #9).Controls like
sap.m.Menucreate internal helper controls (e.g. aMenuWrapper) whose ids are generated by UI5 (matchingManagedObjectMetadata.isGeneratedId). Previously, when JSX constructed such controls inside a view withgetAutoPrefixId() === true, those generated ids were passed throughview.createId(), making the internal control unresolvable at add-time and causing aTypeError.The runtime now guards the
createId()call with!ManagedObjectMetadata.isGeneratedId(rawId)so only author-supplied (static) ids are prefixed. Generated ids pass through untouched. Closes #9. -
#10
e9ffb68Thanks @petermuessig! - JSX view-construction errors are now logged viasap/base/Login addition to propagating. Previously, whencreateContent()threw (sync or async), the error was only visible as a rejected Promise and, in the showcase, as a text message rendered into the DOM. It was never written to the UI5 Log, making it invisible to log-scraping tooling andsap-ui-log-leveldebugging.installViewScopeBridgenow wraps thecreateContent()call with a try/catch (sync) and a.catchon the returned Promise (async). On failure it callsLog.errorwith the full error message, the stack trace, and the component id"ui5.community.jsx.runtime", then re-throws / re-rejects so existing propagation behaviour is unchanged.The showcase's
ExploreSampleview also addsLog.errorcalls in both its demo-view and docs-load catch handlers so the exact user-facing message appears in the log as well.
-
Fixes 1
Notes
Patch Changes
28f2e36Thanks @petermuessig! - Fix string-syntax aggregation bindings clobbering their row template. Binding an aggregation with the classic string form plus a JSX child, e.g.<VBox items="{view>/rows}"><FlexBox/></VBox>, now installs an aggregation binding whosetemplateis the child — parity with the object formitems={{ path: "view>/rows" }}. Childless string aggregation bindings are unaffected (UI5 already handled those). Fixes #6.
Fixes 1
Notes
Patch Changes
-
#4
b464107Thanks @petermuessig! - Fixkeyprop being silently dropped for controls that declare it as a property (e.g.sap.ui.core.CustomData).Babel's automatic JSX transform always extracts
keyfrom the element's attributes and passes it as the third argument tojsx(type, props, key)— it is never present in thepropsobject. The runtime now detects this case and forwards the value to the control'skeyproperty when the control metadata declares one. For controls without akeyproperty the behaviour is unchanged.Fixes #3.
-
Features 1
Notes
Minor Changes
7e382a2Thanks @petermuessig! - Initial release of the plugin-based JSX runtime for UI5. Author UI5 views as.tsx— JSX compiles to plainnew Control(settings)calls, with no React, no virtual DOM, and no reconciler. Ships the core directives (jsx,<Fragment>,<For>,<If>), a five-extension-point plugin SPI (Renderer,IntrinsicHandler,PropertyApplier,ChildrenProcessor,Scope), and the<Switch>sample plugin. Requires Node.js>=22.13.0and, for the build,ui5-tooling-transpile>=3.12.0with itstransformJSXoption.
All notable changes to this package are documented here. This file is generated by changesets — the first entry is written when the initial release is versioned.
Others providing
Compare all 7 on the TypeScript support page →- ui5-task-dts-generatorui5-task-dts-generatorA UI5 builder task that generates d.ts files, TypeScript type declarations, during the build of a UI5 library written in JavaScript, by wrapping @ui5/dts-generator.independent, ui5UI5 builder task generating d.ts type declarationsfrom UI5
- @openui5/sap.ui.core@openui5/sap.ui.coreThe OpenUI5 core: the module loader, the MVC runtime, data binding, routing, theming and the test stack, which is everything a UI5 app does before a single community package is added.sap official, ui5Framework core: module loader, MVC runtime, binding, routing, themingfrom UI5
- babel-preset-transform-ui5babel-preset-transform-ui5A Babel transformer that converts modern ECMAScript or TypeScript UI5 code (ES modules and classes) into the sap.ui.define and Control.extend syntax the UI5 loader expects.community org, ui5Babel transformer from modern ES or TypeScript to UI5 module syntaxfrom UI5
- ui5-task-transpileui5-task-transpileA UI5 Tooling task that transpiles TypeScript, ES modules and other ES6+ sources during the build so the UI5 runtime can load them.community org, ui5UI5 Tooling task transpiling TypeScript and ES modulesfrom UI5
- @ui5/mcp-server@ui5/mcp-serverSAP's MCP server for UI5 development: ten tools that scaffold an app or a card, read the project in front of the agent, and run the linter and the manifest validator against it.sap official, ui5MCP server for UI5 development with ten toolsfrom UI5
- @ui5/webcomponents@ui5/webcomponentsSAP's UI elements as standard custom elements, ui5-button among them, implementing SAP Fiori design and usable from plain HTML, React, Angular or Vue.sap official, ui5SAP's UI elements as standard custom elementsfrom UI5
Details
Sources
Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.
Compatibility and provenance
Contributors
History in the atlas
- the Incubation label the documentation site carries, and the TypeScript floor of 5.0 the requirements spec states
- both of those, and a view that has to stay adaptable through UI5 flexibility
- the Babel floor of 7.20 with `runtime: "automatic"`, and UI5 1.130 LTS and newer
- Both the root README and the package README end on "[Apache License 2.0](LICENSE).", and the crawled npm record for @ui5-community/jsx-runtime reports the same SPDX identifier.
- The type owns the key for a package (CONCEPT-038) and the record stated nothing, which reads as "does not say" while the README's repository layout says of this package "Publishable to npm." and the package README's install step is "pnpm add @ui5-community/jsx-runtime". The sibling packages in the same monorepo are each marked "Not published" and state no distribution.
- First seen.
For your agent
- Ref
artifact:ui5-community-jsx-runtime- JSON
- /artifacts/ui5-community-jsx-runtime.json
- MCP
- Connecting an agent