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

designmode

v0.12.0

Published

Edit live React apps with named styles, responsive previews, image fills, masks and comments. Hand changes to coding agents with component owners and source locations.

Readme

designmode.dev

Edit your running React app like a design file. Select layers, apply named styles, adjust layout and typography, tune solid, gradient and image fills, and leave comments with screenshots and layer references. Copy a precise change list for a teammate or send it to a coding agent, with component owners, source locations and before → after values.

Install · Named styles · Responsive previews · Agent setup

Press Shift+D (or ⌘E / Ctrl+E) to open designmode. If your browser reserves ⌘E, use Shift+D or click the bottom pill. Your edits preview on the page; designmode does not rewrite your source. Copy or Send saves the handoff in History and clears the preview so you can see the app's actual state. Discard is undoable too.

Right-click a layer on the canvas or in the layers tree to copy, paste, duplicate, comment, group, ungroup, mask, hide, lock, flip, or delete it. Right-click another layer to move the menu there; Shift+F10 opens it for the current selection. In the tree, ↑ selects the parent and ↓ selects the first child; on the canvas, Enter / Shift+Enter navigate child / parent, while arrows move or reorder. V selects, C comments, T adds text, and R / O draw a rectangle / ellipse. Existing D (Select) still works. Tab / Shift+Tab move between field values, skipping embedded token and sizing buttons; Alt+↓ cycles through those field actions. Find the reference under More → Keyboard shortcuts.

Fills, images, and layer masks

Select a text layer and use Fill to paint its glyphs. Select a frame, line, or shape to paint its box. Click the fill swatch to choose solid, gradient, or image paint; + adds another fill. Gradient stops and direction remain editable on the canvas.

Choosing Image immediately paints a checkerboard placeholder. Upload a file or drop it onto the preview or fill swatch; replacements retain the sizing and crop settings. Background and text image fills support Fill, Fit, Crop, and Tile. Native <img> elements use the same image picker for source replacement and Fill/Fit, preserving their browser layout and restoring responsive srcset/picture sources on undo or Discard. Files that cannot be decoded leave the current image intact and show an error.

Select sibling layers and choose Use as mask from the right-click menu. The bottom layer becomes the mask source; its shapes, text, images, and transparency reveal the selected content. Control+Command+M on Mac or Ctrl+Alt+M on Windows toggles the relationship. Right-click the mask source to choose Alpha mask or Luminance mask. The layers keep their DOM positions and responsive layout, remain individually editable, and can be restored through undo, Discard, or History. The handoff names the source and affected layers rather than exporting the generated preview image. Perspective sources and groups larger than 500 elements are not supported; images and fonts must be readable by the browser.

Named styles

Open the four-circle styles icon in a section header, beside + where available. Applying a style shows its name once, replacing the raw controls it owns. Click the chip to replace it, or detach it to expose its individual fields while keeping the current appearance. Detaching a border style preserves its separate color and width tokens; detach those fields individually to use raw values. Properties outside the style and existing local overrides remain visible. Empty sections stay compact.

Typography has one picker for text styles and font-family tokens. Full text styles combine related font properties with a size/line-height summary—for example, Large Title / Regular · 34/41. Font-family tokens change only the font, preserving size, weight and spacing. Detach to search or type a raw font family. Styles come from compound text classes, explicit typography objects in token JSON (including local aliases), and token families with the same path plus named font properties. Equal values alone never attach or merge styles; ambiguous families stay separate. Individual edits show Modified, and replacing or detaching a style is one undo step. Color and layout remain independent. CSS variables, relative units, unitless leading, and the original class/token names survive into the handoff. The JSON reader supports the common DTCG typography shape; it is not a full token-format validator.

Border, shadow, and gradient styles use the same choose, replace, modify, and detach controls. They read named CSS variables, relevant declarations from classes, and explicit composite tokens in JSON. Complete width/style/color token families also form border styles. Borders retain their active sides; shadow styles preserve separate focus rings; each gradient is edited within its own fill layer, keeping other paints and image positioning intact. A JSON gradient containing only color stops retains the page's direction and shape. Individual values stay editable, with style names and source locations included in the handoff. Replace, detach, and Discard are undoable.

Color libraries organize explicitly named roles—Text, Surface, Border, Accent, Icons, and named palettes—while preserving each token's identity and opacity. Tokens with the same rendered color remain separate when they have different roles, so a theme can change them independently.

Real responsive preview without Vite

The viewport must exist before the app starts. In a separate browser entry:

import { createViewport } from 'designmode/viewport'

