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
import { defineNanoTerminal } from "@userland-run/nano-sdk/terminal";
defineNanoTerminal(); // registers <nano-terminal> once<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()
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
Same engine, no UI
Need the terminal's capabilities — files, catalog, run, serve — without rendering anything? Use the headless feature service, createHeadless().