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

@triggery/react

v0.10.0

Published

React 18+/19 bindings for Triggery — useEvent / useCondition / useAction / useInlineTrigger / useInspect hooks + <TriggerRuntimeProvider> / <TriggerScope>. Zero runtime dependencies.

Readme

@triggery/react

React 18+/19 bindings for Triggery. Same useEvent / useCondition / useAction shape as @triggery/solid and @triggery/vue. Zero runtime dependencies — the binding is a thin lifecycle layer over @triggery/core.

Install

pnpm add @triggery/core @triggery/react
# pnpm / npm / yarn / bun all work

react and react-dom are peer deps (≥ 18.0.0).

Quick start

A complete scenario lives across four small files. The trigger reads like a spec, components only know about their own port.

1. Define the trigger

// src/triggers/message.trigger.ts
import { createTrigger } from '@triggery/core';

type Settings = { sound: boolean; notifications: boolean };

export const messageTrigger = createTrigger<{
  events: { 'new-message': { text: string; author: string } };
  conditions: { settings: Settings };
  actions: { showToast: { title: string; body: string } };
}>({
  id: 'message-received',
  events: ['new-message'],
  required: ['settings'],
  handler({ event, conditions, actions }) {
    if (!conditions.settings.notifications) return;
    actions.showToast?.({
      title: event.payload.author,
      body: event.payload.text,
    });
  },
});

2. Wrap the tree

// src/main.tsx
import { createRuntime } from '@triggery/core';
import { TriggerRuntimeProvider } from '@triggery/react';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { App } from './App.tsx';

const runtime = createRuntime();

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <TriggerRuntimeProvider runtime={runtime}>
      <App />
    </TriggerRuntimeProvider>
  </StrictMode>,
);

3. Wire components into ports

// src/App.tsx
import { useAction, useCondition, useEvent } from '@triggery/react';
import { useState } from 'react';
import { messageTrigger } from './triggers/message.trigger.ts';

function SettingsProvider() {
  const [settings] = useState({ sound: true, notifications: true });
  useCondition(messageTrigger, 'settings', () => settings, [settings]);
  return null;
}

function Chat() {
  const fire = useEvent(messageTrigger, 'new-message');
  return (
    <button type="button" onClick={() => fire({ text: 'hi', author: 'Alice' })}>
      send
    </button>
  );
}

function Toast() {
  useAction(messageTrigger, 'showToast', ({ title, body }) => {
    console.log(`[${title}] ${body}`);
  });
  return null;
}

export function App() {
  return (
    <>
      <SettingsProvider />
      <Chat />
      <Toast />
    </>
  );
}

Click the button — Toast gets the action. Toggle settings.notifications to false — silent.

For a runnable version: examples/vite-react-counter or open it in StackBlitz from the main README.

API

<TriggerRuntimeProvider runtime>

Provides a Runtime to the subtree. Required for any descendant using the hooks below. You normally create one runtime per app, but isolated runtimes (per-feature, per-tab, per-test) are fully supported.

<TriggerScope id>

Scopes condition / action registrations to triggers that declared the same scope id. Triggers without a scope see only registrations made outside any <TriggerScope>.

useEvent(trigger, eventName)

Returns a stable (payload) => void emitter. Identity is stable across renders.

useCondition(trigger, name, getter, deps?)

Registers a getter the runtime invokes at fire time. Pull-only — your component never re-renders because of the trigger. deps work like useMemo — when they change the runtime sees the fresh closure.

useAction(trigger, name, handler)

Registers an action handler. Last-mount-wins with a DEV warn-once on collision.

useInlineTrigger({ on, do, id? })

Defines a one-off trigger inline inside a component — useful for tiny analytics taps or modal-stack coordination that doesn't need its own *.trigger.ts file. The trigger lives for the lifetime of the component.

useInspect(trigger) / useInspectHistory(limit?)

Read the latest snapshot of a trigger, or subscribe to the runtime's inspector ring buffer. Pair with <InspectorView> from @triggery/devtools-panel for a turnkey debug UI.

createNamedHooks(trigger)

Returns { useFooEvent, useBarCondition, useBazAction } named hooks derived from the trigger schema — purely for code readability in larger files.

Documentation

Full documentation, recipes and API reference at https://triggeryjs.github.io/packages/react/.

Related packages

See the full package list in the repo README.

License

MIT © Aleksey Skhomenko