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

@econ-v1/node-design-seam

v0.1.8

Published

Vendored design drops + data-slot wiring: the closed-vocabulary seam runtime and the pin/bindings/verify CLI

Readme

@econ-v1/node-design-seam

npm

Vendored design drops + data-slot wiring. A designer ships a folder of hash-pinned files — markup, CSS, view modules — that the product renders byte-for-byte. Integration binds live kernel data into it through a write vocabulary too narrow to carry a restyle: set text, set one allowlisted attribute, toggle a state attribute the design itself declared. Nothing in that vocabulary can write a class, a style, or an element. The CLI (pin / bindings / verify / adopt) is the CI gate that keeps the tree honest about it, and preview lets the designer render the drop through that same runtime before anyone integrates it.

This package ships three things:

  • a small runtime (createSeam, mountDropFragment, wireStage, applyBindings) that a stage's own entry module calls to mount a drop and feed it data;
  • a CLI (node-design-seam) that hashes, scans, and verifies a drop against a per-app config file;
  • a teaching layer — the docs below, a skill for each side of the seam (drop-authoring for the designing agent, node-design-seam for the integrating one), and an AGENTS.md template that travels inside the drop.

Documentation

Full docs live in docs/ and ship inside the published tarball.

| | | | --- | --- | | Getting started | install → adopt → wire → verify, end to end | | Working in parallel | designer previews with no stack, developer wires with no data | | Concepts | drops, slots, the seam, and the two hash layers | | Write vocabulary | the three forms, the seven attributes, and what they can't reach | | Configuration | every config key, its default, and what rejects it | | CLI | the four commands: flags, output, exit codes | | Runtime API | full signatures and types | | Troubleshooting | a decoder for every verify failure | | CHANGELOG | read before upgrading — three past releases failed silently |

Two agent skills and one template ship alongside, each written for one side of the seam:

| | | | --- | --- | | skills/drop-authoring/SKILL.md | designer — is this a drop change at all, the authoring sequence, the five fixture states, verification before hand-off | | skill/SKILL.md | integrator — the adopt/wire/verify runbook, the hard rules, a decoder for every gate failure | | templates/AGENTS.stage-drop.md | the drop contract itself: copied into a new drop's root as AGENTS.md, carrying the contract: line the CLI version-gates against |

Install

npm i -D @econ-v1/node-design-seam

Node 18+. The CLI is invoked via the node-design-seam bin it installs; the runtime is imported at the top of a stage's entry module:

import { createSeam, mountDropFragment, wireStage } from "@econ-v1/node-design-seam";

TypeScript declarations ship with the package (generated from the same JSDoc checkJs type-checks — see Runtime API), so this resolves with no @ts-expect-error, Binding included.

Quick start

A stage entry mounts the drop's own bytes, creates a seam over the mounted root, and wires kernel live queries into it — lifecycle-paired to mount(ctx) / unmount():

// ui/src/main.js — the stage entry (developer-owned)
import { createSeam, mountDropFragment, wireStage } from "@econ-v1/node-design-seam";
import BINDINGS from "./design/bindings.gen.js";
import cards from "../../design/wallet-stage-v1/views/cards.view.js";
import DROP_HTML from "../../design/wallet-stage-v1/stage.html?raw";
import DROP_CSS from "../../design/wallet-stage-v1/stage.css?raw";

let seam, unwire;

export async function mount(ctx) {
  const { root } = mountDropFragment({ host: ctx.host.root, html: DROP_HTML, css: [DROP_CSS] });
  seam = createSeam({ root, bindings: BINDINGS, views: [cards] });
  unwire = wireStage(seam, ctx, {
    snapshot: { query: "wallet.summary.v1", params: {}, project: toSummarySnapshot },
    views: { "wallet.cards": { query: "wallet.cards.v1", params: {}, project: toCardsModel } },
  });
}

export async function unmount() {
  unwire?.();
  seam?.dispose();
}

mountDropFragment hosts the drop's html/css verbatim, by default inside a shadow root. createSeam returns an instance scoped to that root — update(snapshot) drives the scalar bindings, feedView(id, data) re-renders a view module into the element carrying its data-view-slot="<id>". wireStage is optional sugar returning a disposer for unmount().

The project functions are the kernel→slot mapping. They conform kernel view-models to the design's slot names, and must return plain data, never markup.

Walked through step by step in Getting started; full signatures in the Runtime API.

The write vocabulary

The design declares its slots in its own markup. The applier can do nothing that isn't one of these three forms:

| In the drop's markup | What integration may do | | --- | --- | | data-bind="slot.path" | replace the element's textContent — never its markup | | data-bind-attr="attrName:slot.path" | set an allowlisted attribute (several comma-separated pairs allowed) | | data-bind-when="slot.path" | toggle hidden when the value is falsy |

The allowlist is exactly seven names — aria-label, aria-valuenow, data-count, data-state, hidden, href, title. class, style and id are excluded and the applier has no branch that writes them. That absence is the mechanism: "integration cannot restyle the design" is a property of the code, not a rule to remember.

Continuous geometry (chart paths, bar widths), values carrying structure inside a string, and theme cannot be expressed this way — and the answer is never a new verb. See Write vocabulary.

Configuration

One node-design-seam.config.json per app repo. Three keys are required:

{
  "dropRoot": "design/wallet-stage-v1",
  "manifestOut": "ui/src/design/drop-manifest.js",
  "bindingsOut": "ui/src/design/bindings.gen.js"
}

notDropContent, legacyAnchors and unwired default sensibly. All paths resolve relative to the config file. Pass a different path with --config <path>. Full reference: Configuration.

Commands

| | | | --- | --- | | node-design-seam pin | hashes every drop file into manifestOut. Adoption only — regenerating it to silence a failing verify is the one canonical misuse | | node-design-seam bindings | scans the drop's data-bind* attributes into bindingsOut; refuses to write on any scan error | | node-design-seam verify | the CI gate: integrity, anchors, contract coverage, freshness, plus the contract-version gate | | node-design-seam adopt <path> | the runbook as one command — place, re-point, pin, regenerate, and print the contract diff | | node-design-seam preview | serves the drop through the real runtime for authoring and goldens; --drop <path> needs no config |

"scripts": {
  "build": "vite build && node-design-seam verify",
  "verify:design": "node-design-seam verify"
}

Full reference: CLI.

Two hash layers, two lifecycles

The seam manifest (manifestOut, from pin) records what design shipped: it changes only at adoption and gates the source tree. An app manifest's ui.integrity records what this build ships: restamped every build, gating delivery and the shell's cache verification on load. verify runs before stamping, so a tampered drop can never launder itself into a validly-stamped package — the build fails at the seam gate first. Detail in Concepts.

Contributing

Gates, the rules a contributor must not break, and the release process are in CONTRIBUTING.md.

License

GNU Affero General Public License v3.0 only (AGPL-3.0-only).

Versions 0.1.1 through 0.1.7 were published under MIT OR Apache-2.0; that grant still stands for those releases.

Further reading

  • Framework design (locked): docs/superpowers/specs/2026-08-10-design-seam-framework-design.md in the econ-v1/node repo.
  • The contract this package implements: docs/design/DATA_SLOT_CONTRACT.md in the econ-v1/node repo.