npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xenosystem/workbench

v1.2.3

Published

Shared workbench runtime for the XENO panel platform — mounts @xenosystem/block-sdk panels from a registry into a Dockview layout, with a framework-free layout model, reconciliation, and persistence.

Readme

@xenosystem/workbench

The shared workbench runtime for the XENO panel platform — the generalization of Motion's Dockview layout system into a host-agnostic library.

It mounts @xenosystem/block-sdk panels from a PanelRegistry into a docking layout, reconciles the registry into panes, and persists layout through a pluggable seam — so Pixel, Motion, Sound, Canvas, and xeno-apps all get the same docking/layout runtime instead of each re-implementing it. This is step 2 of the panel-platform build order (spec §9).

Two halves, one contract

| Entry point | What | Depends on | |---|---|---| | @xenosystem/workbench | The framework-free layout model, reconciler, controller, persistence, and an in-memory dock substrate. A headless consumer (agent, builder, SSR, tests) can read and drive a layout with no DOM. | @xenosystem/block-sdk only | | @xenosystem/workbench/react | The React + Dockview rendering half: <Workbench>, the pane adapter, and hooks. | + react, dockview-react |

The spec's rule holds: layout is described in the locked PanelLayout vocabulary (position / width / height / visible / order per panel — §9), not a new one.

Install

npm install @xenosystem/workbench @xenosystem/block-sdk
# React host also needs:
npm install react react-dom

Quickstart (React host)

import { createStore } from 'zustand/vanilla'
import { PanelRegistry, createAppHost, type PanelModule } from '@xenosystem/block-sdk'
import { Workbench } from '@xenosystem/workbench/react'
import { createWebLayoutStorage, WORKBENCH_THEME_TOKENS } from '@xenosystem/workbench'
import 'dockview-react/dist/styles/dockview.css' // Dockview's base layout CSS (the XENO theme is automatic)

const registry = new PanelRegistry()
registry.register(colorPanel)
registry.register(layersPanel)

const store = createStore(/* the app's existing zustand store */)

export function App() {
  return (
    <Workbench
      registry={registry}
      // pass WORKBENCH_THEME_TOKENS so panel bodies use the same chrome colors:
      hostFor={(module: PanelModule) =>
        createAppHost({ manifest: module.manifest, store, theme: WORKBENCH_THEME_TOKENS })}
      storage={createWebLayoutStorage('myapp.workbench')}
      onReady={(controller) => { /* drive menus: controller.togglePanel('layers') */ }}
    />
  )
}