if (!createViewport()) {
  await import('./app') // mounts your app and initializes designmode
}

The outer page becomes the editor shell; the same URL loads inside an iframe and mounts the app once. Changing width then updates CSS media queries, matchMedia, viewport units, resize events, and fixed/absolute positioning together. App state survives preview resizing. Keep app startup inside the dynamic import; do not mount it before calling createViewport(). Respect frame-blocking policies; this entry cannot be added to an already-running app without restarting it.

The Vite plugin already supplies this shell during development, so it needs no extra bootstrap. This entry also works in a built demo site when you explicitly include designmode there.

New in 0.12.0

  • Edit CSS grid as columns × rows: a grid well with column and row gap beside it, Grid settings for the counts (rows can stay Auto), and drag-reorder of grid children. Hand-sized tracks are reported, not rewritten.
  • Type any unit into a number field — 50%, 2rem, calc(100% - 8px) — and it is written as typed when the property accepts it; an invalid value flashes instead of disappearing.
  • A handoff never goes silent: a blocked clipboard still writes the request file and says so, failure toasts stay clickable above the panels, Restore reports when the layers are gone, and every bridge call times out instead of spinning.
  • Every control does what its label says: Escape reverts in-place text edits, ⌘X/⌘V round-trips a layer, Delete on a ::before clears the pseudo, tiny layers move instead of collapsing, masks clip one layer, comments undo, Delete and zoom keys work from the layers tree, and one ⌘Z undoes one drag. Full list in docs/audit-2026-09-16.md.

Previously in 0.11.0

  • Apply grouped typography, border, shadow, and gradient styles from existing tokens and classes, with independent overrides, detach, undo, and History recovery.
  • Organize color tokens by role while preserving aliases, opacity, and source identity.
  • Paint text with solid, gradient, and image fills. Upload or drop replacement images, keep crop settings, and recover responsive image sources through undo and Discard.
  • Use sibling layers as alpha or luminance masks, with editable sources and a handoff that describes the masking relationship.
  • Use the before-app designmode/viewport entry for native responsive previews outside Vite, with compact controls on mobile widths.
  • Open with Shift+D when a browser reserves ⌘E; use layer context menus, familiar tool shortcuts, and keyboard navigation. Ungroup existing page containers while preserving their content.
  • Use consistent inspector dropdowns with arrow-key navigation, typing to find options, and menus that fit mobile views. Tab between fields, search font families, and select layers beneath inert overlays.
  • Test on the new Orbit playground at /stress: animated content, dark and light surfaces, image fills, design tokens, and responsive layouts.

Previously in 0.10.0

  • Preview native responsive layouts in the same tab with the Vite integration: CSS and JavaScript breakpoints, viewport units, and positioned elements follow the selected width.
  • Keep app state and editor undo history while resizing, with controls outside the app viewport.
  • Restore group membership, sibling order, wrapper edits, image attributes, and original style priorities correctly through Discard and undo.
  • Verify editor behavior with a Chromium, Firefox, and WebKit regression matrix.

Previously in 0.9.0

  • Add and edit min/max width and height on freeform layers, without enabling Auto Layout.
  • Select and edit ::before, ::after and list markers from the layers tree.
  • Reach elements inside dialogs and popovers, decorative overlays with pointer-events: none, and display: contents wrappers.
  • Inspect rotated layers with outlines that follow their corners, read CSS dimensions under scaling, and reorder RTL flex rows in their visual direction.
  • Export a component owner stack with source paths, with asynchronous source-map resolution for React 19.
  • Step numeric fields with ↑/↓, Shift for larger steps and Alt for finer adjustments where supported.

Why

Designers can see exactly what's wrong with a shipped UI but can't express it in a way that survives handoff. "Make the gap bigger and the card less round" becomes a Slack thread. designmode.dev turns direct manipulation into an unambiguous diff:

<div class="card">…</div> in PricingCard (at /project/src/components/PricingCard.tsx:24:9) in Pricing (at /project/src/sections/Pricing.tsx:40:7) in App (at /project/src/App.tsx:12:5)
selector: section.pricing > div.card
- border-radius: 16px → 10px
- gap: 12px → 20px

On page /, <button class="cta">Get started</button> in Hero (at /project/src/sections/Hero.tsx:9:5) (header.hero > button.cta) has this comment: "should feel heavier" — make the change it describes.

An AI agent (or a human) can apply that against the real codebase, using the project's existing styling approach.

Install

One script tag — drop it in your dev index.html and press Shift+D:

<script src="https://unpkg.com/designmode"></script>

Or via npm:

npm i -D designmode
import 'designmode/auto'   // initializes on load — or: import { init } from 'designmode'; init()

Requirements: React 18+ running a development build (source locations are dev-only — see Limitations).

Close the loop with an agent (optional)

Instead of pasting the prompt yourself, let your agent pull it. Add the dev bridge to your Vite config and register the MCP server with your agent:

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import designmode from 'designmode/vite'

export default defineConfig({
  plugins: [react(), designmode()],
})

Register the MCP server in the agent you use:

# Codex
codex mcp add designmode -- npx -y --package=designmode designmode-mcp

# Claude Code
claude mcp add designmode -- npx -y --package=designmode designmode-mcp

Then tell that agent:

Watch designmode and apply my design changes as they arrive

When an agent is watching, Send to agent hands over the change list and shows live progress. The copy icon beside it gives you the same prompt for another tool or a teammate. With the Vite bridge but nobody watching, Copy copies the prompt and leaves the request in the project's .designmode/requests/ inbox for later pickup.

Copy and Send save an entry in History and clear the live preview. Open History from the three-dots menu to copy a prompt again, restore supported pending edits, or copy a revert prompt after the agent reports completion. History survives reloads within the current tab's session. An agent reporting completion does not prove the source change is correct: inspect the resulting page.

The bridge also scans your project for design tokens and saves images attached to comments or fills under .designmode/, giving your agent a file path it can open. Keep the overlay and bridge in development only. Other setups can use the clipboard or implement the same HTTP endpoints.

Hacking on it

npm install
npm run dev -- --port 5175  # demo; /stress is the Orbit playground; /dls shows panel primitives
npm test           # typecheck, rebuild, then run all Playwright suites
npm run test:cross-browser # system contracts in Chromium, Firefox and WebKit

Install the browser engines with npx playwright install chromium firefox webkit before the cross-browser run. Open /stress and its Test guide for a hands-on editing checklist. See the system audit for coverage and known integration limits.

What you can do

| | | |---|---| | Select | Click; ⌘/Ctrl+drag for marquee; Esc deselects | | Move | Drag (flex children reorder live; ⌥+drag forces free move) | | Resize / rotate | Handles; corner-outside zones rotate; Shift snaps 15° | | Nudge / reorder | Arrow keys move freeform layers; on the flex main axis they reorder siblings. Shift = 10px for nudges | | Group | Shift+A wraps selection in an auto-layout container; ⌘⇧G ungroups editor groups or existing page containers, preserving their children and loose text | | Masks | Select sibling layers and choose Use as mask; choose alpha or luminance from the mask source's context menu; undo, Discard, and History restore the relationship | | Images | Upload or drop images onto a fill preview or swatch; replace native image sources; retain crop settings and restore responsive sources on undo | | Delete | Delete/Backspace | | Tools | V / D select, B browse, C comment, T text, R rectangle, O ellipse, M minimize. Shift+D opens or tucks away the editor | | Comments | Paste, drop or pick an image ("make it look like this" — saved under .designmode/, exported as a path), and @mention layers inline via the composer's inspect button; each mention resolves to component + file:line | | Panel | Design controls: Position, Auto layout, Appearance, Typography, Fill, Stroke, Effects | | States and pseudo elements | Edit :hover, :focus, :active and :disabled styles; select existing ::before, ::after and ::marker layers | | Sizing | Fixed / Hug / Fill where the layout supports them, plus min/max width and height on freeform layers | | Zoom | + / - to zoom, 0 to reset, and Space+drag to pan | | Tokens | Read from your source through the dev bridge — CSS custom properties, Sass/Less variables and token JSON, with the authored name and the file:line that defines it — merged with runtime resolution (oklch palettes, shadcn channel triples, clamp()/calc()) for the swatch. Grouped and searchable by name or value; framework internals (--tw-*) never offered | | Named styles | Typography, borders, shadows, and gradients combine related values into one replaceable style. Individual overrides show Modified; detach, undo, and History restore preserve the handoff's source identity | | Responsive preview | Native CSS and JavaScript breakpoints through the Vite shell or designmode/viewport; compact inspector controls at narrow widths | | Utility classes | In a Tailwind-style codebase the class is the token: the field shows bg-bg-secondary, and clicking it offers the other classes your project ships. Each field is independent: replacing or detaching one property preserves the class-backed values shown by sibling fields | | Pause | Freeze the page's motion (CSS animations, transitions, Web Animations, video) to inspect one frame of it — a view state, not an edit | | Reset | Revert one element's changes in a single step, without touching the rest | | Layers | Left tree with component chips at fiber boundaries; double-click to rename; right-click for actions; ↑ / ↓ select parent / child | | MCP | A row in the three-dots menu: the status dot, the state in a word, and a copy icon for the setup command or the watch sentence. The dot also rides the dots button as a badge |

