RunMat
GitHub

WASM & TypeScript/JavaScript

Use the runmat npm package when embedding RunMat in a browser, web worker, Electron app, or Node-based tool.

npm install runmat

The public entrypoint is initRunMat. It loads the WASM module, resolves optional startup assets, creates a RunMatSessionHandle, and returns an object for executing MATLAB-compatible source.

First Execution

import { initRunMat } from "runmat";

const session = await initRunMat({
  language: { compat: "matlab" }
});

const result = await session.executeRequest({
  source: {
    kind: "text",
    name: "<repl>",
    text: "A = magic(3); disp(A)"
  }
});

console.log(result.stdout);
console.log(result.workspace.values);

session.dispose();

executeRequest accepts either inline source or a path resolved through the configured filesystem provider:

await session.executeRequest({
  source: { kind: "path", path: "src/main.m" }
});

Initialization Options

initRunMat options fall into a few practical groups.

GroupOptionsPurpose
Runtimesnapshot, enableJit, language.compatControl startup state, native-code tiering, and MATLAB compatibility mode.
GPUenableGpu, wgpuPowerPreference, wgpuForceFallbackAdapterRequest WebGPU acceleration and adapter preferences.
FilesystemfsProviderProvide file I/O for load, save, scripts, and path execution.
PlottingplotCanvas, scatterTargetPoints, surfaceVertexBudgetAttach a canvas and tune plotting LOD defaults.
DiagnosticstelemetryConsent, telemetryId, logLevel, emitFusionPlan, callstackLimit, errorNamespaceConfigure logging, telemetry, error detail, and optional fusion-plan payloads.

GPU is requested by default, but the wrapper checks for navigator.gpu and falls back to CPU execution when WebGPU is unavailable.

Results

executeRequest resolves to an ExecuteResult.

FieldUse
flow, valueText, valueJsonReturned value or output-list information.
displayEventsValues displayed during execution.
stdoutBuffered stdout/stderr stream entries.
workspaceWorkspace snapshot with names, types, shapes, residency, previews, and preview tokens.
figuresTouchedFigure handles changed by the request.
warningsStructured MATLAB warning entries.
stdinEventsPrompt/response transcript for interactive input.
errorStructured syntax, semantic, compile, or runtime error details.
profiling, fusionPlanOptional performance and acceleration diagnostics.

Execution errors are exposed as structured result data and are also coerced into useful JavaScript errors on rejected wrapper calls.

Workspace Inspection

Each workspace entry includes class, shape, dtype, residency, small previews, and an optional previewToken. Hosts can use those entries to build variable panes without asking MATLAB to print variables.

const entry = result.workspace.values.find((value) => value.name === "A");

if (entry?.previewToken) {
  const full = await session.materializeVariable(entry.previewToken, {
    limit: 4096
  });
  console.log(full.valueText);
}

materializeVariable can also use { name } or { previewToken, name } selectors. Slice options are available for large arrays.

Filesystem Providers

RunMat file I/O is backed by a JavaScript filesystem provider. If no provider is passed, the wrapper creates a default provider that tries IndexedDB and falls back to memory.

import {
  createInMemoryFsProvider,
  createIndexedDbFsHandle,
  createRemoteFsProvider,
  initRunMat
} from "runmat";

const session = await initRunMat({
  fsProvider: createInMemoryFsProvider()
});

Common choices:

ProviderUse
createInMemoryFsProviderTests, examples, and ephemeral sessions.
createIndexedDbFsHandle / createIndexedDbFsProviderBrowser persistence.
createDefaultFsProviderIndexedDB with memory fallback.
createRemoteFsProviderHTTP-backed file operations for hosted workspaces or object stores.

The provider contract covers reads, writes, metadata, directory listing, deletion, rename, and related file operations used by MATLAB-compatible I/O builtins.

Streams And Interaction

Hosts can stream output before executeRequest resolves:

const id = await import("runmat").then(({ subscribeStdout }) =>
  subscribeStdout((entry) => {
    terminal.write(entry.text);
  })
);

For interactive prompts, register an input handler on the session:

await session.setInputHandler(async (request) => {
  if (request.kind === "line") {
    return window.prompt(request.prompt) ?? "";
  }
  return { kind: "keyPress" };
});

session.cancelExecution() cooperatively interrupts a running request. Use session.dispose() when tearing down a REPL, editor pane, worker, or notebook kernel.

Plotting

For simple single-canvas plotting, pass a canvas during initialization:

const canvas = document.querySelector<HTMLCanvasElement>("#plot")!;

const session = await initRunMat({
  plotCanvas: canvas
});

await session.executeRequest({
  source: { kind: "text", name: "<plot>", text: "x = 0:0.1:10; plot(x, sin(x))" }
});

Advanced hosts can use exported helpers such as createPlotSurface, bindSurfaceToFigure, presentSurface, getPlotSurfaceCameraState, renderFigureImage, exportFigureScene, and importFigureScene to support multiple canvases, saved camera state, thumbnails, and figure replay.

Fusion And Diagnostics

Set emitFusionPlan: true during initialization, or call session.setFusionPlanEnabled(true), when a UI needs acceleration-plan details. The package also exports createFusionPlanAdapter for inspector panes that should subscribe to plan changes only while visible.

session.gpuStatus() reports whether GPU acceleration was requested, whether it is active, and which adapter was selected. session.memoryUsage() reports the current WebAssembly heap size.

Lifecycle

Each RunMatSessionHandle owns runtime state, workspace values, input handlers, and any session-level resources. Call dispose() when the surrounding UI is unmounted.

try {
  await session.executeRequest({
    source: { kind: "text", name: "<cleanup>", text: "clear" }
  });
} finally {
  session.dispose();
}