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

agent-wireframe-dsl

v0.1.3

Published

AI-friendly UI wireframe DSL with React renderer

Readme

agent-wireframe-dsl

A compact, JSON-based UI wireframe DSL designed for AI-assisted prototyping. Describe layouts and widgets in terse JSON; the React renderer turns them into a live visual preview instantly.

npm version license: MIT

Installation

npm install agent-wireframe-dsl
# or
pnpm add agent-wireframe-dsl

Peer dependencies — make sure these are already in your project:

npm install react react-dom zod

Usage

WireframeViewer — the simplest way

Drop WireframeViewer anywhere in your React tree and pass a DSL object (or anything — invalid input is shown as a friendly error list):

import { WireframeViewer } from 'agent-wireframe-dsl';

const dsl = {
  t: 'page',
  label: 'My App',
  children: [
    {
      t: 'card',
      children: [
        { t: 'text', label: 'Hello World', variant: 'primary' },
        { t: 'button', label: 'Click me', variant: 'primary' },
      ],
    },
  ],
};

export default function App() {
  return <WireframeViewer dsl={dsl} />;
}

renderToPng — export to PNG

Renders a DSL definition to a base64 PNG data URL. Useful for generating preview images, sharing wireframes, or saving them to disk.

Requires a browser environment — this function uses document and the DOM.

import { renderToPng } from 'agent-wireframe-dsl';

const dataUrl = await renderToPng(dsl);
// dataUrl: "data:image/png;base64,..."

// download it
const a = document.createElement('a');
a.href = dataUrl;
a.download = 'wireframe.png';
a.click();

Options:

await renderToPng(dsl, {
  width: 1440,          // rendered width in px (default: 1280)
  pixelRatio: 3,        // device pixel ratio / resolution (default: 2)
  backgroundColor: '#f0f0f0', // PNG background color (default: '#ffffff')
});

validateDsl + renderNode — lower-level control

import { validateDsl, renderNode } from 'agent-wireframe-dsl';

const result = validateDsl(rawJson);

if (!result.success) {
  console.error(result.errors); // string[]
} else {
  const element = renderNode(result.data); // ReactNode
}

Zod schema — extend or compose

import { dslNodeSchema } from 'agent-wireframe-dsl';

// Use as a building block inside your own Zod schema
const mySchema = z.object({
  version: z.string(),
  ui: dslNodeSchema,
});

Custom component registry — replace default components

Override the default components with custom ones (e.g., for theming or design system integration):

import { WireframeViewer, defaultRegistry, type ComponentRegistry, type DslNode } from 'agent-wireframe-dsl';

// Define a custom button component
function MyCustomButton({ node }: { node: DslNode }) {
  return (
    <button style={{ background: '#ec4899', color: 'white' }}>
      {node.label}
    </button>
  );
}

// Create a custom registry with the custom button
const customRegistry: ComponentRegistry = {
  ...defaultRegistry,
  button: MyCustomButton, // override just the button
  // all other components use defaults
};

// Use it with WireframeViewer
<WireframeViewer 
  dsl={myDsl} 
  registry={customRegistry}  // optional; uses defaults if omitted
/>

If no registry prop is provided, WireframeViewer uses defaultRegistry, ensuring backward compatibility.

API Reference

