Three layers
Primitives, components, composition.
Architecture
The library has four layers. You should be able to drop in at any of them and have the ones below behave sanely.
#1. Primitives - svelte-p5
<P5Canvas>mounts a p5 instance, exposes it viabind:instance, callsremove()on unmount. Dynamically imports p5 on the client so SSR builds don't choke.createP5Bridge(initial)wraps an object in a$stateproxy and returns it under.state.utils/hasdisableFES,createColorCache,createFontAtlas,hitTest. Re-exported from the main entry.
Use this layer alone when you know p5 and don't want any abstraction between your sketch and the canvas.
#2. Components - svelte-p5-components
Chrome and overlays for canvas apps. Nothing in here knows what's being visualised; it's all layout and input plumbing.
<Sketch>wraps<P5Canvas>with aResizeObserverand autopixelDensity.<CanvasFrame>is the layout shell: snippet slots for top / bottom / leftRail / rightRail / canvas / overlay with pointer-events discipline baked in.<SplitPane>is the two-panel resizable split (horizontal or vertical).<HoverTooltip>is an edge-aware floating tooltip anchored to a screen point.<EntityToggleList>is the speaker/actor/series toggle panel with colored swatches and optional grouping.<TimelineTrack>/<TimelineScrubber>/createMediaSynccover scrubbable timelines, with segments, view windows, hover previews, and honest disclosure when video playback overrides the speed multiplier.<FPSMonitor>and<SketchDebug>are rAF-driven debug overlays.<DraggableWindow>and<DraggableSketch>are floating-panel primitives (neodrag-powered).
Use this layer when you're building a real UI around sketches and don't want to rewrite ResizeObservers, drag logic, resize coordination, scrub plumbing, or FPS overlays.
#3. Viz contract - svelte-p5-viz
The interface between chrome and the visualizations it hosts. Added in 0.3 once a handful of consumer apps all grew the same informal shape for their viz panels — this package formalises it.
VizPanel<TData, TConfig>is the renderer contract: atypestring, adefaultConfig, and arender(ctx, data, config)method that returns aPanelResult.createPanelRegistry()is the type→impl lookup a scene runner uses to resolve aPanelInstanceto a live panel.SceneConfigis the JSON-serialisable shape (panels plus a single / split / grid layout) that describes a multi-viz dashboard.createSceneState()is the Svelte 5$statehelper for chrome-level shared hover and highlight ids.
No visualization code ships here on purpose — that belongs in apps or in a future viz-pack. This package is the contract the studio (see §5) will be designed against.
#4. Composition - your app
Example 03 is a reasonable template: a toolbar with global controls, three floating sketches, a reactive class in .svelte.ts as the single source of truth. The library doesn't ship app-level code on purpose.
An app that adopts svelte-p5-viz typically looks like:
- a
PanelRegistryregistered at boot with the app's panel implementations, - a
SceneConfig(hand-written JSON, URL-encoded state, or a future studio export), - a scene runner that resolves each
PanelInstanceto aVizPaneland callsrenderinside the p5 draw loop.
#5. No-code studio (future)
A visual editor that lets researchers and educators compose scenes without writing code is the longer-term direction. It will live in its own repo, not as a library, and will depend on layers 1-3. See no-code-product.md.
#The one rule
p5 draws pixels, Svelte does everything else.
- UI chrome (toolbars, modals, sidebars, windows) is Svelte components and CSS.
- Visualization content lives inside a
<P5Canvas>or<Sketch>. - Shared state is
$state, either viacreateP5Bridgeor a reactive class. - Layout is CSS Grid or Flexbox, never hand-computed inside a canvas.
Apps that cross this boundary - drawing buttons in the canvas, simulating text inputs with p.text, computing layout in pixels - are the ones that feel janky. The browser is already excellent at the everything-else part; let it do that.
#What's deliberately missing
- No store API. Svelte 5's runes replace
writable(). - No data-viz primitives (scales, axes, tooltips).
d3-scaleis onepnpm addaway and does the job better than anything this library could ship. A dedicatedsvelte-p5-vizpackage may land if demand shows up. - No dock manager.
<DraggableWindow>handles floating panels; if you want VSCode-style splits and tabs, use dockview. - No canvas-based UI. If it needs accessibility, focus, or input, it's HTML.
#Versioning
0.x is unstable. Minor bumps can break public API. Anything that does will have BREAKING CHANGE: in its commit so release-please bumps the major line when we eventually reach 1.0. New features are additive; deprecations get a minor bump with a warning before they disappear.