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

classicy

v2.1.5

Published

A UI framework in React, replicating the user interface of Classic MacOS 8 (called Platinum).

Readme

Classicy

Previously Platinum

A UI framework using native CSS/JS replications of the Mac OS 8 interface components.

Just curious? Visit our website to learn more.

Demo

See a demo here!

UI Components

See our Storybook collection here!

Building and running on localhost

This project uses pnpm (enable it with corepack enable). First install dependencies:

pnpm install

To create a production build:

pnpm build

To create a development build:

pnpm dev

Running

To run the example site locally (builds the package and starts the example dev server):

pnpm preview

Then visit the site in your browser at http://localhost:3000.

(For iterative package development you can also use pnpm dev, which builds the source. The example/ app consumes it directly through the pnpm workspace — no linking step required.)

Browser app — TimeMachine Proxy

The Browser app requires the TimeMachine Web Proxy to fetch archived web pages. A Docker Compose setup is included in example/timemachine/:

cd example/timemachine
cp .env.example .env   # adjust if needed
docker compose up -d

The proxy runs on http://localhost:8765 by default. Enable it in the Browser app under File → Settings → Enable TimeMachine Proxy.

Acknowledgements

  • New Dawn by Nathanael Gentry
  • Scrollbars of the Classic Mac OS by Jessica Stokes (@ticky)
  • after-dark-css, for the basic System 7.1.1 interface
  • flyer, for further inspiration
  • Robin Casady, for releasing ChicagoFLF into the public domain
  • Apple, who maintains the copyright on the background patterns, icons and interface components

Features

Legend

| | | | |:--------:|:-------------------:|:-------------------:| | ✅ | ℹ️ | ⚠️ | | Complete | Partially complete. | Experimental | | | | Subject to change |

  • Desktop
    • ✅ The ubiquitous Finder
    • Menubar
      • ✅ System Menu
      • ✅ App Switcher
      • ✅ Widgets
        • ✅ Date/Time
        • ✅ Sound
    • Icons
      • ✅ App Shortcuts
      • ✅ Cleanup
      • Arrange By…
  • Sounds
    • ✅ Sound Provider
    • ✅ Load sound theme from JSON
    • ✅ Audio Sprites support
    • ✅ Sound Manager Control Panel
      • ✅ Sound Event Handler
        • ✅ Event dispatcher/player
        • ✅ Automatic event intercept and play for known events (map audio sprites to events)
  • Logging & Diagnostics
    • ✅ registerClassicyLogSink — host apps receive Classicy logs, errors, and crash reports (production builds included)
  • Screen Saver
    • ✅ Idle-activated full-screen screensavers (After Dark CSS ports: Flying Toasters, Fish, Warp, and 9 more)
    • ✅ Screen Saver Control Panel (pick saver, timeout, per-saver options)
    • ✅ registerClassicyScreenSaver API with custom or schema-derived options UI
  • Appearance Manager Control Panel (Theme Manager)
    • ✅ Appearance Manager Control Panel
    • ✅ System
      • ✅ Load theme from JSON
      • ✅ System events for modifying theme
    • UI
      • ✅ Typography settings
      • ✅ Measurement settings
      • ✅ Desktop settings
      • ✅ System colors
      • ✅ Configurable color variables
    • ✅ Color Theme-able components
  • App Template
    • ✅ App Context/Event Handler
    • ✅ App Switcher
  • Window
    • Controls
      • ✅ Zoom
      • ✅ Resize
      • ✅ Collapse
      • ✅ Close
      • ✅ Placard
      • ✅ Header
    • Dialog
      • Modal
        • Dialog
          • ✅ Movable
          • ✅ Non-movable
        • Alert
          • ✅ Movable
          • ✅ Non-movable
      • ✅ Modeless
    • ✅ Standard
  • System
    • ✅ File System
      • ✅ Integrated into Finder.app
  • UI Components
    • ✅ Text Input
    • ✅ Text Area
    • ✅ Button
    • ✅ Tabs
    • ✅ Radio Button
    • ✅ Drop-down menu
    • ✅ Drop-down menu groups (optgroup)
    • ✅ Form (dialog layout, safe submit)
    • ✅ Multi-select menu (List Box)
    • ✅ Combo box (autocomplete)
    • ✅ Table (Platinum list view)
    • ✅ Checkbox
    • ✅ Bevel Button
    • ✅ Slider
    • ✅ Spinner
    • ✅ Date Picker
    • ✅ Time Picker
    • ✅ Expandable (Disclosure)
    • ✅ Fieldset
    • ✅ Separator
    • ✅ Progress
    • ✅ Balloon Help (tooltip)
    • ✅ Link (desktop-routed hyperlink)
    • ✅ Meter (gauge with zones)
    • ✅ Output (read-only result)
    • ✅ Keyboard shortcut display (kbd)
    • ✅ Menu
      • ✅ Desktop Menu
      • ✅ Contextual Menu
      • ✅ Submenu
    • Gallery Picker (Slider)
    • ✅ Color Picker

