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

@middag-io/react

v0.37.1

Published

MIDDAG shared React UI library for Moodle, WordPress and other Inertia hosts

Readme

@middag-io/react

Shared React UI library for the MIDDAG ecosystem. Consumed by Moodle (local_middag) and WordPress host plugins via Inertia.js.

Live Demo | Documentation

Stack

  • React 19, TypeScript, Tailwind CSS v4
  • Inertia.js (peer dependency — all hosts use Inertia)
  • ReUI components (Radix-based)
  • TanStack Table, @xyflow/react, @dnd-kit

Install

Quick start (recommended)

npx create-middag-ui

The wizard detects your host platform (Moodle/WordPress), configures authentication, and scaffolds a ui/ directory with a working build.

Manual install

npm public (no auth needed):

npm install @middag-io/react react react-dom @inertiajs/react @inertiajs/core

GitHub Packages (includes TypeScript source for IDE navigation):

# Add to global ~/.npmrc
echo "@middag-io:registry=https://npm.pkg.github.com" >> ~/.npmrc
echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN" >> ~/.npmrc

npm install @middag-io/react react react-dom @inertiajs/react @inertiajs/core

Create a token at github.com/settings/tokens with read:packages scope. See Authentication for details.

Distribution

@middag-io/react is the complete rendering engine — every block, shell, layout, contract and registry you need to build plugins. Two ways to install it:

  • npm (public, no auth): compiled ESM bundle + type declarations + declaration maps.
  • GitHub Packages (auth): adds the TypeScript src/ for IDE "go to definition". Requires a read:packages token (see above).

MIDDAG also offers a commercial Pro tier (@middag-io/react-pro) — additional blocks, an application shell and extra themes, used for internal products and consulting. Not needed to build with this library.

Usage

import { ContractPage, registerDefaults } from '@middag-io/react';
import type { PageContract } from '@middag-io/react';

// Register core shells, layouts, and the standard Community blocks
registerDefaults();

// Render a contract-driven page
<ContractPage contract={myContract} />

Selective registration (IIFE consumers)

WordPress and other IIFE consumers should import only the blocks they need to avoid bundling heavy dependencies (@xyflow/react, @dnd-kit, zod, react-hook-form) via inlineDynamicImports:

import {
  registerShell, registerLayout, registerBlock,
  BasicShell, StackLayout, SidebarLayout, DashboardLayout,
  DenseTableBlock, MetricCardBlock, EmptyStateBlock,
} from '@middag-io/react';

registerShell('product', BasicShell);
registerLayout('stack', StackLayout);
registerLayout('sidebar', SidebarLayout);
registerLayout('dashboard', DashboardLayout);
registerBlock('dense_table', DenseTableBlock);
registerBlock('metric_card', MetricCardBlock);
registerBlock('empty_state', EmptyStateBlock);

Lazy block loading

Blocks can defer data loading until they mount (useful for tabbed pages):

// PHP sends block with empty data + lazyProp metadata:
{
  type: 'dense_table',
  key: 'invoices',
  data: {},
  meta: { lazyProp: 'invoices' }
}

// PHP also sends a top-level Inertia prop (initially null):
// 'invoices' => null

// When the block mounts, it auto-fetches via router.reload({ only: ['invoices'] })
// Radix Tabs unmounts inactive tabs, so lazy blocks only fetch when their tab activates

ReUI components

Consumers can import ReUI primitives for custom components:

import { Tabs, TabsList, TabsTrigger, TabsContent } from '@middag-io/react/reui/tabs';
import { Button } from '@middag-io/react/reui/button';

Custom blocks

import { registerBlock, type BlockProps } from '@middag-io/react';

function ChartBlock({ block }: BlockProps<{ labels: string[]; values: number[] }>) {
  return <div>{/* your chart */}</div>;
}

registerBlock('chart', ChartBlock);

Contract validation

import { validatePageContract } from '@middag-io/react';

const errors = validatePageContract(contractFromBackend);
if (errors) {
  console.error('Invalid contract:', errors);
}

Zod schemas are exported for consumers who want to extend validation or generate JSON Schema for PHP consumers.

i18n with host-specific resolver

import { I18nProvider } from '@middag-io/react';

// Moodle: inject Moodle string resolver
<I18nProvider asyncResolver={moodleGetStrings}>
  <App />
</I18nProvider>

// WordPress: inject WP i18n resolver
<I18nProvider asyncResolver={wpGetStrings}>
  <App />
</I18nProvider>

Architecture

