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

@zango-core/crud

v2.1.1

Published

Unified React CRUD components library for tables, forms and workflows.

Downloads

750

Readme

@zango-core/crud

npm version license React

Unified React CRUD components library for tables, forms and workflows — one of the Zango frontend packages.

@zango-core/crud renders CRUD interfaces directly from the metadata a Zango backend serves. It pairs an advanced data table (built on TanStack Table) with a dynamic form engine (built on react-jsonschema-form) and a workflow/status-transition system, all driven by one shared, context-based state layer.

The package is hooks-first. useCrud and the table hooks give you the data, state and actions with no UI attached, so you own the markup. CrudHandler is the drop-in alternative when a standard table is what you want. Neither path is deprecated, and both run on the same engine.

Features

  • Hooks first — useCrud (namespaced, with ready-made prop bags), useTable (flat) and per-concern slice hooks expose state and actions with no UI attached.
  • Drop-in when you want it — <CrudHandler api_endpoint="…" /> renders a complete table, and customTableBody lets you swap only the list while keeping fetching, toolbar and detail view.
  • Dynamic forms — server-driven or local RJSF schemas via FormRenderer, plus a themed FormHandler with render slots, custom footer buttons, and --form-* CSS-variable theming.
  • Workflows — status badges, tags, and form-based transitions out of the box.
  • Mobile ready — below the mobile breakpoint the table switches to a card layout and drawers become full-screen overlays, with no extra configuration.
  • Themeable — brand, gray and status colors come from CSS variables your app defines; see Theming.
  • Granular subpath exports — import only what you need (/core, /ui, /form, /table).

Installation

npm install @zango-core/crud
# or: bun add @zango-core/crud

Peer dependencies

Install these alongside the library:

| Package | Version | | --- | --- | | react | ^17.0.0 \|\| ^18.0.0 | | react-dom | ^17.0.0 \|\| ^18.0.0 | | react-router-dom | 7.7.0 | | @zango-core/components | ^1.0.1 |

Requires Node.js 18 or newer. The package is ESM-only ("type": "module").

Quick start

api_endpoint points at a Zango CRUD view: the backend serves the table data and the metadata that drives it.

With hooks (primary)

Mount CrudHandler with a customTableBody. It provides the engine, and your body reads it with useCrud() and renders the list however you like.

import { useCrud } from "@zango-core/crud/core";
import { CrudHandler, useTableContext } from "@zango-core/crud/table";

// Define the body at module scope so its reference stays stable.
function UserCards() {
  const crud = useCrud();
  const { openDetailDrawer } = useTableContext();
  const rows = crud.table?.getRowModel().rows ?? [];

  if (crud.isLoading && rows.length === 0) return <p>Loading…</p>;
  return (
    <div className="grid grid-cols-3 gap-4">
      {rows.map((row) => (
        <button key={row.id} type="button" onClick={() => openDetailDrawer(row)}>
          {String(row.original.name)}
        </button>
      ))}
    </div>
  );
}

export function Users() {
  return <CrudHandler api_endpoint="/api/users/" showPagination={false} customTableBody={UserCards} />;
}

For no CrudHandler chrome at all, mount TableProvider yourself and call useCrud() below it:

import { useCrud } from "@zango-core/crud/core";
import { TableProvider } from "@zango-core/crud/table";

function OrdersInner() {
  const crud = useCrud();
  return (
    <>
      <input value={crud.search.term} onChange={(e) => crud.search.setTerm(e.target.value)} />
      <ul>
        {crud.data.map((row) => (
          <li key={String(row.object_uuid)}>{String(row.name)}</li>
        ))}
      </ul>
      <button type="button" disabled={!crud.pagination.canGoNext} onClick={crud.pagination.goToNextPage}>
        Next
      </button>
    </>
  );
}

export function Orders() {
  return (
    <TableProvider apiUrl="/api/orders/">
      <OrdersInner />
    </TableProvider>
  );
}

Choosing a hook

| You want | Use | Return shape | | --- | --- | --- | | Everything in one call, flat property names | useTable() | flat | | Everything plus ready-made prop bags for the Crud* components | useCrud() | namespaced | | Just one concern (search, filters, pagination, selection, columns, actions) | slice hooks such as useTableSearch() | flat, per concern |