<Workbench> applies the canonical XENO panel look automatically (see below), builds a WorkbenchController once the dock is ready, restores any persisted layout (else seeds from each panel's defaultSlot), and auto-saves on user drags/resizes. Each pane resolves its panel from the registry, mounts it through the host you supply, and gets the iconic tab (lucide icon + title) for free.

The canonical theme (zero-config)

The dark monochrome XENO chrome — rounded gapped panels, compact uppercase tab strip, lucide icon + title tabs — is injected and applied by default; no CSS import, no theme prop. Panels draw from the same tokens via WORKBENCH_THEME_TOKENS (both --panel-* and --xeno-* names). Opt out with <Workbench theme="none">; a static @xenosystem/workbench/theme.css and ensureWorkbenchThemeInjected() are exported for manual control. Ported faithfully from xeno-motion, aligned to DESIGN_SYSTEM.md (monochromatic white accent, neutral-gray text). See INTEGRATION.md and examples/theme-preview.html.

Tab-icon bundle-size trade-off (honest note). The zero-config default resolves manifest icons from lucide's static icons map via a lazy import('lucide-react') (the main entry — it has a package exports map and bundles correctly in Vite/Rollup production). It deliberately does NOT use lucide-react/dynamic, whose extension-less star re-export Rollup collapses to an empty chunk (lucide#2743) → blank packaged window while dev works. The cost: the static map is not tree-shakeable, so a lazy chunk carries the full lucide set (loaded on demand, off the critical path). We chose correctness over size for the default. To ship only the icons you use, pass a tree-shaken renderer: renderPanelIcon={(name) => /* your mapped <Icon/> */}.

Quickstart (headless)

import { PanelRegistry } from '@xenosystem/block-sdk'
import { WorkbenchController, MemoryDockAdapter } from '@xenosystem/workbench'

const controller = new WorkbenchController({
  registry,                       // a PanelRegistry
  adapter: new MemoryDockAdapter(), // no DOM
})
controller.mount()                // seeds panels by defaultSlot
controller.togglePanel('layers')
const snapshot = controller.snapshot() // serializable PanelLayout map

What's in the package

| Module | Exports | Purpose | |---|---|---| | model | PanelLayout, WorkbenchLayout, WorkbenchSnapshot, PANEL_SLOTS | The per-panel layout vocabulary + a mutable model (seed/show/hide/move/size/snapshot). | | adapter | DockAdapter, MemoryDockAdapter, DockPanelSpec | The substrate seam + a shippable in-memory implementation. | | reconcile | reconcile, ReconcilePlan | Pure registry × layout × current-panes → add/remove/update plan. | | controller | WorkbenchController, WorkbenchState | The generalization of Motion's layoutStore (show/hide/toggle/switch/save/restore/reset), observable. | | presets | WorkspacePreset, presetFromLayout, layoutFromPreset, serialize/deserializeWorkspaces | Named workspaces (Motion's WORKSPACE_LAYOUTS generalized). | | storage | LayoutStorage, InMemoryLayoutStorage, createWebLayoutStorage | Pluggable, version-gated persistence. | | mountPanel | mountPanel, MountedPanel | The single bridge from a PanelModule to a DOM element. | | @xenosystem/workbench/react | Workbench, PanelPane, DockviewDockAdapter, useWorkbench, useWorkbenchState | React + Dockview rendering. | | @xenosystem/components/chrome | PANEL_METRICS, class constants, rowClass/badgeClass/…, PANEL_PRIMITIVES_CSS, ensurePanelPrimitivesInjected | Canonical panel chrome. @xenosystem/workbench/primitives is a deprecated pointer. | | @xenosystem/components/chrome (React) | PanelFrame, Toolbar, Section, RowList/Row, SearchField, SegmentedControl, Toggle, Field, EmptyState/LoadingState/ErrorState, Badge, StatTile, ProportionBar, Sparkline, … | The same chrome as React components. Pointer: /primitives/react. |

Panel-chrome primitives

@xenosystem/components/chrome is the canonical answer to "how does the inside of a panel look" (@xenosystem/workbench/primitives is a deprecated pointer at that family since 1.2.0). Before it, the chrome contract had been independently reinvented three times across the ecosystem, and each of the five shipped canonical panels re-declared its own 100-line const S: Record<string, CSSProperties> bag.

What was lifted, from where:

| Source | What was taken | |---|---| | xeno-workflow index.css | The frame contract, class names byte-identical: xeno-panel / -header / -title / -content / -content--no-header, driven by --xeno-panel-gap / --xeno-panel-radius. Workflow can delete its local copy and import ours with zero markup churn. | | xeno-post ui/kit.tsx | The primitive vocabulary: Section, RowList/Row, Toolbar, StatTile, ProportionBar, EmptyState/LoadingState/ErrorState, StatusBadge, IconFrame — re-cut from dashboard density to in-panel density. | | xeno-comms XenoPanel | Confirmation of the frame shape (title + actions + content). No new ideas; it validated the other two. | | The five shipped panels | Every numeric value, by census. Where they agreed, the consensus value is used verbatim; where they disagreed, PANEL_METRICS annotates the alternatives. | | xeno-canvas | The actionable-hint empty state — a second line that says what the thing is and how to make one, not a restatement of the emptiness. |

Three gaps the primitives close. Across all five shipped panels the census found: no hover state anywhere, no focus-visible state anywhere (every input sets outline: none with no replacement), and no shared disabled treatment (eleven hand-written opacity pairs). Those now exist once.

Two structural guarantees, both test-enforced:

  • Every var() carries a literal fallback. A panel dropped into a product's own chrome with no workbench theme still renders correctly. The chain is --panel-* → --xeno-* → literal, which is what 4 of the 5 shipped panels already use.
  • No Dockview, no icon barrel. A panel must not pay for a docking library. Icons are ReactNode props; the three internal glyphs (SearchGlyph, ClearGlyph, ChevronGlyph) are <XenoElement> over per-id @xenosystem/elements declarations (components 0.37.2) — the lucide-react/dynamic packaged-build failure cannot recur. Chrome does import @xenosystem/elements-react for those glyphs; it does not import lucide.

