This document explains when to use shadmin vs @mdxui/admin and how to migrate existing React Admin applications.
Use this decision tree to pick the right package:
┌─────────────────────────────┐
│ Are you building an admin │
│ dashboard UI? │
└─────────────┬───────────────┘
│
YES
│
┌─────────────▼───────────────┐
│ Do you have an EXISTING │
│ react-admin application? │
└─────────────┬───────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
YES │ NO
│ │ │
▼ │ ▼
┌─────────────────┐ │ ┌─────────────────┐
│ shadmin │ │ │ @mdxui/admin │
│ (this package) │ │ │ │
└────────┬────────┘ │ └────────┬────────┘
│ │ │
▼ │ ▼
• Drop-in replacement │ • Zero ra-core deps
• Keep ra-core hooks │ • TanStack Query native
• Same DataProvider API │ • Maximum flexibility
• Minimal code changes │ • Smaller bundle size
│
┌─────────────▼───────────────┐
│ Do you need react-admin's │
│ API compatibility? │
└─────────────┬───────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
YES │ NO
│ │ │
▼ │ ▼
┌─────────────────┐ │ ┌─────────────────┐
│ shadmin │ │ │ @mdxui/admin │
│ (API compat) │ │ │ (fresh start) │
└─────────────────┘ │ └─────────────────┘
| Scenario | Package | Why |
|---|---|---|
| New project, no react-admin | @mdxui/admin |
Smaller bundle, no legacy patterns |
| Migrating from react-admin | shadmin |
Drop-in UI replacement |
Want useRecordContext etc. |
shadmin |
Re-exports ra-core hooks |
| Using TanStack Query natively | @mdxui/admin |
No ra-core abstraction layer |
| Need DataProvider abstraction | shadmin |
Compatible with react-admin DataProvider |
| Building with dotdo platform | @mdxui/admin |
Native TanStack integration |
Choose shadmin if you:
- Have an existing React Admin application you want to modernize
- Need drop-in compatibility with ra-core hooks and data patterns
- Want to incrementally migrate without rewriting business logic
- Require React Admin's ResourceContext and record/resource conventions
- Use React Admin's DataProvider/AuthProvider abstractions
Choose @mdxui/admin if you:
- Are starting fresh with no React Admin codebase
- Want zero ra-core dependency (cleaner bundle, no legacy patterns)
- Prefer TanStack Query native patterns over React Admin's hooks
- Need maximum flexibility in data layer integration
- Are building with the dotdo platform (@dotdo/react/tanstack)
| Aspect | shadmin | @mdxui/admin |
|---|---|---|
| ra-core dependency | Yes (via facade) | No |
| Hook API | useRecordContext, useResourceContext |
TanStack Query native |
| Data Provider | React Admin DataProvider | Any (TanStack Query) |
| Migration effort | Low (drop-in) | Higher (rewrite hooks) |
| Bundle size | Larger (includes ra-core) | Smaller |
| Long-term direction | Migration path to native | Native from start |
shadmin provides ShadCN-styled versions of all React Admin UI components while maintaining ra-core compatibility.
// Before: React Admin with Material UI
import { List, Datagrid, TextField, EditButton } from 'react-admin'
// After: shadmin with same API
import { List, Datagrid, TextField, EditButton } from 'shadmin'What changes:
- Visual appearance (Material UI → ShadCN/Tailwind)
- Underlying primitives (MUI → Radix)
What stays the same:
- All ra-core hooks work identically
- DataProvider/AuthProvider contracts
- Resource routing and conventions
If you want to eventually remove ra-core dependency, shadmin's facade pattern supports gradual migration:
// shadmin exports these from ra-core today
import { useRecordContext, useResourceContext } from 'shadmin'
// Future: shadmin can swap to native implementations
// Your code doesn't changeFor teams wanting zero ra-core:
- Replace
shadminimports with@mdxui/admin - Swap ra-core hooks for TanStack Query patterns
- Remove DataProvider, use direct API calls with TanStack
shadmin uses a controlled facade over ra-core, exposing only these exports:
useResourceContext- Get current resource nameuseRecordContext- Get current recorduseListContext- Access list data, pagination, selectionuseEditContext- Access edit context (record, save)useCreateContext- Access create context
useCreatePath- Create paths for resource routesuseRedirect- Programmatic navigationuseRefresh- Refresh current view data
useDataProvider- Access DataProvider instanceuseDelete- Delete single recorduseDeleteMany- Delete multiple records
useUnselectAll- Clear list selection
useGetIdentity- Get current user identityuseLogout- Log user out
EditBase- Headless edit controllerShowBase- Headless show controllerCreateBase- Headless create controller
ResourceContext- Resource context objectResourceContextProvider- Provider component
fetchRelatedRecords- Fetch related records for export
Identifier,RaRecord,SortPayload,FilterPayloadDataProvider,AuthProvider,UserIdentityListControllerResult,Exporter,MutationModeResourceDefinition
shadmin is a git submodule in the mdxui monorepo, ensuring:
- Isolation - ra-core dependencies are contained within shadmin
- Zero leakage - No ra-core imports exist outside packages/shadmin
- Independent versioning - shadmin can release independently
- Clean separation - mdxui ecosystem remains ra-core-free
projects/ui/
├── packages/
│ ├── admin/ # @mdxui/admin - pure UI, no ra-core
│ ├── primitives/ # @mdxui/primitives - base components
│ ├── shadmin/ # ← git submodule (owns ra-core)
│ │ └── packages/
│ │ └── shadmin/
│ │ └── src/
│ │ └── facade/
│ │ └── ra-core.ts # Controlled facade
│ └── ...
- shadmin issues: https://github.com/dot-do/shadmin/issues
- mdxui issues: https://github.com/dot-do/ui/issues
- React Admin docs: https://marmelab.com/react-admin/documentation.html