docs/docs/en/runjs/context/libs.md
ctx.libs is the unified namespace for RunJS built-in libraries (React, Ant Design, dayjs, lodash, etc.). No import or async loading; use ctx.libs.xxx directly.
| Scenario | Description |
|---|---|
| JSBlock / JSField / JSItem / JSColumn | React + Ant Design for UI, dayjs for dates, lodash for data |
| Formulas / calculations | formula or math for Excel-like formulas and math expressions |
| Event flow / linkage | lodash, dayjs, formula, etc. in logic-only code |
| Property | Description | Docs |
|---|---|---|
ctx.libs.React | React core for JSX and Hooks | React |
ctx.libs.ReactDOM | ReactDOM (e.g. createRoot) | React DOM |
ctx.libs.antd | Ant Design (Button, Card, Table, Form, Input, Modal, etc.) | Ant Design |
ctx.libs.antdIcons | Ant Design icons (PlusOutlined, UserOutlined, etc.) | @ant-design/icons |
ctx.libs.dayjs | Date/time utilities | dayjs |
ctx.libs.lodash | Utilities (get, set, debounce, etc.) | Lodash |
ctx.libs.formula | Excel-like formulas (SUM, AVERAGE, IF, etc.) | Formula.js |
ctx.libs.math | Math expressions and evaluation | Math.js |
For backward compatibility, some libs are also on ctx: ctx.React, ctx.ReactDOM, ctx.antd, ctx.dayjs. Prefer ctx.libs.xxx for consistency and docs.
lodash, formula, math are lazy-loaded: the first access to ctx.libs.lodash triggers a dynamic import, then the result is cached. React, antd, dayjs, antdIcons are preloaded in context.
const { Button, Card } = ctx.libs.antd;
ctx.render(
<Card title="Title">
<Button type="primary">Click</Button>
</Card>
);
const { React } = ctx.libs;
const { useState } = React;
const { Button } = ctx.libs.antd;
const App = () => {
const [count, setCount] = useState(0);
return <Button onClick={() => setCount((c) => c + 1)}>{count}</Button>;
};
ctx.render(<App />);
const { Button } = ctx.libs.antd;
const { UserOutlined, HeartOutlined } = ctx.libs.antdIcons;
ctx.render(<Button icon={<UserOutlined />}>User</Button>);
const now = ctx.libs.dayjs();
const formatted = now.format('YYYY-MM-DD HH:mm:ss');
ctx.message.info(formatted);
const user = { profile: { name: 'Alice' } };
const name = ctx.libs.lodash.get(user, 'profile.name', 'Unknown');
const values = [1, 2, 3, 4];
const sum = ctx.libs.formula.SUM(values);
const avg = ctx.libs.formula.AVERAGE(values);
const result = ctx.libs.math.evaluate('2 + 3 * 4');
// result === 14
ctx.importAsync('react@19'), JSX uses that instance; do not mix with ctx.libs.antd. Load antd for that React version (e.g. ctx.importAsync('[email protected]'), ctx.importAsync('@ant-design/[email protected]')).ctx.libs.React or Hooks, run await ctx.importAsync('react@version') so the same React as the page is used.