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

@everystate/pattern-catalogue

v1.1.0

Published

EveryState Pattern Catalogue - 13 UI patterns demonstrating the No Ceiling architecture: declarative specs, imperative components, and the { component } escape hatch

Readme

@everystate/pattern-catalogue

EveryState Pattern Catalogue - A comprehensive demonstration of 13 UI patterns using the "No Ceiling" architecture.

This application showcases the hybrid approach where declarative view specs and imperative components work together seamlessly through the { component } escape hatch. The store's dot-paths are the universal interface.

Architecture: No Ceiling

Declarative Specs              Imperative Components
(from @everystate/view-ui)     (from @everystate/ui)
         \                           /
          ------> composed via <-----
              { component: "name" }

No floor: Beginners write declarative specs
No ceiling: Experts drop to imperative when needed
Universal interface: The store's dot-paths connect everything

What's Included

13 UI Patterns

| Pattern | Type | Package | Demonstrates | |---------|------|---------|--------------| | Counters | Declarative | @everystate/view-ui | forEach, bind, drag-and-drop reordering | | Table | Declarative | @everystate/view-ui | Nested forEach, fragment forEach, bind interpolation | | Undo/Redo | Imperative | @everystate/ui | History tracking, time-travel debugging | | Accordion | Imperative | @everystate/ui | Exclusive visibility, toggle state | | Toasts | Imperative | @everystate/ui | Auto-dismiss timers, stacking | | FSM | Imperative | @everystate/ui | Finite state machines, parallel HSM | | Grid | Imperative | @everystate/ui | Derived state, computed subtotals | | Form | Imperative | @everystate/ui | Validation, error display, derived valid state | | Todos | Imperative | @everystate/ui | Hierarchical TOC, nested lists | | SWAPI | Imperative | @everystate/ui | Async data, loading states, pagination | | Tabs | Imperative | @everystate/ui | Exclusive panels, content preservation | | Modals | Imperative | @everystate/ui | Stacking, focus management | | Theme | Imperative | @everystate/ui | CSS custom properties, data-theme attribute |

5 Pages

  • Home (/) - Counters, Undo/Redo, Accordion, Toasts, FSM
  • Data (/data) - Table, Grid
  • Forms (/forms) - Form validation, Todos
  • Async (/async) - SWAPI async data fetching
  • UI (/ui) - Tabs, Modals

Installation

npm install @everystate/pattern-catalogue
cd node_modules/@everystate/pattern-catalogue
npm install
npm run dev

Open http://localhost:8080

Quick Start (Clone & Run)

git clone https://github.com/ImsirovicAjdin/everystate-pattern-catalogue
cd everystate-pattern-catalogue
npm install
npm run dev

How It Works

1. Store as Universal Interface

All components (declarative and imperative) read and write to the same store:

const store = createEveryState({
  counterIds: ['a', 'b', 'c'],
  counters: { a: { count: 0 }, b: { count: 0 }, c: { count: 0 } },
  // ... all other state
});

2. One Factory, One Line Per Page

createSpecPage auto-merges handler factories and auto-names component mount functions:

import { createSpecPage } from '@everystate/view/app';
import { tableHandlers, countersHandlers } from '...';
import { mountTabs, mountGrid, mountFSM } from '...';

const page = createSpecPage({
  store,
  handlers: [tableHandlers, countersHandlers],
  components: [mountTabs, mountGrid, mountFSM],
});

3. Pages Are Pure Data

Specs are JSON-serializable objects. No boot functions, no manual wiring:

const homeSpec = {
  tag: "div", children: [
    countersSpec,              // declarative: forEach + bind
    { component: "undoRedo" }, // imperative escape hatch
    { component: "fsm" },     // imperative escape hatch
  ]
};

4. Routes Map Specs to Pages

const router = createRouter({
  store,
  routes: [
    { path: '/',      view: 'home',  component: page(homeSpec) },
    { path: '/data',  view: 'data',  component: page(dataSpec) },
    { path: '/forms', view: 'forms', component: page(formsSpec) },
  ],
});
router.start();

The entire app wiring is 3 statements: create the store, create the page factory, start the router.

Key Concepts

The { component } Escape Hatch

When a declarative spec contains { component: "name" }, the view interpreter:

  1. Creates a container element
  2. Looks up the mount function from the components registry
  3. Calls mountFn(store, container)
  4. Stores the returned teardown function
  5. Treats it as a leaf node (no child recursion)

The imperative component has full DOM control inside its container. The store is the only shared interface.

Dot-Path Subscriptions

Both declarative and imperative components use the same subscription model:

// Declarative: bind attribute
{ tag: "h2", bind: "counters.{counterId}.count" }

// Imperative: explicit subscription
store.subscribe('counters.a.count', (v) => el.textContent = v);

Wildcards work everywhere:

store.subscribe('counters.*', () => recalculateTotal());

TOC Pattern

Table of Contents (TOC) arrays drive list rendering:

{
  counterIds: ['a', 'b', 'c'],  // <- TOC
  counters: {                    // <- data indexed by TOC
    a: { count: 0 },
    b: { count: 0 },
    c: { count: 0 },
  }
}

Declarative: forEach: "counterIds"
Imperative: syncTOC(store, 'counterIds', container, mountFn)

Architecture Notes

See option6-no-ceiling-notes.md for a deep dive into:

  • Why this architecture exists
  • Comparison to other frameworks
  • Design principles and tradeoffs
  • The journey from options 1-6

Dependencies

All EveryState packages are peer dependencies or regular dependencies:

  • @everystate/core - Store with dot-path subscriptions
  • @everystate/view - Declarative spec interpreter
  • @everystate/view-ui - Declarative component specs
  • @everystate/ui - Imperative components
  • @everystate/router - SPA routing as state
  • @everystate/aliases - DOM shorthand (mk, data, cls, on, append)

Scripts

npm run dev      # Start Vite dev server on port 8080
npm run build    # Build for production
npm run preview  # Preview production build

Philosophy

  • Transparent: Every spec is a readable plain object, every component is vanilla JS
  • No ceiling: Escape to imperative when declarative becomes awkward
  • No floor: Declarative specs are beginner-friendly
  • Zero magic: No virtual DOM, no reconciliation, no hidden reactivity
  • Longevity: Plain JS objects and functions never break

License

MIT © Ajdin Imsirovic