PANEL_METRICS is the single source of truth for both the stylesheet and any JS that needs a measurement — the CSS is generated from it. That kills a whole bug class: a virtualizer computing scroll geometry from a JS row height while CSS sizes the row is a silent desync waiting to happen.

Deliberate divergences from DESIGN_SYSTEM.md

Flagged rather than hidden — both are dense-in-panel vs. app-chrome distinctions:

| Doc says | Panels do | Primitives ship | |---|---|---| | §3.1 compact controls are 24px | inspector/history/transport 18, layers 20 | controlHeightSm: 20 (default in toolbars) and controlHeight: 24 (§3.1-compliant, for panel bodies) | | §7 badges are 18px / 10px | inspector + history 12px / 8px (byte-identical) | badgeHeight: 12 (default) and badgeHeightMd: 18 (size="md") |

Adopting the primitives therefore never makes an existing panel denser than it already is.

Migration candidates (a LATER wave — nothing is refactored yet)

Ranked by how much hand-rolled chrome disappears:

  1. Inspector — the largest win and the lowest risk. Its styles.ts (280 LOC) is the only extracted style bag in the catalog and it is where the canonical Section (20px header, rgba(255,255,255,0.03) wash, enable toggle) and the Field label-column layout came from. It would delete sectionHeader/sectionTitle/sectionBody/fieldRow/search/chip/badge/ iconBtn/miniBtn/textBtn/empty/scroll.
  2. History — Row + Badge + SearchField + StatusBar + EmptyState map 1:1; its badge and search recipes are already byte-identical to the primitives'. Its xeno-history-spinner class, which no package currently defines, is covered by .xeno-spin / LoadingState.
  3. Layers — same shape as History, plus it is the one panel that would keep a local override (--xeno-row-h: 24px) rather than adopt the 22px default. Its drop-hint borders and thumbnail stay panel-local; everything around them is primitive.
  4. Transport — narrower: IconButton (its 20×18 filled button is the md size), SegmentedControl for the readout cycle, Badge for the chips. Its scrubber is irreducibly panel-local.
  5. Color — the odd one out on every axis (its own #e6e6e6/#141414 tokens, a different input family, letterSpacing: 0.4 unitless where everyone else uses em). Migrating it is as much a normalization as a refactor; do it last and expect visual deltas.

Two cross-cutting fixes belong to that wave, not this one: the two status reds (#ef4444 vs rgba(239,68,68,0.65) — PANEL_COLORS now spells both, error for indicators and errorText for text), and history's virtualizer fallback of 24 against its own default row height of 22 — a latent desync of exactly the kind PANEL_METRICS exists to prevent.

How it generalizes Motion

| Motion layoutStore / WorkspaceManager | @xenosystem/workbench | |---|---| | ALL_PANELS (hard-coded PanelDef[]) | any PanelRegistry of SDK panels | | PanelDef.defaultGroup | PanelManifest.defaultSlot | | buildDefaultLayout (Dockview placement) | DockviewDockAdapter slot→split/tab heuristic | | showPanel / hidePanel / togglePanel | WorkbenchController methods | | WORKSPACE_LAYOUTS presets | WorkspacePreset (host-supplied; no domain presets baked in) | | saveLayout / restoreLayout (localStorage, version-gated) | LayoutStorage seam (createWebLayoutStorage is version-gated) | | panelTitles overrides | controller.renamePanel | | zustand create store | framework-free controller + useWorkbenchState (useSyncExternalStore) |

Motion is not modified — it adopts this runtime later, at the product-adoption phase.

Scripts

npm run typecheck   # tsc --noEmit
npm test            # vitest run   (154 tests)
npm run build       # tsup → dist (esm + cjs + d.ts for '.', './react',
                    #              './primitives', './primitives/react')
                    #        + dist/theme.css and dist/primitives.css

See INTEGRATION.md and examples/ (a node-runnable headless composition).


© XENO Corporation — private. Panel-platform step 2 (spec §9).