# Refine: a data and routing layer for React CRUD work

> Refine is a React meta-framework aimed at admin panels, dashboards and internal tools, where data handling, routing and access control are shared across whatever UI library you pick. It pays off when many resources and several roles need consistent wiring, and it costs you when you expected a finished interface on the first commit.

**refinedev/refine** — A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.

- Repository: https://github.com/refinedev/refine
- Website: https://refine.dev
- Stars: 35,730 · Forks: 3,220
- Language: TypeScript
- License: MIT
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/refinedev-refine

## One command starts a project, and no package is called refine

Every route into the framework starts with a single scaffold command, and a browser playground plus the AI agent at refine.dev are two other doors into the same code.

```sh
npm create refine-app@latest my-refine-app
```

One detail is worth catching on day one: nothing here publishes under the bare name refine. The root package.json is called refinedev, is flagged private, and sits at version 0.0.0, and every import in the documentation carries an @refinedev scope. So refine is not something you pull in with npm install refine. It is a family of scoped packages, the scaffolder picks a set for you, and that set becomes the part of your dependency list you have to keep an eye on from then on.

## Headless means the shell is three props, and one of them is cut off

The published Quick Start compresses an entire application into one Refine element fed by three props.

```tsx
import React from "react";
import { Refine, useMany } from "@refinedev/core";
import { ThemedLayout } from "@refinedev/mui";
import dataProvider from "@refinedev/simple-rest";
import routerProvider from "@refinedev/react-router";
import { BrowserRouter, Outlet, Route, Routes } from "react-router";

import CssBaseline from "@mui/material/CssBaseline";

export default function App() {
  return (
    <BrowserRouter>
      <CssBaseline />
      <Refine
        dataProvider={dataProvider("https://api.fake-rest.refine.dev")}
        routerProvider={routerProvider}
        resources={[
```

Because the resources array stops mid-expression, the honest reading is that the framework hands you transport and a route table while you supply the pages that render them. The imports show the split plainly: dataProvider arrives from @refinedev/simple-rest already bound to a URL, routerProvider comes from @refinedev/react-router as a bare value, ThemedLayout is pulled from @refinedev/mui, and CssBaseline comes straight from @mui/material. That separation is the design, and it is why the same shell can sit behind a Mantine layout, a Chakra layout or your own Tailwind markup without the data code changing.

## One data provider at a time, drawn from thirteen named backends

The feature list names connectors for REST, GraphQL, NestJs CRUD, Airtable, Strapi, Strapi v4, Supabase, Hasura, Appwrite, Nestjs-Query, Firebase, Sanity and Directus, and rounds that up to 15+ backend services. The duplicate-looking entry is the informative one: strapi and strapi-v4 are separate packages under packages/, so a team on Strapi has to know which major version its server runs before it picks anything. A Refine application takes a single dataProvider, which makes this a decision made at the start of a project rather than a setting you can revisit later. The scaffolded example points at https://api.fake-rest.refine.dev, a public demo host, which is fine for the first hour and wrong for anything you intend to keep.

## Access control and auth live in examples/, not in a documented package list

Authentication, access control, routing, networking, state management and i18n are the six concerns the project names as its own responsibility, yet the tree gives you no obvious first-class entry point for two of them. Under examples/ sit access-control-casbin, access-control-cerbos, access-control-permify and accessControl, next to authProvider, authentication, auth-headless, auth-otp, auth-keycloak, auth-auth0, auth-google-login, auth-kinde, auth-mantine, auth-mui, auth-material-ui, auth-antd and auth-chakra-ui. Those are complete applications you can read, not adapters the Quick Start imports. The consequence is concrete: a team that needs Casbin enforcement or OTP sign-in is expected to open a directory of examples and reconstruct the wiring, and the README does not document a single canonical way to do it.

## The routing layer is React-router shaped, and no Node version is stated

The feature list advertises advanced routing with any router library of your choice, and the use case section names Next.js, Remix, React Native and Electron as platforms. What the snippet actually shows is the React Router shape: BrowserRouter, Outlet, Route and Routes imported from react-router, with routerProvider passed beside it. Moving to another platform means implementing the same provider interface against a different host, and only the React Router implementation appears in code anyone is given to copy. The README also states no minimum Node version, no browser support table and no required package manager for consumers, even though the repository itself runs on pnpm workspaces with pnpm-lock.yaml. If your CI pins an old Node release, the scaffolder will not stop you before you find out.