src/
  app/           # ContractPage, registries (shell/layout/block), providers, LazyBlock
  base/          # Shells, layouts, blocks, hooks, theme, form, partials, registries (field/icon/cell)
  components/
    reui/        # ReUI primitives (Radix-based, source of truth)
    examples/    # ReUI component examples (synced from registry)
  contracts/     # TypeScript types (PageContract, BlockData, etc.)
  lib/           # Generic utilities and hooks
  assets/        # Fonts, lottie animations
  index.ts       # Barrel export
demo/            # Demo harness (standalone SPA — `npm run dev`)
docs/            # Guides, reference and the public JSON schemas
scripts/         # Tooling (contracts codegen, docs payload, sync, doctor)
.githooks/       # Git hooks (pre-commit, commit-msg, pre-push)

What belongs here vs host plugins

| Here (@middag-io/react) | Host plugin (Moodle/WP) | |-----------------------------|-------------------------------------| | Shells, layouts, blocks | Extensions with host-specific pages | | ContractPage renderer | Inertia server-side adapter | | Theme system | License validation (server-side) | | i18n provider (generic) | i18n resolver (host-specific) | | Type contracts | API endpoints, DB queries | | ReUI examples (reference) | Custom components |

Development

# Check environment
npm run doctor

# Demo harness -- standalone SPA, no server needed
npm run dev             # http://localhost:5173

# Typecheck
npm run typecheck

# Lint
npm run lint:fix

# Tests
npm test

# Build ESM lib
npm run build

The demo harness consumes the engine from src/ via Vite aliases (instant HMR), mocks @inertiajs/* with self-contained adapters in demo/adapters/, and renders PageContracts end to end.

ReUI component examples

Examples from the ReUI registry are synced to src/components/examples/. They serve as reference for component usage and are excluded from the published NPM package.

# Sync all examples from ReUI registry (auto-discovers new components)
npm run sync:examples

# Preview what would be synced
npm run sync:examples -- --dry-run

# Check if new examples are available (used by CI)
npm run sync:examples -- --check

A GitHub Action runs weekly (Mondays 8:00 UTC) to check for new examples and opens a PR automatically if updates are available.

Git Hooks

Configured via .githooks/ (activated by npm run prepare):

| Hook | Trigger | Protection | |--------------|--------------|-------------------------------------------| | pre-commit | git commit | Typecheck + lint on staged files | | commit-msg | git commit | Enforces Conventional Commits format | | pre-push | git push | Typecheck + contract drift + lib build |

Versioning

release-please owns versioning: it scans Conventional Commits on main, opens a release PR (version bump + CHANGELOG.md) and, on merge, cuts the tag + GitHub release and publishes. Commit types decide the bump (0.x rule: feat/breaking = minor, fix = patch).

CLI

The package includes a CLI for bootstrapping and maintaining the UI layer in consumer projects:

| Command | Description | |-----------------------------------------|------------------------------------------------------------| | npx create-middag-ui | Bootstrap ui/ | | npx @middag-io/react doctor | Validate consumer project setup (deps, configs, peer deps) | | npx @middag-io/react dev | Start mock dev server from consumer project | | npx @middag-io/react add-block <type> | Scaffold a new block type with component + mock factory | | npx @middag-io/react upgrade | Check for updates and run codemods |

Scripts

| Command | Description | |---------------------------|------------------------------------------------| | npm run doctor | Validate development environment | | npm run dev | Demo harness (demo/) | | npm run build | Build ESM lib to dist-lib/ | | npm run typecheck | TypeScript type check | | npm run lint | ESLint check | | npm run lint:fix | ESLint auto-fix | | npm run format | Prettier format | | npm run format:check | Prettier check | | npm test | Vitest run (all tests) | | npm run gen:contracts | Regenerate contract types from JSON schemas | | npm run sync:examples | Sync ReUI examples from registry | | npm run docs:build | Build + verify the public docs payload |

Peer Dependencies

  • react ^19.0.0
  • react-dom ^19.0.0
  • @inertiajs/react ^3.0.0
  • @inertiajs/core ^3.0.0

CI/CD

| Workflow | Trigger | What it does | |------------------------------|------------------------------------|-----------------------------------------------------------------| | ci.yml | Pull requests to main | Static checks + contract drift + tests/coverage + build | | publish.yml | Push to main | release-please → publish to GitHub Packages + npm public → docs | | notify-schemas-updated.yml | Push to main (docs/public/schemas) | Notifies downstream consumers of schema changes | | sync-examples.yml | Monday 8:00 UTC / manual | Sync ReUI examples, opens PR if updates |

License

Apache-2.0 OSS. The rendering engine, the standard Community blocks, shells, layouts, contracts and registries. Free to use, fork and ship. See LICENSE.

The commercial Pro tier (@middag-io/react-pro — additional blocks, an application shell, extra themes) is a separate, proprietary package distributed via GitHub Packages. It is not part of this repository and is not needed to build with this library.