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

@pumped-fn/lite-render-react

v0.1.2

Published

React adapter that lowers a verified @pumped-fn/lite-render-core spec to React over a Lite scope

Readme

@pumped-fn/lite-render-react

Status: experimental. APIs change without notice; not recommended for production yet.

React adapter for the @pumped-fn/lite-render-core render contract.

This is the react half of a core/react split (mirroring json-render): core owns the portable spec, the schema vocabulary, the typed authoring surface, and the runtime verifier; this package lowers a verified spec to React over a Lite scope. It is generic over an arbitrary catalog plus a component-implementation map — there is no board (or any other) domain in src.

React is an observer here. Durable state and async stay in Lite flows; this adapter only reads state reactively through useScopedValue and dispatches on / watch actions through the core dispatcher flow.

When to Use

Use this to render a @pumped-fn/lite-render-core spec in React: the catalog's components become React implementations, and the verified spec drives them. The timing is the integration edge — after the spec, schema, and flows have clear owners in core and Lite.

If the UI is hand-authored React, do not route it through a spec; render from useScopedValue and mutate through scoped actions directly. Reach for this when the spec is the artifact you ship.

Install

npm install @pumped-fn/lite @pumped-fn/lite-react @pumped-fn/lite-render-core @pumped-fn/lite-render-react

Usage

Pair a core defineRender(...) contract with your React implementations and get a one-prop <View>. The implementations are type-checked against the contract's catalog; the contract binds context, state, and the dispatcher — so the call site needs no type annotations.

import { defineRender, type NodeRenderProps } from "@pumped-fn/lite-render-core"
import { defineView } from "@pumped-fn/lite-render-react"

const render = defineRender({ schema, state, catalog, actions }) // core: one inferred contract

function BoardView({ props, slots }: NodeRenderProps<(typeof catalog)["Board"]>) {
  return <section aria-label={String(props.heading)}>{slots.rows}</section>
}
function CardView({ props, on }: NodeRenderProps<(typeof catalog)["Card"]>) {
  return <button data-done={String(props.done)} onClick={() => on.toggle({ id: "..." })}>{String(props.label)}</button>
}

const View = defineView(render, { Board: BoardView, Card: CardView }) // react: one bound component

// <View spec={spec} /> — only `spec`; context / state / dispatch / components all bound from the contract.

A BoardView / CardView whose prop or event kind disagrees with the contract's catalog fails to compile. JsonRender and defineComponents remain exported for advanced / manual wiring (JsonRender takes spec, context, components, state, and dispatch explicitly).

Mount it under the Lite providers, exactly as any @pumped-fn/lite-react tree:

<ScopeProvider scope={scope}>
  <ExecutionContextProvider ctx={ctx}>
    <View spec={spec} />
  </ExecutionContextProvider>
</ScopeProvider>

Behavior Surface

defineView (and defineComponents) bind a React implementation to every catalog component. The renderer hands each implementation three groups, all derived from the catalog:

  • props — each declared prop resolved to its kind-typed value (string, number, boolean, string | null, readonly unknown[], Record<string, unknown>).
  • slots — each slot lowered to rendered children; a repeating slot renders once per resolved array element with that element bound as the item context.
  • on — each catalog event lowered to a dispatcher whose payload is the kind-typed event shape. Inside a repeating slot the renderer threads the current element as the dispatch item, so item-bound action params ({ item: "id" }) resolve through the core dispatcher; nodes outside any repeat dispatch with no item. Two sibling nodes watching the same state path each fire their own action.

Because React props are checked contravariantly, an implementation whose prop or event kind disagrees with the catalog fails to type-check at the bind — the renderer cannot drift from the catalog the verifier guards. Verification runs lazily inside <JsonRender> (cached per context+spec identity, so the same spec re-verifies under a different context), so there is no import-time work.

Honest boundary. The mirror catches wrong-kinded props/events, not an implementation that accepts a narrower set of props — ignoring a declared prop is sound structural subtyping. The "array" prop kind erases its element type to readonly unknown[] at the impl boundary (repeating slots, not props, carry per-element rendering). Both are coarseness that cannot drift, not gaps the verifier would otherwise catch.

Exports

  • defineView(contract, impls) — binds a core contract and its catalog implementations into a React.FC<{ spec: JsonSpec }>; impls is type-checked against the contract's catalog with no call-site annotations.
  • JsonRender — the generic renderer (advanced / manual): props spec, context, components, state, dispatch.
  • defineComponents(catalog, impls) — binds and kind-checks a component-implementation map to a catalog.
  • Types: RenderContract, JsonRenderProps, ComponentMap, NodeRenderProps, EventPayload, ValueForKind, RenderCatalog, RenderCatalogComponent.

Testing

Render the real adapter in a browser test under ScopeProvider and ExecutionContextProvider over a createScope() scope, then assert DOM output and that component events run their Lite flows — no module mocks, the scope is the only seam. Spec authoring and verification can be unit-tested in @pumped-fn/lite-render-core without React.

License

MIT


Part of pumped-fn — start with the docs or the mental model.