# External Packages

> Part of the NocoDB documentation (Workflows > Scripts > API Reference). Index of all pages: https://nocodb.com/llms.txt. Any docs page is available as Markdown by adding `.md` to its URL.

URL: https://nocodb.com/docs/workflows/scripts/api-reference/external-packages
Last updated: 2026-10-03

Import external NPM packages into NocoDB Scripts with dynamic imports.

NocoDB Scripts can import external JavaScript packages with **dynamic imports**. This lets you use NPM libraries in your scripts.

### Which type of imports are supported?

Only dynamic imports with `import()` are supported. Static imports (`import ... from '...'`) do not work.

### Can I import any NPM package?

Some packages do not work.

✅ **Works:** Pure JavaScript/ESM libraries (for example, lodash, dayjs, uuid, zod, axios).

❌ **Doesn't work:** Packages that require DOM (react-dom, jquery, chart.js) or Node.js APIs (fs, net, crypto Node module, express, sharp).

**Tip:** A package that runs in a Web Worker usually works in NocoDB Scripts.

### Why do some packages fail in NocoDB Scripts?

Scripts run in a Web Worker sandbox. This environment:

* Has no DOM (`document`, `window`, `HTMLElement`).
* Has no Node APIs (`fs`, `process`, `child_process`, native addons).
* Does not allow synchronous browser storage (`localStorage`, `document.cookie`).

### How do I import multiple packages?

Use separate dynamic imports:

```javascript
const _ = (await import('lodash')).default;
const dayjs = (await import('dayjs')).default;
```

### Do I need .default after import?

Many CDN-transpiled packages put the default export at `.default`. If you get `undefined`, try this:

```javascript
const dayjs = (await import('dayjs')).default;
```

### How do I pin a specific package version?

Put a version or semver tag in the CDN URL. This prevents breaking changes.

```javascript
const _ = (await import('https://esm.sh/lodash@4.17.21')).default;
```

### Common gotchas & troubleshooting

* **Named vs default exports:** Read the docs of the package. You can need named imports:
  ```javascript
  const { nanoid } = await import('nanoid');
  const { z } = await import('zod');
  ```
* **Tree-shaking:** For smaller bundles, import subpaths when they are available (for example, lodash-es functions).

### Examples that work well

* lodash / lodash-es
* dayjs
* zod
* uuid
* axios (uses fetch in browsers)

### Examples that won't work

* react-dom, jquery, chart.js, leaflet (DOM-bound)
* express, fs-extra, sharp, sqlite3 (Node-only)
* js-cookie (needs document.cookie)

### Security considerations

* Prefer pinned versions.
* Check the reputation of the package. Do not import untrusted code at runtime.
* Validate and sanitize all data that goes into third‑party libs.

### Example: Full flow

```javascript
// Load external libs
const _ = (await import('https://esm.sh/lodash@4.17.21')).default;
const dayjs = (await import('https://esm.sh/dayjs@1')).default;

// Query data
const customers = base.getTable('Customers');
const recordQueryResult = await customers.selectRecordsAsync();

// Group and format
const groupedByStatus = _.groupBy(recordQueryResult.records, r => r.getCellValue('Status'));
for (const [status, customers] of Object.entries(groupedByStatus)) {
  output.text(`${status}: ${recordQueryResult.records.length} customers`);
}
output.text(`Report generated on: ${dayjs().format('MMMM D, YYYY')}`);
```

## Good to know

* External packages are available only in the browser environment. They do not work in Webhook Scripts.
* **Important:** Only dynamic imports with `import()` are supported. Static imports (for example, `import _ from 'lodash'`) are not supported.

---

## Related pages

- [Base](https://nocodb.com/docs/workflows/scripts/api-reference/base.md): The base object in NocoDB Scripts gives access to the tables and collaborators of the current base.
- [Cursor](https://nocodb.com/docs/workflows/scripts/api-reference/cursor.md): The cursor object in NocoDB Scripts tells a script which base, table, view and row are active.
- [Table](https://nocodb.com/docs/workflows/scripts/api-reference/table.md): The Table object in NocoDB Scripts represents a table and gives methods to query, create, update, and delete its records.
- [View](https://nocodb.com/docs/workflows/scripts/api-reference/view.md): The View object in NocoDB Scripts represents a view of a table and lets you query its records.
- [Field](https://nocodb.com/docs/workflows/scripts/api-reference/field.md): The Field object in NocoDB Scripts gives access to the configuration of a table column, and the field types and their cell values.
- [RecordQueryResult](https://nocodb.com/docs/workflows/scripts/api-reference/record-query-result.md): The RecordQueryResult object in NocoDB Scripts holds the records from a query and supports pagination.
- [Record](https://nocodb.com/docs/workflows/scripts/api-reference/record.md): The NocoDBRecord object in NocoDB Scripts represents one table row and gives methods to read its cell values.
- [Session](https://nocodb.com/docs/workflows/scripts/api-reference/session.md): The session object in NocoDB Scripts gives information about the user who runs the script.