Component Reference

All components are exported from the classicy package. Import them by name:

import { ClassicyWindow, ClassicyButton, ClassicyBalloonHelp } from 'classicy';

Building an app? docs/BUILDING-APPS.md is the step-by-step guide: ClassicyApp and ClassicyWindow prop-by-prop, manifests, reducers, menus, icons, files, dialogs, balloon help, sound, analytics, extensions, persistence, and testing — plus the traps that cost the most time. It ships with the package at node_modules/classicy/docs/BUILDING-APPS.md.

Using an AI coding agent? A complete machine-oriented reference to the public API — every component's props, app/event/icon registration, theming, analytics, sound, and the untrusted-action rules — ships with the package at docs/AGENT-REFERENCE.md (node_modules/classicy/docs/AGENT-REFERENCE.md). Point your agent at it.

Each table below lists the raw HTML element the component replaces — inside a Classicy desktop, prefer the component over the raw tag (e.g. ClassicyButton instead of <button>) to get theming, sounds, and balloon help for free. The full two-way map, including HTML elements that have no Classicy equivalent, is in docs/AGENT-REFERENCE.md §4.0.

Application Shell

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | ClassicyDesktop | Root desktop surface — icons, menu bar, wallpaper, drag-select | — (desktop metaphor) | | ClassicyDesktopMenuBar | Top menu bar with system menu, app menu, and widget tray | <nav> | | ClassicyApp | Application container. Props: id, name, icon, defaultWindow | — | | ClassicyWindow | Window chrome with title bar and controls. Props: id, appId, title, closable, zoomable, collapsable, resizable, modal, initialSize, initialPosition, minimumSize | <dialog> (non-modal; modal prop for modal) | | ClassicyBoot | Boot screen shown on first load | — | | ClassicyScreenSaver | Idle-activated screensaver extension (auto-mounted by ClassicyDesktop); register your own savers with registerClassicyScreenSaver | — | | ClassicyAboutWindow | Standard "About This App" dialog. Props: appId, appName, appIcon | <dialog> |

Inputs

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | ClassicyButton | Push button. Accepts children as label | <button> | | ClassicyCheckbox | Checkbox with optional label. Props: checked, label, onChangeFunc | <input type="checkbox"> | | ClassicyRadioInput | Radio button group. Props: label, options (array of { label, value }) | <input type="radio"> group | | ClassicyInput | Single-line text field. Props: placeholder, value, onChangeFunc | <input type="text"> (any text-like type) | | ClassicySpinner | Numeric stepper (up/down arrows). Props: value, min, max, step | <input type="number"> | | ClassicyPopUpMenu | Drop-down selector. Props: label, options ({ label, value } items or { groupLabel, options } groups), value | <select> / <option> / <optgroup> | | ClassicyListBox | Scrolling list with single or multi selection (⌘-toggle, Shift-range). Props: options, selectionMode, selected, onChangeFunc, visibleRows | <select multiple> | | ClassicyComboBox | Editable field with filtering suggestions and a pop-up arrow. Props: options, filter, freeText, onSelectFunc | <datalist> | | ClassicyDatePicker | Date input with calendar picker. Props: value, placeholder, onChangeFunc | <input type="date"> | | ClassicyTimePicker | Time input with clock picker. Props: value, placeholder, onChangeFunc | <input type="time"> |

Text Editing

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | ClassicyTextEditor | Plain-text editor area. Props: content, onChangeFunc | <textarea> | | ClassicyRichTextEditor | Rich-text editor (bold, italic, lists). Props: content, onChangeFunc | contenteditable region |

Layout & Structure

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | ClassicyTabs | Tabbed container. Children must be ClassicyTab items with a title prop | — (ARIA role="tablist" pattern) | | ClassicyDisclosure | Collapsible section (expand/collapse). Props: label, open | <details> / <summary> | | ClassicyControlGroup | Labeled fieldset grouping form controls. Props: label | <fieldset> / <legend> | | ClassicyControlLabel | Inline label for a control. Props: label | <label> | | ClassicySplitView | Resizable two- or three-pane container with a draggable, keyboard-accessible divider. Props: direction, defaultSizes, minPaneSize, onResize, onResizeCommit | — (nearest: obsolete <frameset>) | | ClassicyForm | Form wrapper with HIG row/dialog spacing; submit never navigates. Props: onSubmitFunc, layout. Pair with ClassicyFormButtonRow for the Cancel/OK row | <form> | | ClassicyTable | Platinum list view over arbitrary data: sortable/resizable columns, Mac row selection, keyboard navigation. Props: columns, rows, getRowId, selectionMode, onActivateRow | <table> |