| Export | Kind | Description | |--------|------|-------------| | WireframeViewer | React component | Validates dsl: unknown and renders, or shows errors | | renderToPng | Async function | (dsl: unknown, opts?: RenderToPngOptions) => Promise<string> — renders to a PNG data URL | | RenderToPngOptions | Type | Options for renderToPng: width, backgroundColor, pixelRatio | | renderNode | Function | (node: DslNode, key?: number) => ReactNode — low-level renderer | | defaultRegistry | Object | Default component registry mapping all NodeTypes to components | | validateDsl | Function | (input: unknown) => ValidationResult \| ValidationError | | dslNodeSchema | Zod schema | Schema for a single DSL node (recursive) | | dslRootSchema | Zod schema | Alias for the root node schema | | ComponentRegistry | Type | Record<NodeType, React.ComponentType<{ node: DslNode }>> — custom component mapping | | ComponentRegistryContext | React context | Provides custom registry through render tree | | createRegistry | Function | (base: ComponentRegistry, overrides: Partial<ComponentRegistry>) => ComponentRegistry — merge registries | | DslNode | Type | TypeScript interface for any DSL node | | ValidationResult | Type | { success: true; data: DslNodeSchema } | | ValidationError | Type | { success: false; errors: string[] } | | NodeType, LayoutType, WidgetType | Types | Union literals for node t values | | VariantValue, SizeValue, WidthValue, GapValue, AlignValue | Types | Prop value unions | | DslNodeSchema | Type | Zod-inferred type for a validated DSL node |

DSL Reference

Every node requires exactly one field: t (the node type). All other fields are optional. Unknown keys are rejected at validation time.

Layout nodes

| t | Description | Key props | |-----|-------------|-----------| | page | Root page container | label, children | | section | Labelled section with vertical stack | label, gap, children | | row | Horizontal flex row | gap, align, children | | col | Vertical flex column | w, gap, children | | grid | CSS grid | cols, gap, children | | stack | Vertical stack with alignment | gap, align, children | | card | Rounded bordered card | label, children |

Widget nodes

| t | Description | Key props | |-----|-------------|-----------| | text | Paragraph or heading | label / value, size, variant | | button | Clickable button | label, variant, size | | input | Single-line text input | label, hint, value | | textarea | Multi-line text input | label, hint, value | | select | Dropdown selector | label, items | | checkbox | Checkbox | label | | radio | Radio group | label, items | | switch | Toggle switch | label | | tabs | Tab bar | items | | list | Bulleted list | label, items | | table | Data table | label, columns, rows | | avatar | Avatar circle (initials) | label, size | | image | Image placeholder | label | | badge | Pill badge | label / value, variant | | divider | Horizontal rule | — | | chart | Chart placeholder | label |

Shared props

| Prop | Type | Values | |------|------|--------| | variant | string | primary secondary danger success warning ghost outline | | size | string | xs sm md lg xl | | w | string | xs sm md lg xl full auto half | | gap | string | none xs sm md lg xl | | align | string | start center end stretch | | h | string | xs sm md lg xl | | cols | number | 1 – 12 | | span | number | 1 – 12 | | comment | string | Freeform annotation — ignored by the renderer |

Example — dashboard card

{
  "t": "page",
  "label": "Dashboard",
  "children": [
    {
      "t": "row",
      "gap": "md",
      "children": [
        {
          "t": "card",
          "label": "Users",
          "children": [
            { "t": "text", "label": "1,024", "size": "xl", "variant": "primary" },
            { "t": "text", "label": "Total registered users", "size": "sm" }
          ]
        },
        {
          "t": "card",
          "label": "Revenue",
          "children": [
            { "t": "text", "label": "$48,300", "size": "xl", "variant": "success" },
            { "t": "text", "label": "Month to date", "size": "sm" }
          ]
        }
      ]
    },
    {
      "t": "section",
      "label": "Recent Orders",
      "children": [
        {
          "t": "table",
          "columns": ["Order", "Customer", "Status", "Amount"],
          "rows": [
            ["#1001", "Alice", "Shipped", "$120"],
            ["#1002", "Bob",   "Pending", "$85"]
          ]
        }
      ]
    }
  ]
}

Design principles

  • AI-friendly — the terse t-keyed schema is easy for LLMs to generate reliably.
  • Validated at runtime — Zod strict-object schemas reject unknown keys immediately with clear error messages.
  • Inline styles only — no CSS framework dependency; the renderer works out of the box in any React environment.
  • ComposablevalidateDsl, renderNode, and the Zod schemas are all individually exportable so you can integrate at whatever level fits your app.

License

MIT