React 19 · TypeScript · tree-shakeable

Lightweight, modular React libraries

PiplupJS is a set of small packages that each solve one problem well — React Hook Form adapters for MUI, role-based access control, cache busting — so you install what you need and nothing else.

Pick the problem

The packages are grouped by what they solve, not by what they are built from.

Wired up, not wrapped up

Field binding and validation come from the adapter. The permission check resolves wildcards. Neither needs a Controller or a context lookup in your component.

import { FormContainer } from '@piplup/rhf-core';import { MuiTextFieldElement } from '@piplup/rhf-adapters/mui-material';import { Can } from '@piplup/react-acl';export function InvoiceForm() {  return (    <FormContainer onSuccess={save}>      <MuiTextFieldElement        name="reference"        label="Reference"        rules={{ required: 'Required' }}      />      {/* Rendered only if the user holds invoice:write — or invoice:* */}      <Can permission="invoice:write">        <Button type="submit">Save</Button>      </Can>    </FormContainer>  );}

Small on purpose

Each package covers one concern and ships ESM and CJS with `sideEffects: false`, so your bundler drops what you do not import.

Typed end to end

Types are generated from the source, not hand-maintained. Permission and role names can be narrowed to your own strings so a typo fails the build.

Adapters, not wrappers

Every adapter is a hook returning props and an element that spreads them. When the element does not fit, drop to the hook instead of forking it.

Peer-dependency honest

React, MUI and react-hook-form stay peers, so you control their versions and never end up with two copies in one app.

Start with the problem you have

Every package has an installation page with a runnable example, and the API pages are generated from the types they ship.