A frontend Framework for building admin applications running in the browser on top of REST/GraphQL APIs, using ES6, React and Material Design. Previously named admin-on-rest. Open sourced and maintained by marmelab.
Links
Features
Backend Agnostic: Connects to any API (REST or GraphQL, see the list of more than 45 adapters)
All The Building Blocks You Need: Provides hooks and components for authentication, routing, forms & validation, datagrid, search & filter, relationships, validation, roles & permissions, rich text editor, i18n, notifications, menus, theming, caching, etc.
High Quality: Accessibility, responsive, secure, fast, testable
Great Developer Experience: Complete documentation, IDE autocompletion, type safety, storybook, demo apps with source code, modular architecture, declarative API
Great User Experience: Optimistic rendering, filter-as-you-type, undo, preferences, saved queries
Complete Customization: Replace any component with your own
☂️ Opt-In Types: Develop either in TypeScript or JavaScript
Powered by MUI, react-hook-form, react-router, react-query, TypeScript and a few more.
At a Glance
// in app.js
import * as React from "react";
import { render } from 'react-dom';
import { Admin, Resource } from 'react-admin';
import restProvider from 'ra-data-simple-rest';
import { PostList, PostEdit, PostCreate, PostIcon } from './posts';
render(
<Admin dataProvider={restProvider('http://localhost:3000')}>
<Resource name="posts" list={PostList} edit={PostEdit} create={PostCreate} icon={PostIcon} />
</Admin>,
document.getElementById('root')
);
The <Resource>
component is a configuration component that allows to define sub components for each of the admin view: list
, edit
, and create
. These components use MUI and custom components from react-admin:
// in posts.js
import * as React from "react";
import { List, Datagrid, Edit, Create, SimpleForm, DateField, TextField, EditButton, TextInput, DateInput, useRecordContext } from 'react-admin';
import BookIcon from '@mui/icons-material/Book';
export const PostIcon = BookIcon;
export const PostList = () => (
<List>
<Datagrid>
<TextField source="id" />
<TextField source="title" />
<DateField source="published_at" />
<TextField source="average_note" />
<TextField source="views" />
<EditButton />
</Datagrid>
</List>
);
const PostTitle = () => {
const record = useRecordContext();
return <span>Post {record ? `"${record.title}"` : ''}</span>;
};
export const PostEdit = () => (
<Edit title={<PostTitle />}>
<SimpleForm>
<TextInput disabled source="id" />
<TextInput source="title" />
<TextInput source="teaser" options={{ multiline: true }} />
<TextInput multiline source="body" />
<DateInput label="Publication date" source="published_at" />
<TextInput source="average_note" />
<TextInput disabled label="Nb views" source="views" />
</SimpleForm>
</Edit>
);
export const PostCreate = () => (
<Create title="Create a Post">
<SimpleForm>
<TextInput source="title" />
<TextInput source="teaser" options={{ multiline: true }} />
<TextInput multiline source="body" />
<TextInput label="Publication date" source="published_at" />
<TextInput source="average_note" />
</SimpleForm>
</Create>
);