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

@react-x11/workbench

v0.2.0

Published

The component workshop for react-x11: develop, test and compare components in isolation

Readme

@react-x11/workbench

A component workshop for react-x11: develop, test and compare components in isolation.

It solves the problem Storybook solves, for a toolkit that has no browser to put an iframe in. It is not a port of Storybook — no addon platform, no manager/preview split, no MDX. Just the jobs: mount one component on its own, see every variant at once, tweak its props while it runs, and compare two of them side by side.

Status: M1. The story contract, discovery, x11-workbench ls and the workshop GUI are implemented and tested. Hot reload with state preserved, a richer knobs panel and the component inspector are M2; headless screenshot capture and visual diffing are M3. The design, including what is deliberately not here, is in docs/prd-workbench.md.

A story

A story is a component rendered inside another react-x11 component — the way your library's component renders inside somebody's app. A file's named exports are its stories; its default export is the file's metadata — unless it is a component, in which case it is the file's story:

// src/badge.tsx — a component module, no story file, nothing imported
export default function Badge() {
  return <text>Ready</text>;
}

Point the globs at your source (stories: ['src/**/*.tsx']) and every such module is in the sidebar, labelled with the component's own name. There are no knobs until there are args — the rungs below add those.

// stories/card.story.tsx
import { story } from '@react-x11/workbench/story';
import { Card } from '../src/card.js';

export default { title: 'Card' };

// The simplest thing that works: a component export.
export const basic = () => <Card title="Space Helmet X24" />;

// Say more when you need more — never on a second API.
export const product = story(
  (args: { title: string; outOfStock: boolean; padding: number }) => (
    <Card {...args} />
  ),
  {
    args: { title: 'Space Helmet X24', outOfStock: false, padding: 12 },
    controls: { padding: { type: 'number', min: 0, max: 40 } },
  },
);

Ceremony is additive: every capability is an independent opt-in on the story you already wrote, and the file stays a plain module you can run yourself.

Install

npm i -D @react-x11/workbench

react-x11 and react are peer dependencies. Optionally add a config — without one, every **/*.story.tsx is discovered:

// workbench.config.ts
export default {
  stories: ['stories/**/*.story.tsx'],
};

Story files are compiled by tsx, which reads your tsconfig.json — so it needs the react-x11 JSX runtime, the same setting that compiles the components themselves:

{ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "react-x11" } }

Without it, JSX compiles to React.createElement and every story fails to render with ReferenceError: React is not defined.

Use

x11-workbench dev      # the workshop (needs a running X server)
x11-workbench ls       # what was discovered; --json for the model

The workshop

  • Select a story — it mounts on a canvas, in a frame the size of the component itself.
  • Select a file — every story in it at once, as a labelled grid. Both themes doubles the grid, light beside dark.
  • Pin — holds the current story in one pane while the sidebar drives the other. The pinned pane owns its own theme, so pinning a story and flipping it is how you compare one component against itself.
  • Controls — a story with args gets a panel: text, number (a slider when bounded), switch, options. Edits apply to the running story without remounting it, so its state survives your tweaking, and they persist while you look at something else. Reset drops them.
  • Editing a story file re-discovers and remounts it.

A story that throws is contained: the failure gets a panel with its stack, and the rest of the workshop keeps working. So does a story file that throws while being imported.

Story reference

export default {
  title?: string,        // sidebar label; default: the file's basename
  size?, theme?, direction?,   // defaults for every story in the file
}

story(render, {
  name?: string,         // display name; default: the export name
  size?: { width, height },    // the room the story gets
  theme?: 'light' | 'dark' | 'both',
  direction?: 'ltr' | 'rtl' | 'both',
  args?: object,         // initial props — this alone gives you controls
  controls?: {           // say more than the arg's type does
    [key]: 'text' | 'number' | 'boolean'
         | readonly (string | number)[]              // options
         | { type: 'number', min?, max?, step? },    // slider when bounded
  },
  play?, capture?,       // reserved for M2/M3; ignored today
})

Controls are inferred from args when you do not declare them: a string is a text field, a number a number, a boolean a switch.

Subpaths

| Import | What it is | | -------------------------------- | -------------------------------------------------------------------- | | @react-x11/workbench/story | The contract. Zero dependencies — adopt the format without the tool. | | @react-x11/workbench/discovery | Globs and module loading to the story model. Node-facing. | | x11-workbench | The bin: dev, ls. |

Development

npm test              # headless: no display, no xvfb
npm run typecheck
npm run shot -- out.png --select product    # screenshot any view

The whole suite — the workshop's own UI included — renders against node-x11's pure-JavaScript X server in process, via react-x11/test. The same path takes screenshots, which is how this repo does design review; see AGENTS.md.

The workbench previews its own error and controls panels (stories/workbench-ui.story.tsx), which is both a demo and how those surfaces get reviewed.

Licence

MIT