Skip to content

Concepts

Embedded engines

The JavaScript SDK supports running SurrealDB as an embedded database through two engine plugins. Choose the one that matches your environment:

EnginePackageEnvironmentStorage options
WebAssembly@surrealdb/wasmBrowsersmem://, surrealkv:// (dedicated worker only)
Node.js@surrealdb/nodeNode.js, Bun, Denomem://, surrealkv://

RocksDB (rocksdb://) and IndexedDB (indxdb://) were removed in SurrealDB 4.0. The Node.js and WebAssembly engine pages describe how existing data moves to SurrealKV.

Both plugins work with ES modules (import), not CommonJS (require).

Note

Neither engine runs on Android or iOS. Hermes has no WebAssembly runtime, and the Node.js engine is a native Node addon that React Native cannot load. Apps built with Expo or React Native connect to a remote instance over wss:// or https://.

Each plugin runs a SurrealDB engine that ships as its own package: @surrealdb/wasm-native for WebAssembly and @surrealdb/node-native for Node.js. From plugin version 3.0.4, the engine is a peer dependency, so you choose which SurrealDB release runs embedded in your app, independently of the plugin version. Install a specific release with npm install --save @surrealdb/node-native@3.3.2, or let your package manager pick the newest release in the supported range. The Node.js and WebAssembly engine pages describe pinning and how to check the loaded version.

The @surrealdb/wasm package runs SurrealDB inside a browser environment. It can run inside a Web Worker to keep the main thread responsive.

The engine supports in-memory databases, and persistent storage with SurrealKV over the browser's Origin Private File System (OPFS). Persistent storage requires a web worker.

npm install --save @surrealdb/wasm @surrealdb/wasm-native
import { Surreal, createRemoteEngines } from 'surrealdb';
import { createWasmEngines } from '@surrealdb/wasm';

const db = new Surreal({
    engines: {
        ...createRemoteEngines(),
        ...createWasmEngines(),
    },
});

await db.connect('mem://');

These engines run on the main thread of the page, so they support mem:// only. A surrealkv:// database needs the web worker setup below.

A web worker runs JavaScript on a separate thread in the background of the page, so database work in a worker does not delay the page's own drawing and input. createWasmWorkerEngines starts the worker, loads the engine into it, and passes each query and its result between the page and the worker, so the rest of the application uses db in the same way as on the main thread. The only worker-specific line is the import of the worker script, written below in the ?worker form that Vite uses to bundle a file as a worker. Other bundlers have their own form for this:

import { Surreal, createRemoteEngines } from 'surrealdb';
import { createWasmWorkerEngines } from '@surrealdb/wasm';
import WorkerAgent from '@surrealdb/wasm/worker?worker';

const db = new Surreal({
    engines: {
        ...createRemoteEngines(),
        ...createWasmWorkerEngines({
            createWorker: () => new WorkerAgent(),
        }),
    },
});

await db.connect('mem://');

A worker created this way is a dedicated worker, which is where a persistent surrealkv:// database has to run. Connect to one with a surrealkv:// endpoint:

await db.connect('surrealkv://myapp');

The WebAssembly engine page describes what a persistent browser database needs from the page, including persistent storage permission and one tab per database.

If you are using a bundler like Vite, you may need to exclude the WASM package from dependency optimisation and enable top-level await:

vite.config.js
export default {
    optimizeDeps: {
        exclude: ['@surrealdb/wasm'],
        esbuildOptions: {
            target: 'esnext',
        },
    },
    esbuild: {
        supported: {
            'top-level-await': true,
        },
    },
};

The @surrealdb/node package runs SurrealDB within Node.js, Bun, or Deno. It supports in-memory databases and persistent storage via SurrealKV.

npm install --save @surrealdb/node @surrealdb/node-native
import { Surreal, createRemoteEngines } from 'surrealdb';
import { createNodeEngines } from '@surrealdb/node';

const db = new Surreal({
    engines: {
        ...createRemoteEngines(),
        ...createNodeEngines(),
    },
});

await db.connect('mem://');
// or persist with SurrealKV:
await db.connect('surrealkv://./data');

To enable versioned storage for temporal queries, append ?versioned=true to the connection string:

await db.connect('surrealkv://./data?versioned=true');

When using the Node.js engine, you must close the connection with .close() when you are done to ensure the database is properly shut down:

await db.close();

Was this page helpful?