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

@jayalfredprufrock/mobx-toolbox

v0.5.4

Published

Misc mobx/react modules/utilities.

Readme

mobx-toolbox

A collection of MobX + React utilities: lazy-loading observables, model/store factories, a client-side router, form state management, dialog management, and general-purpose React hooks.

Installation

pnpm add @jayalfredprufrock/mobx-toolbox mobx mobx-react-lite

Peer dependencies:

| Package | Required for | | -------------------------- | ------------------------------------------------------------------- | | mobx + mobx-react-lite | all modules | | typebox | form, model | | history | router | | react | dialog, form, lazy-observable, react-util, router, util |


Modules

dialog

MobX-powered dialog/modal stack with state-transition support for enter/exit animations.

import { useDialogs, MobxDialogs } from "@jayalfredprufrock/mobx-toolbox/dialog";

function App() {
  const dialogs = useDialogs();
  return <MobxDialogs store={dialogs} />;
}

// Anywhere in the tree:
const dialogs = useDialogStore();
dialogs.open(ConfirmModal, { message: "Are you sure?" });

Full docs


form

Schema-driven form state with TypeBox validation, field-level error messages, and submit lifecycle tracking.

import { useForm, MobxForm } from "@jayalfredprufrock/mobx-toolbox/form";
import * as T from "typebox";

const schema = T.Object({ email: T.String(), password: T.String({ minLength: 8 }) });

function LoginForm() {
  const form = useForm(schema, { handleSubmit: async (data) => login(data) });
  return (
    <MobxForm store={form}>
      <input {...form.fields.email.props()} />
      <button type="submit">Login</button>
    </MobxForm>
  );
}

Full docs


lazy-observable

Lazy-loading MobX observables that fetch data on first observation and reset automatically when unobserved.

import { lazyObservableArray } from "@jayalfredprufrock/mobx-toolbox/lazy-observable";

const users = lazyObservableArray(() => api.getUsers());
// users.value is [] until observed; fetch fires automatically inside an observer

Includes a LazyObserver React component that renders a placeholder while loading and propagates fetch errors to an error boundary.

Full docs


model

Factory functions for creating observable model classes and collection stores from TypeBox schemas.

import { makeModel, makeStore } from "@jayalfredprufrock/mobx-toolbox/model";
import * as T from "typebox";

const UserModel = makeModel(T.Object({ id: T.Number(), name: T.String() }), {
  keys: ["id"] as const,
  reload: ({ id }) => api.get(`/users/${id}`),
  delete: ({ id }) => api.delete(`/users/${id}`),
});

const UserStore = makeStore(UserSchema, {
  transform(data) {
    return new UserModel(data, this);
  },
  getAll: () => api.get("/users"),
  create: (body) => api.post("/users", body),
});

export const userStore = new UserStore();
await userStore.getAll(); // → User[]
await userStore.all.value[0].delete(); // removes from store too

Full docs


router

MobX-based client-side router for React. Routes are plain objects; symbol-keyed metadata controls guards, loaders, and layouts.

import {
  RouterStore,
  Router,
  makeRoutes,
  GUARD,
  LOAD,
} from "@jayalfredprufrock/mobx-toolbox/router";

const routes = makeRoutes()({
  index: HomePage,
  dashboard: {
    [GUARD]: requireAuth,
    [LOAD]: loadDashboard,
    index: DashboardPage,
    $id: DetailPage,
  },
});

const router = new RouterStore();
router.initialize(routes);

function App() {
  return <Router store={router} />;
}

Full docs


react-util

General-purpose React hooks: async state management, debouncing, resize observation, and mount lifecycle helpers.

import { useAsync, useDebouncedCallback } from "@jayalfredprufrock/mobx-toolbox/react-util";

// Runs on mount; re-runs when deps change; handles loading/error/value
const state = useAsync(async (signal) => fetchUser(id), [id]);

// Stable debounced callback, safe to call after unmount
const save = useDebouncedCallback((value) => persist(value), []);

Full docs


util

Small MobX + React utilities.

import { mutable, useAutorun } from "@jayalfredprufrock/mobx-toolbox/util";

// Class accessor decorator — makes a field reactive without makeObservable
class Store {
  @mutable accessor theme = "light";
}

// MobX autorun that disposes on unmount
function MyComponent() {
  useAutorun(() => {
    document.title = store.pageTitle;
  });
}

Full docs