useTable() and useCrud() return different shapes for the same data, so mixing them up gives undefined rather than an error:

useTable().searchTerm;      useTable().currentPage;       // flat
useCrud().search.term;      useCrud().pagination.currentPage; // namespaced

useCrud() also returns prop bags (headerProps, toolbarProps, tableProps, paginationProps, filterProps, detailProps, addFormProps) that spread onto the presentational components in @zango-core/crud/ui. The hooks guide has the full reference, provider requirements and known pitfalls.

Drop-in component

When a standard table is enough, render CrudHandler alone:

import { CrudHandler } from "@zango-core/crud/table";

export function Users() {
  return <CrudHandler api_endpoint="/api/users/" />;
}

That renders a complete table: header, search, filters, pagination, and a detail drawer. See the CrudHandler guide for every prop.

Theming

Styles ship inside the JavaScript bundle and are injected automatically — there is no CSS file to import. The library reads its colors from CSS custom properties that your app defines. It does not ship brand colors, so define the brand scale at minimum:

:root {
  --color-brand-25: #e9f6f4;
  --color-brand-50: #d3ede9;
  --color-brand-100: #b1e1da;
  --color-brand-200: #8ecfc7;
  --color-brand-300: #64bdb1;
  --color-brand-400: #3fa99a;
  --color-brand-500: #136f63; /* primary */
  --color-brand-600: #0f5d53;
  --color-brand-700: #0b4a43;
  --color-brand-800: #083834;
  --color-brand-900: #052b28;
  --color-brand-950: #021815;
}

Gray, success, error and warning scales (--color-gray-*, --color-success-*, --color-error-*, --color-warning-*) can be overridden the same way, and --radius sets the corner radius. Semantic tokens such as --primary and --ring are derived from the brand scale. The full variable list is in CSS_VARIABLES.md, and per-element class and style hooks are covered in the styling guide.

Entry points

The library ships multiple entry points so consumers only pull in what they use:

| Import | Contents | | --- | --- | | @zango-core/crud | Everything (convenience root barrel). | | @zango-core/crud/core | Headless logic only — useCrud, CrudProvider, column and prop-bag helpers, types. No UI, no CSS. | | @zango-core/crud/ui | Presentational Crud* components, cells and workflow primitives. Importing it also activates the toast notifier used by the headless hooks. | | @zango-core/crud/form | FormRenderer, FormHandler, useForm, theming utilities. | | @zango-core/crud/table | Table engine — CrudHandler, Table, TableProvider, all useTable* hooks. |

Documentation

Full guides live in docs/guide/:

Further references: CSS_VARIABLES.md (theming variables), BACKEND-CONTROL-FLAGS.md (metadata flags the backend can send), and TABLE_STYLING.md.

Upgrading to 2.x

  • @zango-core/components is now ^1.0.1 (was ^0.2.x). Update the peer dependency.
  • New headless layer: useCrud, CrudProvider and useForm (see /core and /form).
  • useTableData no longer accepts cell render props; pass them to TableProvider or CrudHandler.
  • useTableActions().exportData no longer supports "xlsx"; use "json" or "csv".
  • useTablePagination takes optional overrides and works without a provider.

The full before/after table is in Building Custom CRUD Views with Hooks.

Development

git clone https://github.com/Healthlane-Technologies/pkg-zango-crud.git
cd pkg-zango-crud/crud/frontend
npm install

Common scripts:

| Script | Description | | --- | --- | | npm run dev | Start the development server (port 1234). | | npm run dev:mock | Dev server with MSW mocks enabled. | | npm run build | Build the library (all entry points). | | npm test | Run the unit test suite (Vitest). | | npm run test:e2e | Run the Playwright end-to-end suite. | | npm run lint | Lint and format diagnostics (Biome). |

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md for setup, the project layout, and the development workflow. In short: run npm run lint and npm test before opening a PR, and follow Conventional Commits for commit messages.

To report a security vulnerability, please follow SECURITY.md rather than filing a public issue.

License

This project uses a multi-license arrangement, matching the wider Zango project: documentation (docs/) is licensed under CC BY-SA 4.0, client-side JavaScript under the MIT Expat license, and all other content under the Apache License 2.0. See LICENSE for the full text.

Copyright © Healthlane Technologies Pvt. Ltd. ("Zango").