Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Studio

brink-studio is the reference web authoring app for ink — a browser IDE built on the Web & WASM bindings. It’s both a usable editor and a worked example of how to assemble a full client: editor, live preview, project navigation, and screenplay mode, all driven by @brink-lang/web.

What it does

  • Multi-file ink editor (CodeMirror 6) with diagnostics, semantic highlighting, completions, hover, go-to-definition, find-references, rename, code actions, folding, signature help, and inlay hints — every EditorSession query wired to the editor.
  • Live player — step through the compiled story with choice selection; playback state persists to localStorage and replays on reload.
  • Screenplay mode — character lines (@Name:<>) and parentheticals ((text)<>) render with hidden sigils, name coloring, and depth indicators.
  • Project navigation — a binder tree of knots and stitches (function knots marked with a distinct icon) with drag-to-reorder and structural edits, plus file tabs (pinned/unpinned) and symbol tabs.
  • Activity-bar sidebar — a VS Code-style icon column that swaps the left dock between views; the binder is the first view, the state view the second.
  • State view — a read-only runtime debugger that surfaces the running story’s status, current position, call stack, globals, and pending choices, refreshed as the story advances. (Interim raw dump; a structured, name-resolved view is planned — see issue #62.)
  • Line-element switching — convert a line between narrative, choice, sticky choice, gather, and divert via keyboard or UI.

Architecture

The studio is a pnpm workspace of focused packages. The app shell is thin; the capability lives in libraries, each independently testable.

PackageResponsibility
@brink-lang/studioapp shell + entry point (Vite)
@brink/studio-uiReact components: layout, activity bar, binder, state view, player, tabs, status bar
@brink/studio-storeZustand store — editor / compile / tabs / player / binder / layout slices
@brink/ink-editorthe CodeMirror 6 editor, state management, IDE extensions, screenplay sigils
@brink/ink-operationspure line-editing functions (no CM6, React, or wasm)
@brink-lang/webergonomic wrappers over the brink-web FFI
@brink/wasm-typesshared TypeScript interfaces (zero runtime) — decouples everything from the FFI

The dependency flow is one-directional: @brink/wasm-types is depended on by all; @brink-lang/web wraps the raw brink-web module; @brink/ink-editor consumes @brink-lang/web + @brink/ink-operations; @brink/studio-store orchestrates editor, compile, and player state; @brink-lang/studio assembles the lot.

Running it

The WASM package must exist first — @brink-lang/web resolves brink-web through a file: path to crates/brink-web/www/pkg:

# 1. build the wasm package (see Web & WASM)
wasm-pack build crates/brink-web --target web --out-dir www/pkg

# 2. install + run the studio
pnpm install
pnpm dev            # Vite dev server on http://localhost:5180
CommandPurpose
pnpm devdev server (port 5180)
pnpm buildproduction build
pnpm typecheckTypeScript, no emit
pnpm testVitest unit tests (jsdom)
pnpm test:e2ePlaywright end-to-end suite

Tech stack

React 19 · TypeScript 5.7 · Vite 6 · Zustand 5 · CodeMirror 6 · react-resizable-panels for layout · Vitest + Playwright for tests. The editor talks to the toolchain entirely through @brink-lang/web, so it stays a pure front-end with the compiler and runtime living in the WASM module.