The panel includes drag-to-scrub on labels, math expressions (300+50), "Mixed" on multi-select, searchable font families, and a full custom color picker with solid/gradient/image fills. Tab moves between inspector value fields, skipping the token action icons inside them.

How it works

  • bippy maps DOM elements to React fibers; owner stacks identify the components that wrote the JSX, and source maps resolve compiled locations where available.
  • The editor UI is isolated in shadow DOM. With the viewport shell, the app and canvas overlay run inside the frame while the panel lives in the parent document; both share one editor store. Standalone use keeps them in one document.
  • The panel is Preact + htm (not React) — it must not interfere with the host app's React tree, and htm avoids needing JSX compilation for the library.
  • Selection handles and guides are drawn on a <canvas> in a requestAnimationFrame loop; a transparent interaction layer captures pointer events only while design mode is active.
  • Edits are recorded per element as { prop, original, value } overrides in a central store (src/lib/store.ts), applied as inline styles, fully revertible via Discard.

Project structure

src/
  lib/                  the library (published surface)
    index.ts            init(): shadow-DOM host and event wiring
    auto.ts             script-tag entry (init on load)
    store.ts            central state: selection, edits, transforms, groups, comments
    inspector.ts        DOM element → component name + source file:line (via bippy)
    export.ts           allItems()/buildPrompt(): edits → AI-ready markdown
    bridge.ts           client of the dev bridge: handoff, image upload, status polling
    check.ts            handoff snapshots, History restore and revert prompts
    tokens.ts           token detection: runtime cascade + merge with source scan
    typography.ts       named typography styles and property bindings
    paint-styles.ts     border, shadow, and gradient style discovery
    layer-masks.ts      alpha/luminance previews from editable sibling layers
    viewport-shell.ts   before-app entry for native responsive previews
    utilities.ts        which utility class governs a property, and its group
    overlay/            canvas rendering, pointer interaction, geometry
    panel/              Preact panel: sections, inputs, color picker, styles
  scan-tokens.ts        source scanner: CSS/Sass/Less/JSON tokens with file:line
  vite.ts               dev-server bridge: handoff, tokens, images
  mcp.ts                MCP server (designmode-mcp bin) — agents pull/resolve changes
  demo/                 Vite demo app used for development

Limitations

  • Responsive canvas: with designmode/vite, the app runs once inside a real resizable iframe. The width controls drive native media queries, matchMedia, viewport units and resize events without reloading the app. Editor controls stay outside the frame. Widths larger than the available canvas can be scrolled horizontally. Other integrations can use the before-app designmode/viewport entry above. Standalone/script-tag use without either shell retains the older CSS-only approximation; it cannot change JavaScript viewport reads or viewport units. Apps that must run at the top level can opt out with designmode({ viewport: false }). Frame-blocking policies remain respected.
  • Dev builds only for source locations. React 18 provides fiber._debugSource; React 19 uses debug stacks and asynchronous source-map resolution. Missing maps or framework debug data can limit attribution; Server Component mapping has not yet been verified against a real Next.js app. On production builds everything still works except file:line attribution.
  • Live previews do not survive a reload or author responsive media queries. Handoff prompts remain in the current tab's History.
  • Pseudo-element bounds are approximate; perspective transforms and transformed modal dialogs have geometry limitations.
  • Which token is in effect on an element is read from the cascade, so same-origin stylesheets only (CORS). Which tokens exist comes from the source scan and is unaffected — without the Vite plugin, only the runtime half is available. __DESIGN_MODE__.audit(el) reports, per property, whether a missing token is a literal, framework plumbing, an unreadable sheet, or a real miss.
  • Keyboard and pointer editing are the primary workflow. Narrow viewport previews have compact controls; touch-only editing has not been comprehensively verified.

Contributing

See CONTRIBUTING.md. The short version: npm run dev, keep interactions clear and predictable, keep diffs small, and run npm run typecheck before pushing. CLAUDE.md documents the architecture invariants and known traps — read it even if you're not using Claude.

License

Proprietary — all rights reserved. See LICENSE. Not open source; no permission is granted to use, copy, or distribute this code.