## Auto-generated CRUD views depend on a resources array the snippet never finishes

Two advertised capabilities go undemonstrated in the one place they are supposed to appear. The feature list promises auto-generation of CRUD interfaces from your API data structure, and the use case section claims built-in SSR support with Next.js and Remix. The documented snippet exercises neither: it ends inside the resources prop and wraps everything in BrowserRouter, a client-side router. Taken literally, a developer who copies it ends up with a browser router pointed at a public demo API and an empty resource list, and both route generation and screen generation have nothing to work from. Nothing in the code warns you that entries are missing, and the only record of the finished result in the file is a link to a preview image. The rest has to come from the tutorial and the guides, not the README.

## Three packages, three unrelated major numbers, and a main branch ahead of every release

Recent releases do not line up. @refinedev/core is at 5.0.12 from 2026-04-02, @refinedev/mui is at 8.0.2 from 2026-03-23 and @refinedev/devtools is at 2.0.5 from 2026-03-16, so the framework has no single version number you can quote, pin or attach to a bug report. The default branch received a push on 2026-09-10, close to five months past the newest of those three releases, meaning the published packages sit behind main by a margin npm will not show you. Devtools is the sharpest version of that gap: it is promoted as a headline feature that dives into your app and gives useful insights, and the file never says how to install it, when to enable it, or what it actually inspects. The project is not stalled, but its release trail is uneven.

## Contributing means pnpm, lerna, nx, biome and a script that deletes the lockfile

The repository root is a workspace, and its scripts describe the contributor loop in full. The default build is lerna run build --scope @refinedev/core, which touches one package, so anyone editing an adapter outside core needs the wider lerna run build --scope @refinedev/* --scope create-refine-app. Linting runs biome check . rather than eslint, commits are gated by commitlint and husky, versions move through .changeset/, and end to end work uses cypress run -C cypress/cypress.config.ts --browser chrome. One script deserves caution: nuke:lockfiles deletes package-lock.json, yarn.lock and pnpm-lock.yaml across the packages, and coffee chains that with a clean install and the wide build. The lockfile is disposable by design here, which is convenient for maintainers and a hazard for anyone who needs reproducible local resolution.

## Conclusion

For a team building an admin panel over REST or GraphQL with several roles to keep straight, the provider model removes a lot of repeated wiring and the templates page shows the target. It is the wrong choice if you need a non-React stack, a complete interface on day one, or a single version number to pin. Before committing, check how the resources array shapes your routes, plan to copy access control out of examples/ rather than a documented package, and confirm that the Devtools you saw advertised is the one published at 2.0.5.

## FAQ

### How do I install refine?

The project documents scaffolding a new app with npm create refine-app@latest my-refine-app, or generating one in the browser at refine.dev/core/?playground=true. There is no bare refine package; the imports in the example come from @refinedev/core, @refinedev/mui, @refinedev/react-router and @refinedev/simple-rest.

### Does Refine work outside React?

Everything shown is React: the Quick Start is a .tsx file importing BrowserRouter, Outlet, Route and Routes from react-router, and the project describes itself as a React meta-framework written in TypeScript. The named host platforms are Next.js, Remix, React Native and Electron, all reached through a React routing interface.

### Which backend does the starter example talk to?

The snippet wires dataProvider to https://api.fake-rest.refine.dev through @refinedev/simple-rest, which is a public demo API rather than your own server. You replace it with a connector for your backend, of which the feature list names thirteen plus others counted as 15+.

### How is access control configured in Refine?

The README names access control as one of the concerns the hooks and components cover, but it does not document a single canonical configuration. The tree ships full examples instead, including access-control-casbin, access-control-cerbos, access-control-permify and accessControl, which you read and adapt rather than install.

### Is the Refine Devtools package something I have to install separately?

The README lists Refine CORE Devtools as a key feature and gives no install or activation steps, so the file never settles the question. The package is published separately as @refinedev/devtools, released at 2.0.5 on 2026-03-16, which is a different major number from @refinedev/core and @refinedev/mui.

## Sources

- [Official documentation](https://refine.dev)
- [Official README](https://github.com/refinedev/refine#readme)
- [Project repository](https://github.com/refinedev/refine)
- [Release notes](https://github.com/refinedev/refine/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/refinedev-refine
