# drf-react-by-schema

> Components and Tools for building a React App having Django Rest Framework (DRF) as server

Latest version **0.29.5** (published 2026-11-03) · MIT license · 0 weekly downloads

## Install

```sh
npm install drf-react-by-schema
pnpm add drf-react-by-schema
yarn add drf-react-by-schema
bun add drf-react-by-schema
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.29.5 |
| Published | 2026-11-03 |
| First published | 2022-12-15 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 1010.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (Unknown) |
| Author | Coletivo EITA |
| Maintainers | dtygel, llagocarvalho |
| Keywords | react, drf, django, django rest framework, schema based forms, MUI, MUI DataGrid, yup |

## Links

- npm: https://www.npmjs.com/package/drf-react-by-schema
- Repository: https://gitlab.com/eita/drf-react-by-schema/drf-react-by-schema-js
- Homepage: https://gitlab.com/eita/drf-react-by-schema/drf-react-by-schema-js#readme
- Issues: https://gitlab.com/eita/drf-react-by-schema/drf-react-by-schema-js/issues
- npm.io page: https://npm.io/package/drf-react-by-schema

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.29.5 (latest) — 2026-11-03
- 0.29.4 — 2026-11-03
- 0.29.3 — 2026-11-03
- 0.29.2 — 2026-11-02
- 0.29.1 — 2026-10-29
- 0.29.0 — 2026-10-27
- 0.28.29 — 2026-10-20
- 0.28.28 — 2026-10-19
- 0.28.27 — 2026-10-19
- 0.28.26 — 2026-10-19
- 0.28.25 — 2026-10-17
- 0.28.24 — 2026-10-17
- 0.28.23 — 2026-10-12
- 0.28.22 — 2026-10-12
- 0.28.21 — 2026-09-24
- … 223 more at https://npm.io/package/drf-react-by-schema/versions

## README

![DRF And React By Schema - React](https://gitlab.com/eita/drf-react-by-schema/drf-react-by-schema-js/-/raw/master/banner_drf-react-by-schema_react_1280x500.png)

*DRF and React by Schema* is a pair of packages — `drf-react-by-schema-django` (server) and `drf-react-by-schema` (client) — that add schema-driven CRUD to a Django REST Framework backend. Django describes each model; React renders forms, validation, lists and detail views from that description.

## How it works

- **Django/DRF owns the data model.** Models, serializers and viewsets stay on the server. `drf-react-by-schema-django` derives a per-model **schema** (field types, labels, required/read-only flags, choices, relations, validators, layout) and serves it through `OPTIONS`, or writes it to disk with the `sync_react` command.
- **React renders from the schema.** `drf-react-by-schema` reads the schema and builds the matching UI: a field `type` selects the form widget, the DataGrid cell, its inline editor and the yup validation rule. No per-model form code.
- **One source of truth.** Changing a Django model is enough to change the React forms, columns and validation. Widgets, layout, labels and validation can still be customized per app.

Published packages: npm [`drf-react-by-schema`](https://www.npmjs.com/package/drf-react-by-schema) and PyPI [`drf-react-by-schema`](https://pypi.org/project/drf-react-by-schema/).

## API reference

Every exported component (purpose and props), the full `useAPIWrapper()` API (data,
auth, form state, dialogs, feedback), the shared prop building blocks
(`fieldsLayout`, `fieldsProps`, `sumRows`, actions, …) and the utility functions are
documented in **[`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)**.

Consuming apps must use `useAPIWrapper()`. The lower-level `useDRFReactBySchema()` is
internal, is not exported from the package entry and must not be used by app code.

## Field types & widgets

Every schema field `type` maps to a specific widget. This includes the standard
types (text, number, choices, dates, booleans, files, images, …) and the **PostGIS
geometry** fields (`point`, `polygon`, `multipoint`, `multipolygon`,
`geometrycollection`), which render an interactive Leaflet map picker/drawer with a
read-only thumbnail map in the DataGrid.

See the complete table of field types and their widgets (including the geometry
behaviours — add/move/remove rules, GeoJSON text sync and fallbacks) in
**[`docs/FIELD_TYPES.md`](docs/FIELD_TYPES.md)**.

## Conditional visibility (`conditional_visible`)

A field can be shown/hidden from the `<Form>`/`FormBySchema` and the DataGrid inline
editor depending on the value of other fields. While hidden, its value is cleared on save
(and in the form). The schema key `conditional_visible`, produced by the Django package's
custom fields, accepts these shapes:

- a single `[sourceField, sourceValue]` pair — a single condition,
  e.g. `["type", "book"]`;
- a plain array of conditions — combined with **OR** (show if *any* matches), the legacy
  fallback;
- an explicit `{ operator: 'AND' | 'OR', conditions: [...] }` expression for arbitrary,
  parenthesised logic. `conditions` may mix pairs and nested expressions, e.g. show
  `isbn` only when the record `type` is `book` and the `format` is *either* `hardcover`
  *or* `paperback`:

  ```json
  {
    "operator": "AND",
    "conditions": [
      ["type", "book"],
      {
        "operator": "OR",
        "conditions": [
          ["format", "hardcover"],
          ["format", "paperback"]
        ]
      }
    ]
  }
  ```

A plain array of conditions is always **OR**; use an explicit `{ operator: 'AND', ... }`
when every condition must hold. Combined with `ui_required`, a conditionally visible field
is required only while it is actually shown.

