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

@prismui/react

v0.5.0

Published

React adapter for PrismUI - A composable UI runtime platform with four-layer architecture

Readme

@prismui/react

React adapter for PrismUI Runtime Kernel

npm version License: MIT

Overview

@prismui/react is the official React adapter for PrismUI Runtime Kernel. It provides hooks-based integration for React applications, enabling seamless access to the event-driven runtime with full TypeScript support.

Hooks-based APIZero business logicFull TypeScript support

Installation

npm install @prismui/react @prismui/core

Peer Dependencies:

  • react >= 18.0.0
  • react-dom >= 18.0.0
  • @prismui/core >= 0.5.0

Quick Start

1. Setup Runtime and Provider

import {
  createInteractionRuntime,
  createPageModule,
  createModalModule,
} from "@prismui/core";
import { PrismUIProvider } from "@prismui/react";

// Create runtime
const runtime = createInteractionRuntime({
  modules: [createPageModule(), createModalModule()],
});

// Wrap your app
function App() {
  return (
    <PrismUIProvider runtime={runtime}>
      <YourApp />
    </PrismUIProvider>
  );
}

2. Use Hooks in Components

import { usePage, useModal, useUI } from "@prismui/react";

function MyComponent() {
  const { currentPage, transition } = usePage();
  const { stack, open, close } = useModal();
  const ui = useUI();

  return (
    <div>
      <h1>Current Page: {currentPage}</h1>
      <button onClick={() => transition("dashboard")}>Go to Dashboard</button>
      <button onClick={() => ui.modal.open("confirm")}>Open Modal</button>
    </div>
  );
}

Available Hooks

Core Hooks

useRuntime()

Access the runtime instance directly.

import { useRuntime } from "@prismui/react";

function MyComponent() {
  const runtime = useRuntime();

  // Access runtime methods
  runtime.dispatch({ type: "MY_EVENT", payload: "data" });

  return <div>...</div>;
}

useRuntimeState()

Subscribe to the entire runtime state.

import { useRuntimeState } from "@prismui/react";

function MyComponent() {
  const state = useRuntimeState();

  return <div>Current Page: {state.currentPage}</div>;
}

useSelector(selector)

Subscribe to partial state with memoization.

import { useSelector } from "@prismui/react";

function MyComponent() {
  const modalCount = useSelector((state) => state.modalStack.length);

  return <div>Open Modals: {modalCount}</div>;
}

Module Hooks

usePage()

Page navigation and state.

import { usePage } from "@prismui/react";

function Navigation() {
  const { currentPage, transition, history } = usePage();

  return (
    <nav>
      <button onClick={() => transition("home")}>Home</button>
      <button onClick={() => transition("about")}>About</button>
      <p>Current: {currentPage}</p>
    </nav>
  );
}

useModal()

Modal management.

import { useModal } from "@prismui/react";

function ModalControls() {
  const { stack, open, close, closeAll, isOpen } = useModal();

  return (
    <div>
      <button onClick={() => open("dialog")}>Open Dialog</button>
      <button onClick={() => close("dialog")}>Close Dialog</button>
      <p>Open modals: {stack.length}</p>
    </div>
  );
}

useDrawer()

Drawer management.

import { useDrawer } from "@prismui/react";

function DrawerControls() {
  const { stack, open, close, isOpen } = useDrawer();

  return <button onClick={() => open("menu", "left")}>Open Menu</button>;
}

useNotification()

Notification system.

import { useNotification } from "@prismui/react";

function NotificationDemo() {
  const { items, notify, dismiss, dismissAll } = useNotification();

  const showSuccess = () => {
    notify({
      type: "success",
      message: "Operation completed!",
      autoDismissMs: 3000,
    });
  };

  return (
    <div>
      <button onClick={showSuccess}>Show Success</button>
      <p>Active notifications: {items.length}</p>
    </div>
  );
}

useForm()

Form state management.

import { useForm } from "@prismui/react";
import { useEffect } from "react";

function LoginForm() {
  const form = useForm();

  useEffect(() => {
    form.register("email", "");
    form.register("password", "");
  }, []);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    const isValid = form.validate((fields) => ({
      email: !fields.email?.value ? "Email is required" : null,
      password: !fields.password?.value ? "Password is required" : null,
    }));

    if (isValid) {
      form.submit();
      try {
        await loginAPI(form.getValues());
        form.submitDone();
      } catch (error) {
        form.submitFail(error.message);
      }
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={form.fields.email?.value || ""}
        onChange={(e) => form.set("email", e.target.value)}
        onBlur={() => form.touch("email")}
      />
      {form.fields.email?.error && (
        <span className="error">{form.fields.email.error}</span>
      )}

      <input
        type="password"
        value={form.fields.password?.value || ""}
        onChange={(e) => form.set("password", e.target.value)}
      />

      <button type="submit" disabled={form.isSubmitting}>
        {form.isSubmitting ? "Logging in..." : "Login"}
      </button>

      {form.formSubmitError && (
        <div className="error">{form.formSubmitError}</div>
      )}
    </form>
  );
}

