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

@playfast/reform-react

v1.0.1

Published

The React / DOM host for reform — mounts a renderer-neutral scene as a live React tree with fine-grained, tear-free reactivity.

Readme

@playfast/reform-react

The React / DOM host for reform. Mount a renderer-neutral scene as a live React tree with fine-grained, tear-free reactivity.

npm license built with Effect


@playfast/reform-react is the bridge between a reform scene and the DOM. You build a scene with @playfast/reform; this package builds its runtime, renders its compositions, and keeps the tree in sync with the engine — subscribing to exactly the state slices each composition reads, and nothing more.

Install

bun add @playfast/reform-react @playfast/reform effect react react-dom

effect, react (^19), and @playfast/reform are peer dependencies. Bring your own react-dom root.

Quick start

The app owns the React root; you hand Reform a closed scene and it does the rest:

import { createRoot } from 'react-dom/client'
import { Layer } from 'effect'
import { scene } from '@playfast/reform'
import { Reform } from '@playfast/reform-react'
import { AppShell } from './features/shell/shell.compose'
import { makeAppLayer } from './app/app.layer'

const AppScene = scene(AppShell, {
  provide: [makeAppLayer()],
})

const container = document.getElementById('root')!
createRoot(container).render(<Reform scene={AppScene} />)

Reform builds a single ManagedRuntime from the scene's closed layers for the mounted root, renders under a provider, dispatches any boot events after commit (so bus subscribers exist before events fire), and queues disposal when the scene changes or unmounts so StrictMode's synthetic cleanup can be cancelled.

If the root must produce output on its first render, prepare the runtime at an explicit ownership boundary and render the prepared handle:

import { createRoot } from 'react-dom/client'
import { prepareReform, ReformPrepared } from '@playfast/reform-react'

const prepared = prepareReform(AppScene)
createRoot(container).render(<ReformPrepared prepared={prepared} />)

Create one prepared handle per React root. ReformPrepared renders immediately, then boots and disposes the runtime from layout effects; if a prepared handle is created but never mounted, call prepared.dispose().

Key concepts

| export | kind | purpose | | --- | --- | --- | | Reform | component | Mount a Scene — the primary entry point | | prepareReform | function | Build a scene runtime before React renders | | ReformPrepared | component | Render a prepared runtime on the first pass | | PreparedReformRuntime | interface | Lifecycle handle returned by prepareReform | | Compose | component | Render a single composition (memoised by class + shallow props) | | ReformProvider | component | Provide a built runtime to child compositions | | ReformRuntime | interface | The capabilities a host needs from a built reform runtime | | ComposeOutsideProvider | error | <Compose> used without a surrounding <ReformProvider> | | UnknownSlot | error | A composition was asked for a slot its manifest does not declare |

Full API reference: playbook/api.doc.md.

How reactivity works

There are no hooks to call — subscription is automatic. Compose tracks the state slices a composition reads during render and subscribes to them through useSyncExternalStore, so updates are correct under React 19's concurrent rendering (no tearing). As tracked slices change between renders, the live subscription re-points — subscribing newly-read slices and dropping stale ones — instead of tearing down and rebuilding, keeping the hot path O(1).

Slots filled by lazy features render through a feature host that drives load / mount and paints loading and retryable-failure placeholders.

This is a synchronous client host (ManagedRuntime.runSync). The default Reform component builds after commit; prepareReform / ReformPrepared are the explicit path for first-render output.

The reform family

Core @playfast/reform · React Native host @playfast/reform-react-native · forms @playfast/reform-forms + @playfast/reform-forms-react · testing @playfast/reform-proof

License

MIT