docs_headless/src/content/docs/Getting-Started.md
Welcome to ra-core, the headless single-page application framework for React that helps you build admins panels, internal tools, dashboards, ERPs, and B2B Apps, on top of any REST or GraphQL API.
Ra-core provides hooks and components to manage the data fetching, data edition, navigation, security, and internationalization logic that you've probably already implemented several times and that form the base of any single-page application. It glues together powerful React libraries like TanStack Query, react-hook-form, and react-router.
Ra-core has a strong emphasis on relational APIs, and lets you aggregate data from several sources directly in the frontend without the need for complex backend logic.
Ra-core is headless, so it gives you the freedom to build your admin interface with Shadcn UI, Material UI, Ant Design, Chakra UI, Daisy UI, or any custom UI components.
You can use ra-core to:
Ra-core is the base of two popular admin frameworks:
These frameworks themselves are used by thousands of developers worldwide.
if you want to see demos of ra-core in action, check out the following resources:
Ra-core accelerates admin application development by providing:
For a complete feature overview, see our Features Guide.
Install ra-core using npm or yarn:
npm install ra-core
# or
yarn add ra-core
Here's a minimal admin app using ra-core with native HTML5 components:
First, install the JSON Server data provider for the example:
npm install ra-data-json-server
# or
yarn add ra-data-json-server
Then create your app:
// in src/App.tsx
import React from 'react';
import {
CoreAdmin,
Resource,
ListBase,
useListContext,
ReferenceFieldBase,
useRecordContext
} from 'ra-core';
import jsonServerProvider from 'ra-data-json-server';
// Simple TextField component to display user names
const UserNameField = () => {
const record = useRecordContext();
return <span>{record?.name}</span>;
};
// Simple HTML-based List component
const PostList = () => (
<ListBase>
<PostListView />
</ListBase>
);
const PostListView = () => {
const { data, isLoading } = useListContext();
if (isLoading || !data) return <div>Loading...</div>;
return (
<div style={{ padding: '20px', fontFamily: 'Arial, sans-serif' }}>
<h1 style={{ marginBottom: '20px' }}>Posts</h1>
<table style={{
width: '100%',
borderCollapse: 'collapse',
border: '1px solid #ccc',
borderRadius: '8px',
overflow: 'hidden'
}}>
<thead style={{ backgroundColor: 'rgba(0, 0, 0, 0.05)' }}>
<tr>
<th style={{
padding: '12px',
textAlign: 'left',
borderBottom: '2px solid #ccc',
fontWeight: 'bold'
}}>ID</th>
<th style={{
padding: '12px',
textAlign: 'left',
borderBottom: '2px solid #ccc',
fontWeight: 'bold'
}}>Title</th>
<th style={{
padding: '12px',
textAlign: 'left',
borderBottom: '2px solid #ccc',
fontWeight: 'bold'
}}>Author</th>
</tr>
</thead>
<tbody>
{data.map(record => (
<tr key={record.id}>
<td style={{ padding: '8px 16px', borderBottom: '1px solid #ddd' }}>
{record.id}
</td>
<td style={{ padding: '8px 16px', borderBottom: '1px solid #ddd' }}>
{record.title}
</td>
<td style={{ padding: '8px 16px', borderBottom: '1px solid #ddd' }}>
<ReferenceFieldBase
source="userId"
reference="users"
record={record}
>
<UserNameField />
</ReferenceFieldBase>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
const App = () => (
<CoreAdmin dataProvider={dataProvider}>
<Resource name="posts" list={PostList} />
</CoreAdmin>
);
export default App;
Here is the result you should get:
Ra-core provides the foundation; you build the interface. Here's a suggested development path:
Admin Component: Extend CoreAdmin with your branding, global settings, and custom providers. Configure your data provider, auth provider, i18n provider, and global theme settings.
Layout: Create a layout component with navigation, header, and user menu. Your layout wraps all pages and typically includes a sidebar, top bar, breadcrumbs, and main content area. See the Layout documentation for implementation patterns.
Navigation: Build a sidebar or menu using useResourceDefinitions to list available resources and useHasDashboard to conditionally show a dashboard link. Create navigation items with proper routing and active states.
List View: Create list pages with titles and action buttons (like Create). Use ListBase as your foundation and build custom headers with search, filters, and bulk actions. See the List Introduction for step-by-step guidance.
Data Table: Build table components with filtering, sorting, and pagination. Leverage useListContext to access data and state. Implement column sorting, row selection, and responsive design. Consider creating reusable table components for different data types.
Show View: Design detail pages with navigation buttons using ShowBase. Create layouts that display record details clearly, with navigation to edit mode and related resources. Add action buttons for common operations.
Field Components: Create display components like TextField, DateField, NumberField using useFieldValue. Build specialized fields for different data types including email, URL, image, and rich text content. See the Fields documentation for comprehensive examples.
Relational Fields: Build ReferenceField, ReferenceArrayField, ReferenceManyField using their Base counterparts: ReferenceFieldBase, ReferenceArrayFieldBase, and ReferenceManyFieldBase. These handle complex relationships and foreign key displays.
Edit & Create Views: Design form pages with navigation and actions using EditBase and CreateBase. Implement form layouts, validation feedback, and success/error handling. See the Forms Guide for comprehensive form building strategies.
Input Components: Create form inputs like TextInput, DateInput, SelectInput and AutocompleteInput using useInput. Build specialized inputs for different data types including rich text editors, file uploads, and date pickers. See the Inputs documentation for implementation patterns.
Relational Inputs: Build ReferenceInput, ReferenceArrayInput using their Base components: ReferenceInputBase and ReferenceArrayInputBase. These provide autocomplete functionality and relationship management in forms.
Action Buttons: Create SaveButton and DeleteButton components with loading states and custom side effects. Implement optimistic updates, confirmation dialogs, and custom success/error handlers. Use useCreate, useUpdate, and useDelete hooks for data mutations.
Bulk Actions: Add toolbar for bulk operations on list selections. Implement batch delete, export, and custom bulk operations using useListContext for selection state and useUpdateMany for batch operations.
Notifications: Implement toast notifications for errors and undo functionality using useNotificationContext and useTakeUndoableMutation. Create notification components that support different types (success, error, warning) and undoable actions.
Authentication: Design a login page and protected routes using the Authentication system. Implement login forms, password reset, and protected page components using useLogin, useLogout, and Authenticated.
Theme Switching: Add dark/light mode toggles using useStore for persistence. Create theme provider components and implement CSS variable switching or styled-components themes.
Internationalization: Create language switcher components using useLocaleState and useTranslate. Implement translation loading, locale switching, and RTL support. See the Translation Guide for complete i18n implementation.
Error Handling: Customize the error page. Implement global error boundaries and API error handling with user-friendly messages and recovery actions.
Advanced Layouts: Build tabbed forms, filter panels, breadcrumbs, and responsive designs. Create specialized layouts for different screen sizes, implement advanced form patterns like wizard flows, and enhance navigation with breadcrumbs.
This documentation is organized to help you build effectively:
Ready to dive deeper? Start with the General Concepts to understand ra-core's fundamental architecture, then explore the specific areas that match your development needs.
Happy building! 🚀