Menus

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | ClassicyMenu | Drop-down menu used in the menu bar. Props: id, title, menuChildren | <menu> | | ClassicyContextualMenu | Right-click context menu. Renders at pointer position | <menu> (the old contextmenu attribute) |

Feedback & Display

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | ClassicyProgressBar | Determinate progress bar. Props: value, max, label | <progress> | | ClassicyMeter | Gauge with native meter zone semantics (theme accent / alert / error). Props: value, low, high, optimum, segments | <meter> | | ClassicyOutput | Read-only calculation result — static text or inset well. Props: value, htmlFor, variant | <output> | | ClassicyKbd | Keyboard shortcut display in Platinum glyph order (⇧⌘S), inline or as key caps. Props: shortcut, variant | <kbd> | | ClassicyLink | Themed hyperlink routed through the desktop URL opener (WebViewer, browser, or new tab). Props: href, disposition, event | <a> | | ClassicyBalloonHelp | Mac OS 8-style speech-bubble tooltip. Wraps any element. Props: content, title, position, delay | title attribute (tooltip) | | ClassicyIcon | System icon image with optional label. Props: src, label | <img> + caption |

File System

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | ClassicyFileBrowser | File browser with icon and list views. Props: path, onSelect | — |

Media

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | QuickTimeMovieEmbed | Embedded QuickTime-style video player. Props: url | <video> / <audio> |

Menu Bar Widgets

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | ClassicyDesktopMenuWidgetTime | Clock widget for the menu bar | — | | ClassicyDesktopMenuWidgetSound | Deprecated. Mute toggle for the menu bar, no longer mounted by default. Use the Control Strip's built-in Sound module instead (classicy-sound; turn it off with ClassicyDesktop's controlStrip={{ disabledModules }}). Still exported; logs a one-time dev warning when mounted | — |

Control Strip

| Component | Description | HTML equivalent | |-----------|-------------|-----------------| | ClassicyControlStrip | Mac OS 8 Control Strip at the desktop's lower left, showing every registered module — the built-in Sound and Screen Saver modules plus any an app or extension registers. Mounted by ClassicyDesktop; configure with its controlStrip prop (disabledModules, defaultCollapsed, defaultWidth), or pass false to hide it. Its collapsed state, width, and the user's module choices persist | role="toolbar" | | registerClassicyControlStripModule | Adds a module (id, label, 16 px icon, menuItems or content, optional owning appId and order). Call at module scope; the strip updates live. Each module is also listed in System Folder:Control Strip Modules | — | | ClassicyControlStripManager | The Control Strip control panel: show or hide the strip, and show, hide or reorder its modules | — | | ClassicyPopUpSlider | Compact vertical slider for a pop-up bevel button (the Control Strip volume slider). Props: value, onChange, ariaLabel | <input type="range"> |


Architecture

Component Organization

  • <ClassicyAppManagerProvider>
    • <ClassicyDesktop>
      • <ClassicyDesktopMenuBar>
      • <ClassicyDesktopIcon?>
      • <YourClassicyApp>
        • <ClassicyApp>
          • <ClassicyWindow?>
            • <ClassicyUIControls?>
            • <OtherReactNodes?>

ClassicyDesktop must be imported eagerly. Mounting it lazily, a tick after ClassicyAppManagerProvider, corrupts manager state: early dispatches reach a reducer whose state the desktop has not seeded yet, and every dispatch after that throws.

Writing an app? Start with docs/BUILDING-APPS.md — a step-by-step guide covering ClassicyApp, ClassicyWindow, manifests, reducers, menus, files, dialogs, sound, analytics, persistence, and testing.

Seeding default state

ClassicyAppManagerProvider accepts an optional defaultState — a deep-partial ClassicyStore merged over the built-in defaults on first load only (when no saved state exists in localStorage). Returning visitors keep their persisted state.

<ClassicyAppManagerProvider
  defaultState={{
    System: { Manager: { DateAndTime: {
      dateTime: "2001-09-11T12:40:00.000Z", // 8:40 AM US Eastern (EDT, UTC-4)
      timeZoneOffset: "-4",
    } } },
  }}
>
  {/* ... */}
</ClassicyAppManagerProvider>

