SDK

Embedded terminal

Drop the full terminal — VS Code-style chrome, file tree, editor, live preview and a ⌘K palette — into any page with one element. It's a Shadow DOM web component, so its styles are fully isolated from (and can't be touched by) your app.

The terminal ships as a separate subpath, @userland-run/nano-sdk/terminal, so the headless core stays lean: a headless consumer never downloads the UI bundle (WebGPU renderer, CodeMirror, icons).

Declarative — the <nano-terminal> element

javascript
import { defineNanoTerminal } from "@userland-run/nano-sdk/terminal";
defineNanoTerminal(); // registers <nano-terminal> once
html
<nano-terminal
  wasm-url="/nano/nano.wasm"
  service-worker-url="/nano-sw.js"
  style="display:block; height:560px"
></nano-terminal>

The element attaches its own shadow root, injects the scaffold + scoped stylesheet, boots a NanoVM and launches an interactive sh session. Because everything lives in the shadow root, the terminal's CSS can neither leak onto your page nor be overridden by it.

Imperative — createTerminal()

javascript
import { createTerminal } from "@userland-run/nano-sdk/terminal";

const term = await createTerminal(hostEl, {
  wasmUrl: "/nano/nano.wasm",
  features: { editor: false, preview: false },
});
term.openFile("/etc/hostname");

createTerminal(target, config) mounts into a selector, element, or shadow root and resolves to a TerminalHandle { vm, openFile, showPreview, refreshFiles }. The <nano-terminal> element is a thin wrapper over it.

Configuration

TerminalConfig
Meaning (and matching attribute)
wasmUrl
nano.wasm URL — attr wasm-url (default "/nano.wasm")
serviceWorkerUrl
preview-bridge service worker — attr service-worker-url
shellCommand
booted session — attr shell-command (default "sh -i")
fontPx
terminal font size — attr font-px (default 12)
ramMB
guest RAM — attr ram-mb (default 1800)
features
toggle catalog / palette / files / editor / preview — attrs no-catalog, no-editor, …
Point wasm-url at a build with the terminal exports (term_feed / term_reset) and a bundled BusyBox, so the in-page VM can paint a grid and boot a shell.

Same engine, no UI

Need the terminal's capabilities — files, catalog, run, serve — without rendering anything? Use the headless feature service, createHeadless().