useAsync()

Async operation tracking.

import { useAsync } from "@prismui/react";

function DataLoader() {
  const async = useAsync();

  const loadUsers = async () => {
    async.start("fetchUsers");
    try {
      const response = await fetch("/api/users");
      const data = await response.json();
      async.done("fetchUsers", data);
    } catch (error) {
      async.fail("fetchUsers", error.message);
    }
  };

  const operation = async.getOperation("fetchUsers");

  return (
    <div>
      <button onClick={loadUsers} disabled={async.isLoading("fetchUsers")}>
        Load Users
      </button>

      {async.isLoading("fetchUsers") && <Spinner />}

      {operation?.status === "success" && (
        <div>Data: {JSON.stringify(operation.data)}</div>
      )}

      {operation?.status === "error" && (
        <div className="error">{operation.error}</div>
      )}
    </div>
  );
}

Unified DSL Hook

useUI()

Access the unified Interaction DSL with a stable memoized reference.

import { useUI } from "@prismui/react";

function MyComponent() {
  const ui = useUI();

  const handleDelete = async () => {
    const confirmed = await ui.confirm("deleteDialog");
    if (confirmed) {
      ui.notify.success("Item deleted!");
    } else {
      ui.notify.info("Cancelled");
    }
  };

  return (
    <div>
      <button onClick={handleDelete}>Delete</button>
      <button onClick={() => ui.drawer.open("menu", "left")}>Open Menu</button>
    </div>
  );
}

Router Hooks

useRouter()

URL-driven navigation with browser history.

import { useRouter } from "@prismui/react";

function Navigation() {
  const { path, push, back, forward, query } = useRouter();

  return (
    <nav>
      <button onClick={() => push("/dashboard")}>Dashboard</button>
      <button onClick={() => push("/settings?tab=profile")}>Settings</button>
      <button onClick={() => back()}>← Back</button>
      <p>Current path: {path}</p>
    </nav>
  );
}

useLocation()

Reactive router location.

import { useLocation } from "@prismui/react";

function LocationInfo() {
  const { pathname, search, hash } = useLocation();
  return (
    <p>
      {pathname}
      {search}
      {hash}
    </p>
  );
}

useSearchParams()

Reactive query string with setter.

import { useSearchParams } from "@prismui/react";

function SearchFilter() {
  const [params, setParams] = useSearchParams();
  return (
    <input
      value={params.q || ""}
      onChange={(e) => setParams({ q: e.target.value })}
    />
  );
}

Link

Anchor element that navigates via the Router Module.

import { Link } from "@prismui/react";

function NavLinks() {
  return (
    <nav>
      <Link to="/dashboard">Dashboard</Link>
      <Link to="/settings" replace>
        Settings
      </Link>
    </nav>
  );
}

DevTools Hook

useDevTools()

Access runtime DevTools for inspection, timeline, metrics, and snapshots.

import { useDevTools } from "@prismui/react";

function DevToolsPanel() {
  const { available, stateTree, timeline, metrics, snapshots, controller } =
    useDevTools();

  if (!available) return <p>DevTools module not registered</p>;

  return (
    <div>
      <h3>Performance</h3>
      <p>Total events: {metrics.totalEvents}</p>
      <p>Avg duration: {metrics.averageDuration.toFixed(2)}ms</p>

      <h3>Timeline ({timeline.length} entries)</h3>
      {timeline.map((entry, i) => (
        <div key={i}>
          {entry.event.type} — {entry.duration}ms
        </div>
      ))}

      <button onClick={() => controller.captureSnapshot("manual")}>
        Capture Snapshot
      </button>

      <button
        onClick={() => {
          controller.agent.dispatch({
            type: "PAGE_MOUNT",
            payload: { pageId: "test" },
          });
        }}
      >
        Agent: Dispatch Event
      </button>
    </div>
  );
}

TypeScript Support

Full TypeScript definitions included:

import type {
  UsePage,
  UseModal,
  UseDrawer,
  UseNotification,
  UseFormReturn,
  UseAsyncReturn,
  UseDevToolsReturn,
} from "@prismui/react";

Architecture

@prismui/react is a thin adapter layer with zero business logic:

  • All hooks are simple wrappers around runtime controllers
  • State updates trigger React re-renders via useState + useEffect
  • No React-specific logic in @prismui/core
┌─────────────────────────────────┐
│   Your React Components         │
├─────────────────────────────────┤
│   @prismui/react (Hooks)        │
│   - usePage, useModal, etc.     │
├─────────────────────────────────┤
│   @prismui/core (Runtime)       │
│   - EventBus, Store, Modules    │
└─────────────────────────────────┘

Package Info

Links

License

MIT © Fangjun