runner.textmode.art is the sandboxed iframe runtime for
textmode.js. This monorepo
hosts the runner app served at runner.textmode.art
alongside the browser packages host apps use to embed it: the
runner-client iframe client and the
runner-protocol wire contract.
Host apps like editor.textmode.art mount the
runner to execute user sketches in an isolated browser context, away from the
host document. Inside the sandbox, the runner boots a textmode.js rendering
environment with the textmode plugin stack (synth, figlet, filters, and export)
and talks to its host through a small typed message protocol with capability
negotiation, heartbeats, and in-place runtime resets.
- Sandboxed execution: Runs user sketches in an isolated browser context, away from the host document, behind a strict parent-origin allowlist and a minimal iframe sandbox.
- textmode.js runtime: Boots a
textmode.jsrendering environment with the official plugin stack: synth, figlet, filters, and export. - Typed message protocol: Hosts and the runner exchange messages over a
MessagePortthrough a shared, validated wire contract with capability negotiation. - Live runtime control:
runCodeswaps the active sketch in place, andresetRuntimerebuilds the textmode runtime without replacing the iframe document. - Heartbeat monitoring: The runner reports liveness and status so hosts can surface connectivity to users.
The runner powers the sketches in editor.textmode.art. Open the editor and run any sketch. The sandboxed runtime handles execution with no local toolchain required.
| Workspace | Purpose | License |
|---|---|---|
apps/runner |
Hosted Vite app deployed to runner.textmode.art. | AGPL-3.0-or-later |
packages/runner-protocol |
Shared wire protocol types, capabilities, and runtime validators. | CC0-1.0 |
packages/runner-client |
Browser iframe client for embedding the runner in host apps. | AGPL-3.0-or-later |
Public package imports are root-only:
import { IframeTextmodeRuntime } from '@textmode/runner-client';
import { isRunnerMessage } from '@textmode/runner-protocol';Install dependencies from the monorepo root:
npm installStart the runner app:
npm run devRun the full workspace checks:
npm run checkGenerate package API documentation:
npm run build:docsGitHub Pages deployment is handled by
.github/workflows/deploy.yml. It runs the
project checks, builds the workspace with production host origins, and uploads
apps/runner/dist as the Pages artifact.
The runner app has its own deployment and environment notes in
apps/runner/README.md.
@textmode/runner-protocol and @textmode/runner-client are published from
this monorepo.
Verify the tarball contents before publishing either package:
npm pack --dry-run -w @textmode/runner-protocol
npm pack --dry-run -w @textmode/runner-clientPublish public scoped packages with:
npm publish --access public -w @textmode/runner-protocol
npm publish --access public -w @textmode/runner-clientPublish @textmode/runner-protocol before @textmode/runner-client when
releasing matching first-party versions, because the client depends on the
protocol package.
This monorepo contains packages under different licenses:
apps/runner: AGPL-3.0-or-laterpackages/runner-client: AGPL-3.0-or-laterpackages/runner-protocol: CC0-1.0
The root LICENSE covers the AGPL-licensed parts of the repository.
