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

design-folio

v0.2.0

Published

A design presentation system for vibe-coded prototypes

Readme

Design Folio

A design presentation system for vibe-coded prototypes. Bridges the gap between how designers build prototypes with Claude and how they share and present design work.

What it does

Folio wraps your prototype in a viewer with:

  • Prototype tab — your prototype at full size for testing interactions. No state picker, no design notes. Navigate using the links and UI in your prototype.
  • Screens tab — all your screens laid out for design review. Grid view (4-up with pan/zoom) and gallery view (single screen with design notes). This is where you examine design decisions.
  • Explorations tab — isolated UI elements being workshopped before incorporation into full screens. Compare alternatives side by side, mark winners, and link decisions to the screens where they appear. This is where the design process is made visible.
  • Changelog — Claude-summarized history of what changed and when.
  • Documents — links to Figma files, PRDs, research decks, design rationale docs, and other external context.

Setup

Folio is designed to be set up by the /folio Claude Code skill, which handles installation, configuration, and ongoing maintenance automatically. You shouldn't need to configure anything manually.

If you want to set it up manually:

npm install design-folio --save-dev

Add to your Vite config:

import { folioPlugin } from 'design-folio/vite';

export default defineConfig({
  plugins: [folioPlugin()],
});

Create a folio.json at your project root:

{
  "name": "Project Name",
  "designer": "Your Name",
  "description": "A short paragraph about the project.",
  "viewport": "desktop",
  "component": "./src/App.jsx",
  "states": [
    {
      "key": "home",
      "name": "1. Home",
      "group": "Main",
      "state": {},
      "notes": "Design rationale for this screen."
    }
  ]
}

Configuration

All fields in folio.json are optional. Folio works with zero config by defaulting to ./src/App.jsx with a desktop viewport.

| Field | Type | Default | Description | |-------|------|---------|-------------| | name | string | "" | Project name shown in the header | | designer | string | "" | Designer name shown in the header | | description | string | "" | Project description shown in the prototype tab sidebar | | viewport | string or object | "desktop" | "desktop", "wide-desktop", "tablet", "mobile", "responsive", or { width, height } | | component | string | "./src/App.jsx" | Path to the prototype component | | syncTheme | boolean | false | Pass Folio's light/dark theme to the prototype | | prototypeUrl | string | "/" | Base URL for the prototype. When set, Folio renders screens as iframes instead of using React cloneElement — enabling support for any prototype (vanilla JS, multi-page HTML, etc.) | | states | array | [] | Screen states with keys, names, groups, state objects, and notes | | explorations | array | [] | Design explorations with alternatives, winners, and screen links | | changelog | array | [] | Changelog entries grouped by date | | links | array | [] | External document links |

Viewport presets

| Preset | Dimensions | |--------|-----------| | desktop | 1080 × 720 | | wide-desktop | 1440 × 900 | | tablet | 768 × 1024 | | mobile | 375 × 812 | | responsive | 100% width, auto height |

State objects

Each state in the states array drives a screen in the Screens tab.

For React prototypes (no prototypeUrl), the state object is passed as an appState prop via React.cloneElement:

{
  "key": "home-empty",
  "name": "2. Empty State",
  "group": "Home",
  "state": { "items": [], "loading": false },
  "notes": "Shown before any data is loaded."
}

For iframe-based prototypes (with prototypeUrl), use url and/or script to reach each state:

{
  "key": "hierarchy-view",
  "name": "2. Hierarchy View",
  "group": "Map Views",
  "script": "document.getElementById('btnHierarchy').click()",
  "notes": "Org-chart mode showing reports-to relationships."
}

| State field | Type | Description | |-------------|------|-------------| | key | string | Unique identifier (used in URL hash) | | name | string | Display name shown in sidebar and screen title | | group | string | Section heading in the Screens grid | | state | object | Passed as appState prop to React prototypes | | url | string | Page URL for this screen, overrides prototypeUrl (e.g., "deal.html" for multi-page prototypes) | | script | string | JavaScript injected into the iframe after load to trigger the state | | scriptDelay | number | Milliseconds to wait after iframe load before injecting script (default: 100) | | notes | string | Design rationale shown in gallery view |

Explorations

Explorations let designers work on UI elements in isolation — trying different approaches to a search bar, a navigation pattern, a card layout — before incorporating the winner into full screens. Each exploration is a named design problem with multiple alternatives.

{
  "explorations": [
    {
      "key": "search-bar",
      "name": "Search Bar",
      "description": "Search paradigms for the dashboard header",
      "alternatives": [
        {
          "key": "full-width",
          "name": "Full-width Bar",
          "file": "./explorations/search-bar/full-width.html",
          "width": 540,
          "height": 80,
          "notes": "Always-visible search field. Most discoverable."
        }
      ],
      "chosen": "full-width",
      "rationale": "Tested best with non-technical stakeholders.",
      "usedIn": ["home-populated"]
    }
  ]
}

| Exploration field | Type | Description | |-------------------|------|-------------| | key | string | Unique identifier | | name | string | Display name (e.g., "Search Bar") | | description | string | The design question being answered | | alternatives | array | Each alternative has key, name, file (path to HTML), width, height, and notes | | chosen | string or null | Key of the winning alternative | | rationale | string or null | Why the winner was chosen | | usedIn | array | State keys from states where the winner appears in the prototype |

Alternatives can be any web-renderable content — HTML, React components, vanilla JS. Each file is standalone and rendered in an iframe. Dimensions set how large the element renders in comparison and focused views.

The Explorations tab shows two views:

  • Index — all explorations as a list, grouped by decision status (needs decision / decided), with a hero preview of the winner or first alternative
  • Detail — drill into one exploration to see alternatives in comparison mode (side by side) or focused mode (single element on a dot grid canvas with design notes)

Explorations link bidirectionally to screens: the exploration detail shows which screens use the winner, and the Screens gallery shows which exploration informed a screen's design.

Design documents

The /folio skill generates three standardized markdown documents alongside folio.json:

  • docs/design-rationale.md — overall design philosophy, principles, visual language
  • docs/decisions.md — decision log for every exploration: context, alternatives, outcome
  • docs/exploration-mapping.md — which exploration winners appear in which screens

These are linked in the Documents tab and kept updated as the design evolves.

How it works

Folio installs as a Vite plugin that serves your prototype component inside its viewer. Your prototype code is never modified — Folio wraps around it.

The /folio skill handles:

  • Detecting your prototype type and structure
  • Generating folio.json with states, explorations, notes, and changelog
  • Creating and maintaining design documents (rationale, decisions, mapping)
  • Pulling the project description from your README
  • Installing the Tailwind CSS dependency (required by the viewer)
  • Keeping the config updated as you continue vibe coding
  • Proactively asking for design rationale when it's missing

License

MIT