Arrays in defaultState replace their default counterparts wholesale (they are not concatenated). To force a value on every load regardless of saved state, clear localStorage["classicyDesktopState"] or dispatch the change at runtime.

Seeding the default filesystem

ClassicyAppManagerProvider accepts optional defaultFileSystem and defaultFileSystemMode props to seed the virtual filesystem used by Finder and other file-aware apps on first load only (when no saved filesystem exists in localStorage["classicyStorage"]). Returning visitors keep their persisted filesystem.

<ClassicyAppManagerProvider
  defaultFileSystem={{
    "Macintosh HD": {
      _type: "drive",
      _icon: ClassicyIcons.system.drives.disk,
      Documents: {
        _type: "directory",
        _icon: ClassicyIcons.system.folders.directory,
        "My Document.txt": {
          _type: "text_file",
          _mimeType: "text/plain",
          _data: "Hello, Classicy!",
        },
      },
    },
  }}
  defaultFileSystemMode="merge"
>
  {/* ... */}
</ClassicyAppManagerProvider>

defaultFileSystemMode controls how the filesystem is constructed:

  • "merge" (default) deep-merges your tree onto the library's DefaultFSContent
  • "exclusive" uses your tree as the entire filesystem, ignoring DefaultFSContent

Like defaultState, filesystem trees are seed-only. To force a filesystem value on every load regardless of saved state, clear localStorage["classicyStorage"] or rebuild the filesystem at runtime.

To correct a returning visitor's already-persisted tree — renaming a seeded file, fixing a bad URL — pass defaultFileSystemSeedMigrations, a list of one-time corrections applied against stored state (see ClassicyFileSystemSeedMigrations.ts).

Default apps

ClassicyDesktop automatically mounts six built-in apps — SimpleText, PDFViewer, MoviePlayer, PictureViewer, HyperCard, and WebViewer — the same way it always mounts Finder. Each can be disabled individually via a prop on ClassicyAppManagerProvider:

<ClassicyAppManagerProvider
  disableSimpleText={false}    // default: false (loads)
  disablePDFViewer={false}     // default: false (loads)
  disableMoviePlayer={true}    // opt out of Movie Player
  disablePictureViewer={true}  // opt out of Picture Viewer
  disableHyperCard={true}      // opt out of HyperCard
  disableWebViewer={true}      // opt out of Web Viewer
>
  <ClassicyDesktop />
</ClassicyAppManagerProvider>

Disabling an app only stops it from auto-mounting — it remains available to import and render yourself (e.g. import { PDFViewer } from "classicy") if you want custom placement.

Events

  • ClassicyDesktop

    • ClassicyDesktopClick
    • ClassicyDesktopDrag
    • ClassicyDesktopSetBalloonHelp
  • ClassicySoundPlay

    • ClassicyAlertSosumi
    • ClassicyAlertWildEep
    • ClassicyAlertIndigo
    • ClassicyBeep
    • ClassicyBoot
    • ClassicyButtonClickDown
    • ClassicyButtonClickUp
    • ClassicyInputRadioClickDown
    • ClassicyInputRadioClickUp
    • ClassicyMenuClose
    • ClassicyMenuItemClick
    • ClassicyMenuItemHover
    • ClassicyMenuOpen
    • ClassicyWindowClose
    • ClassicyWindowCollapse
    • ClassicyWindowControlClickDown
    • ClassicyWindowControlClickUp
    • ClassicyWindowExpand
    • ClassicyWindowFocus
    • ClassicyWindowMoveIdle
    • ClassicyWindowMoveMoving
    • ClassicyWindowMoveStop
    • ClassicyWindowOpen
    • ClassicyWindowResizeIdle
    • ClassicyWindowResizeResizing
    • ClassicyWindowResizeStop
    • ClassicyWindowZoomMaximize
    • ClassicyWindowZoomMinimize
  • ClassicyDesktopIcon

    • ClassicyDesktopClick
    • ClassicyDesktopAltClick
    • ClassicyDesktopDoubleClick
    • ClassicyDesktopDrag
  • ClassicyApp

    • ClassicyAppOpen
    • ClassicyAppClose
    • ClassicyAppHide
    • ClassicyAppFocus
  • ClassicyWindow

    • ClassicyWindowOpen
    • ClassicyWindowClose
    • ClassicyWindowZoom
    • ClassicyWindowCollapse
    • ClassicyWindowResize
    • ClassicyWindowDrag
    • ClassicyWindowFocus
    • ClassicyWindowContentScroll
    • ClassicyWindowContentClick
  • ClassicyMenu

    • ClassicyMenuHover
    • ClassicyMenuClick
    • ClassicyMenuChange

License

This software is provided free and in the public domain under The Unlicense.