## Scoping autocomplete options (`optionsACQueryParams`)

The package loads relation-field options automatically. To send **static query params**
with those fetches — e.g. to make a backend `filter_by_callback` scope a relation to a
parent record — pass `optionsACQueryParams`:

```tsx
const params = ufpaId ? [`ufpa_id=${ufpaId}`] : undefined;

<Form
  model="linha_de_base"
  optionsACQueryParams={
    params && {
      responsavel: params,                              // a top-level relation field
      formas_acesso_terra: { em_nome_de_quem: params }, // an inline formset's child field
    }
  }
/>
```

A relation field maps to a `string[]`; a writable inline formset maps to a nested record
keyed by its **child** fields under its parent field key. It works on `Form`,
`FormBySchema`, `InlineFormsetFieldBySchema`, the grids (`GenericModelList`,
`GenericRelatedModelList`, `DataGridBySchemaEditable`) and the related-edit dialog
(`DialogFormBySchema`). It is the static counterpart of the per-row `filterOptionsAC`.
Full details: **[`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)** §4.16.

## Localization & theming

User-facing strings (geometry picker, form/dialog action buttons, …) are exposed through
the **MUI theme** (`theme.texts`), so you can localize every widget in your own `theme.ts`
— no provider changes. The package ships with sensible defaults and also localizes the
MUI components it renders (DataGrid, date pickers) to pt-BR.

See the full reference (namespaces, precedence, MUI locale setup, custom markers) in
**[`docs/localization.md`](docs/localization.md)**.

## Authentication, password reset & e-mail

The package ships ready-made pieces for a **forgot/change password** flow over the
JWT + simplejwt stack: the `ForgotPasswordForm` and `ChangePasswordForm` components,
plus `requestPasswordReset`, `validatePasswordReset`, `confirmPasswordReset` and
`changePassword` helpers on
`useAPIWrapper()`. They talk to the endpoints provided by the **Django** package
(`password_reset/request|validate|confirm`, `my_account/change_password`).

See how to wire them up, the server contract, and how to set up e-mail/SMTP for the
reset link in **[`docs/password-reset-and-email.md`](docs/password-reset-and-email.md)**.

## Getting started

1. Build the Django project and models (guide: https://pypi.org/project/drf-react-by-schema/).

2. Create the `frontend` folder that will hold the React app.

3. Install the required peer dependencies:

```bash
yarn add @emotion/react@^11 @emotion/styled@^11 @hookform/resolvers@^3 @mui/icons-material@^6 @mui/material@^6 @mui/x-data-grid@^7 @mui/x-date-pickers@^7 axios@^1 dayjs@^1 react@^18 react-dom@^18 react-hook-form@^7 react-number-format@^5 string-mask@^0.3.0 yup@^1
```

Install the optional widget peers only for the features you use:

```bash
# geometry (PostGIS) pickers
yarn add leaflet@^1.9 react-leaflet@^5 leaflet-draw@^1.0.4
# rich-text fields (model_html)
yarn add @tiptap/react@^3 @tiptap/starter-kit@^3 dompurify@^3
```

4. Install `drf-react-by-schema`:

```bash
yarn add drf-react-by-schema
```

5. Wrap the app with `DRFReactBySchemaProvider`, passing the Django endpoints and the theme:

```tsx
// App.tsx
import { DRFReactBySchemaProvider } from 'drf-react-by-schema';
import * as schemas from './drfReactBySchema';
import { paginationConfig } from './drfReactBySchema/pagination';
import { theme } from './theme';

export default function App() {
  return (
    <DRFReactBySchemaProvider
      serverEndPoint={{
        url: 'http://localhost:8000',
        apiTokenUrl: 'http://localhost:8000/api/token/',
      }}
      schemas={schemas}
      pagination={paginationConfig}
      theme={theme}>
      <YourWonderfulApp />
    </DRFReactBySchemaProvider>
  );
}
```

`schemas` and `paginationConfig` are generated by `sync_react` (see below) and are optional: without them the provider fetches each schema with `OPTIONS` and uses the package's default pagination.

6. Build the pages from the package components. Start with a list and a form:

```tsx
<GenericModelList model="produto" paginationMode="server" />
<Form model="produto" objId={id} />
```

See **[`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)** for every component and the `useAPIWrapper()` surface.

## Syncing React with Django

`drf-react-by-schema-django` ships the `sync_react` management command. Add a script to `package.json`, using the Python executable of your virtual environment:

```json
"scripts": {
    "sync-react": "cd ../ && ./venv/bin/python manage.py sync_react"
}
```

Or, with the virtualenv activated:

```json
"scripts": {
    "sync-react": "cd ../backend && python manage.py sync_react"
}
```

It writes the `src/drfReactBySchema/` folder (path configurable through `DRF_REACT_BY_SCHEMA['REACT_APP_DIR']`):

- `schemas/<Model>Schema.json` — one schema per model;
- `types.ts` — TypeScript interfaces and enums for the models;
- `optionsGetters.ts` — label helpers for the generated enums;
- `index.ts` — one `<Model>Schema` loader per model, imported as a single object (`import * as schemas`);
- `pagination.ts` — the `paginationConfig` object.

Import model types from `drfReactBySchema/types` to type your components and data.

---
_Source: https://npm.io/package/drf-react-by-schema · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
