logologo
Get Started
Tutorials
Guide
Development
Plugins
API
Home
English
简体中文
日本語
한국어
Español
Português
Deutsch
Français
Русский
Get Started
Tutorials
Guide
Development
Plugins
API
Home
logologo
RunJS Overview
Importing Modules
Rendering in Container

Global Variables

window
document
navigator

ctx

ctx.blockModel
ctx.collection
ctx.collectionField
ctx.dataSource
ctx.dataSourceManager
ctx.element
ctx.exit()
ctx.exitAll()
ctx.filterManager
ctx.form
ctx.getModel()
ctx.getValue()
ctx.getVar()
ctx.i18n
ctx.importAsync()
ctx.initResource()
ctx.libs
ctx.location
ctx.logger
ctx.makeResource()
ctx.message
ctx.modal
ctx.model
ctx.notification
ctx.off()
ctx.on()
ctx.openView()
ctx.render()
ctx.request()
ctx.requireAsync()
ctx.resource
ctx.route
ctx.router
ctx.setValue()
ctx.sql
ctx.t()
ctx.view
Previous PageRunJS Overview
Next PageRendering in Container

#Importing Modules

In RunJS, you can use two types of modules: Built-in modules (accessed directly via ctx.libs without importing) and External modules (loaded on demand via ctx.importAsync() or ctx.requireAsync()).


#Built-in Modules - ctx.libs (No import required)

RunJS includes several built-in libraries that can be accessed directly through ctx.libs. You do not need to use import or asynchronous loading for these.

PropertyDescription
ctx.libs.ReactReact core, used for JSX and Hooks
ctx.libs.ReactDOMReactDOM (can be used for createRoot, etc.)
ctx.libs.antdAnt Design component library
ctx.libs.antdIconsAnt Design icons
ctx.libs.mathMath.js: Mathematical expressions, matrix operations, etc.
ctx.libs.formulaFormula.js: Excel-like formulas (SUM, AVERAGE, etc.)

#Example: React and antd

const { Button } = ctx.libs.antd;

ctx.render(<Button>Click Me</Button>);

#Example: ctx.libs.math

const result = ctx.libs.math.evaluate('2 + 3 * 4');
// result === 14

#Example: ctx.libs.formula

const values = [1, 2, 3, 4];
const sum = ctx.libs.formula.SUM(values);
const avg = ctx.libs.formula.AVERAGE(values);

#External Modules

When you need third-party libraries, choose the loading method based on the module format:

  • ESM Modules → Use ctx.importAsync()
  • UMD/AMD Modules → Use ctx.requireAsync()

#Importing ESM Modules

Use ctx.importAsync() to dynamically load ESM modules by URL. This is suitable for scenarios like JS blocks, JS fields, and JS actions.

importAsync<T = any>(url: string): Promise<T>;
  • url: The ESM module address. Supports shorthand formats like <package>@<version> or subpaths like <package>@<version>/<file-path> (e.g., vue@3.4.0, lodash@4/lodash.js). These will be prefixed with the configured CDN base URL. Full URLs are also supported.
  • Returns: The resolved module namespace object.

#Default: https://esm.sh

If not configured otherwise, shorthand forms will use https://esm.sh as the CDN prefix. For example:

const Vue = await ctx.importAsync('vue@3.4.0');
// Equivalent to loading from https://esm.sh/vue@3.4.0

#Self-hosted esm.sh Service

If you need to use an internal network or a self-built CDN, you can deploy a service compatible with the esm.sh protocol and specify it via environment variables:

  • ESM_CDN_BASE_URL: The base URL for the ESM CDN (defaults to https://esm.sh)
  • ESM_CDN_SUFFIX: Optional suffix (e.g., /+esm for jsDelivr)

For self-hosting, refer to: https://github.com/nocobase/esm-server


#Importing UMD/AMD Modules

Use ctx.requireAsync() to asynchronously load UMD/AMD modules or scripts that attach to the global object.

requireAsync<T = any>(url: string): Promise<T>;
  • url: Supports two forms:
    • Shorthand path: <package>@<version>/<file-path>, similar to ctx.importAsync(), resolved according to the current ESM CDN configuration. When resolving, ?raw is appended to request the raw file directly (usually a UMD build). For example, echarts@5/dist/echarts.min.js actually requests https://esm.sh/echarts@5/dist/echarts.min.js?raw (when using the default esm.sh).
    • Full URL: Any full CDN address (e.g., https://cdn.jsdelivr.net/npm/xxx).
  • Returns: The loaded library object (the specific form depends on how the library exports its content).

After loading, many UMD libraries attach themselves to the global object (e.g., window.xxx). You can use them as described in the library's documentation.

Example

// Shorthand path (resolved via esm.sh as ...?raw)
const echarts = await ctx.requireAsync('echarts@5/dist/echarts.min.js');

// Full URL
const dayjs = await ctx.requireAsync('https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js');

Note: If a library provides an ESM version, prefer using ctx.importAsync() for better module semantics and Tree-shaking.