Refine
React framework for building internal tools and admin panels
Refine is an open-source React-based framework for rapidly building CRUD-heavy applications such as admin panels, dashboards and internal tools. The resulting apps are self-hosted on your own infrastructure.
Key features
- Headless React framework
- CRUD scaffolding
- Many backend connectors
- Auth and access control
Pros & cons
Strengths
- Rapid CRUD scaffolding
- Backend-agnostic data providers
- Works with any UI kit
Trade-offs
- React knowledge required
- Abstraction learning curve
Refine replaces
Last reviewed Aug 26, 2026 · 938 words
Refine does not run anywhere. There is no container to start, no port to publish, no admin login to change. It is a React framework you build an admin panel with, and what you end up self-hosting is a folder of static files plus whatever database or API the panel talks to. If you came here expecting a Retool-shaped server you could docker compose up, that is Appsmith or Budibase, and you can stop reading. If you are (or have) a React developer and want internal tools you own completely, Refine is the fastest route I know to a CRUD app that does not embarrass you 6 months later.
Headless means hooks, not components
Refine's core is a set of hooks: useList, useOne, useCreate, useUpdate, useDelete, useForm, useTable, plus a router-agnostic notion of "resources". It ships no visual components of its own. You pick a UI kit (Ant Design, Material UI, Mantine, Chakra, or a shadcn-style Tailwind setup) and Refine supplies pre-wired integrations for each, so a list page with sorting, filtering and pagination is a few dozen lines instead of a few hundred. Because the hooks hold the data logic, you can swap the UI kit later without rewriting the app. That is the strongest argument for choosing it over a hand-rolled admin, and it is also the "abstraction learning curve" in the cons column: you spend the first week learning Refine's conventions before you get faster than plain React.
The other half is the data provider, a small interface (getList, getOne, create, update, deleteOne, getMany, custom) that Refine calls instead of talking to your backend directly. Providers exist for plain REST, GraphQL, Hasura, Strapi, Supabase, Appwrite, Airtable and NestJS CRUD among others. For a self-hoster the two that matter are simple-rest against an API you already have, and the Supabase provider when you want Postgres, auth and row-level security in one container.
Where it sits: database, API, static bundle
Three layers. A database you already run. An API in front of it with authentication (a self-hosted Supabase, PocketBase with a community provider, or your own Express or FastAPI service). Then the Refine build, served as plain files. npm create refine-app@latest scaffolds a Vite project, npm run build produces dist/, and Caddy serves it with a client-side-routing fallback:
admin.example.com {
root * /srv/refine/dist
try_files {path} /index.html
file_server
}
The 256 MB the catalogue lists is the Node build step, not runtime. The served bundle costs your web server nothing it was not already spending. If you prefer everything in Docker, a two-stage Dockerfile that builds on node:20-alpine and copies dist/ into an nginx or Caddy image is 10 lines and produces a 50 MB image.
The 30 lines that replace a Retool page
A resource declaration plus one list component is a working table with server-side pagination:
import { Refine } from "@refinedev/core";
import dataProvider from "@refinedev/simple-rest";
export default function App() {
return (
<Refine
dataProvider={dataProvider("https://api.internal.example.com")}
resources={[
{ name: "orders", list: "/orders", show: "/orders/:id", edit: "/orders/:id/edit" },
]}
/>
);
}
Inside the list route, useTable() returns rows, total count, current filters and sorters, and setters for each; wire them to your UI kit's table and you are done. simple-rest expects GET /orders?_start=0&_end=10&_sort=id&_order=desc by default, so if your API paginates differently you override two methods in the provider rather than fighting the framework. This is where Refine earns its place against Retool: the result is ordinary TypeScript in git, with tests, code review and a CI build, instead of JSON in someone else's cloud.
Auth and access control are yours to wire
Refine gives you two more interfaces and no opinions. The authProvider implements login, logout, check, getIdentity and onError; the accessControlProvider implements a single can({ resource, action }) and Refine calls it before rendering buttons and routes. For a home or small-team deployment the sane pattern is to put the whole bundle and the API behind your existing identity provider at the reverse proxy, then have the authProvider read the session the proxy established. That keeps one login for the entire lab and means Refine never sees a password. Role checks belong in the API regardless; the accessControlProvider hides buttons, it does not enforce anything.
When NocoDB or Appsmith is the better answer
Nobody without React should pick Refine, full stop. If the goal is one person editing rows in a database, NocoDB gives you a spreadsheet over Postgres in a single container with zero code. If a non-developer needs a form-and-table tool with a few buttons, Appsmith's drag-and-drop editor gets there in an afternoon. Refine wins when the tool will live for years, has more than 3 or 4 screens, needs custom logic that a low-code builder would fight, or must be tested and deployed like any other application. At 35,000 stars and MIT licensed, it is also the option with the least vendor risk: the framework is a dependency in your package.json, and if the company behind it vanished tomorrow your build would still run.
What I'd do
A developer with 2 or more internal tools to build: Refine with Ant Design and the Supabase or simple-rest provider, built in CI, served by Caddy behind the same SSO as everything else. Anyone else: NocoDB first, Appsmith second, and only reach for Refine when one of those starts fighting you.
Compare Refine
6 head-to-head comparisons.
Similar developer tools & git apps
Excalidraw
Developer Tools & GitVirtual hand-drawn style whiteboard
Replaces Miro
lazygit
Developer Tools & GitSimple terminal UI for Git commands
Replaces GitKraken, Sourcetree
Hoppscotch
Developer Tools & GitOpen-source API development ecosystem
Replaces Postman, Insomnia
json-server
Developer Tools & GitFull fake REST API from a JSON file in seconds
Replaces Mockoon, Postman Mock
Strapi
Developer Tools & GitLeading open-source headless CMS
Replaces Contentful
NocoDB
Developer Tools & GitOpen-source Airtable alternative
Replaces Airtable