docs/docs/en/runjs/jsx.md
RunJS supports JSX syntax, allowing you to write code similar to React components. JSX is automatically compiled before execution.
ctx.libs.React.createElement and ctx.libs.React.Fragment.ctx.libs.React after compilation.ctx.importAsync('[email protected]'), JSX will switch to using the createElement method from that specific instance.RunJS includes React and common UI libraries built-in. You can access them directly via ctx.libs without using import:
createRoot if needed)const { Button } = ctx.libs.antd;
ctx.render(<Button>Click</Button>);
When writing JSX directly, you don't need to destructure React. You only need to destructure from ctx.libs when using Hooks (such as useState, useEffect) or Fragment (<>...</>):
const { React } = ctx.libs;
const { useState } = React;
const Counter = () => {
const [count, setCount] = useState(0);
return <div>Count: {count}</div>;
};
ctx.render(<Counter />);
Note: Built-in React and external React imported via ctx.importAsync() cannot be mixed. If you use an external UI library, React must also be imported from the same external source.
When loading a specific version of React and UI libraries via ctx.importAsync(), JSX will use that React instance:
const React = await ctx.importAsync('[email protected]');
const { Button } = await ctx.importAsync('[email protected]?bundle');
ctx.render(<Button>Click</Button>);
If antd depends on react/react-dom, you can specify the same version via deps to avoid multiple instances:
const React = await ctx.importAsync('[email protected]');
const { Button } = await ctx.importAsync('[email protected]?bundle&[email protected],[email protected]');
ctx.render(<Button>Button</Button>);
Note: When using external React, UI libraries like antd must also be imported via ctx.importAsync(). Do not mix them with ctx.libs.antd.
<Button type="primary">Text</Button><>...</> or <React.Fragment>...</React.Fragment> (requires destructuring const { React } = ctx.libs when using Fragment){expression} in JSX to insert variables or operations, such as {ctx.user.name} or {count + 1}. Do not use {{ }} template syntax.{flag && <span>Content</span>} or {flag ? <A /> : <B />}array.map() to return a list of elements, and ensure each element has a stable key.const { React } = ctx.libs;
const items = ['a', 'b', 'c'];
ctx.render(
<ul>
{items.map((item, i) => (
<li key={i}>{item}</li>
))}
</ul>
);