# shadcn-admin-kit assembles an admin panel from components you own

> shadcn-admin-kit is a Marmelab component kit for building an admin application on shadcn/ui, with CRUD pages, a data table, forms, references, auth and a dashboard wired to a data provider. The components live in your repository rather than in a node_modules dependency, and the guessers will print the code for your list, edit and show screens based on what your API returns.

**marmelab/shadcn-admin-kit** — Component kit to build your Admin app with shadcn/ui

- Repository: https://github.com/marmelab/shadcn-admin-kit
- Website: http://marmelab.com/shadcn-admin-kit/
- Stars: 1,133 · Forks: 98
- Language: TypeScript
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/marmelab-shadcn-admin-kit

## A kit, not an application

shadcn-admin-kit is described as a component kit to build your Admin app with shadcn/ui, and that framing is the thing to understand before anything else. It is not a starter you clone and abandon, and it is not a product you install from npm. The components are organized in the src/components/admin directory, with the documentation for each component in its respective file, and they are meant to end up in your codebase.

That follows from how shadcn/ui itself works, and it has a direct consequence for maintenance. The kit is under active development, with releases v2.0.0 on 2026-09-04, v1.6.0 on 2026-06-02 and v1.5.0 on 2026-02-20, and the last push was on 2026-10-05. When a component changes upstream, you merge the change, and you can change it, because it is your file.

The feature list describes what an admin application needs, and the list is conventional for the genre. Working List, Show, Edit and Create pages. A Data Table with sorting, filtering, export, bulk actions, column selection and pagination. Form components with data binding and validation. View and edit references, one to many and many to one. A sidebar menu. Login, auth check and access control, compatible with any authentication backend. A dashboard page. Code scaffolding based on the API response using guessers. i18n support, light and dark mode, responsive and accessible. Compatible with any API, REST or GraphQL, and working with Vite.js, Remix and Next.js.

The stack underneath is stated as well: shadcn/ui and Base UI for the interface, Tailwind CSS for styling, Lucide for icons, React Router for routing, TanStack Query for API calls, React Hook Form for forms and validation, Ra-Core as the admin framework, and TypeScript for type safety.

## The Admin root takes a data provider, and the provider is the contract

The entry point of the application is the Admin component, which configures the application adapters, the routes and the UI. The first thing you supply is a data provider, and the abstraction is what makes the kit API agnostic.

A data provider is described as an abstraction that lets you connect your admin to any API, whether REST, GraphQL or any other protocol. The documentation lists 50 or more data providers, and you can build your own. The example uses a simple REST adapter called ra-data-simple-rest.

```tsx
import { Admin } from "@/components/admin/admin";
import simpleRestProvider from 'ra-data-simple-rest';

const dataProvider = simpleRestProvider('http://path.to.my.api');

export const App = () => (
  <Admin dataProvider={dataProvider}>
    {/* Resources go here */}
  </Admin>
);
```

The Resource component from ra-core is what you use to declare the routes of the application, and the README notes that ra-core was automatically added to your dependencies. Resource takes a name, which maps to the API endpoint, and the list, edit, create and show components to use for it. Custom routes are allowed alongside the CRUD ones.

This is the design decision that determines whether the kit fits your project. Everything else in the application, the list pages, the filters, the forms, the references, is expressed in terms of the data provider contract, so a backend that does not fit that contract is a problem before you write a single screen.

## The guessers print your screens, you paste them in

The feature that most changes the first hour of work is the guessers. If you do not know where to start, you can use the built-in guessers to configure the admin, and they will automatically generate code based on the data returned by your API.

The wiring is small. You create a data provider, pass it to Admin, and declare a Resource with the guesser components in place of real ones.

```tsx
import { Resource } from "ra-core";
import simpleRestProvider from 'ra-data-simple-rest';
import { Admin } from "@/components/admin/admin";
import { ListGuesser } from "@/components/admin/list-guesser";
import { ShowGuesser } from "@/components/admin/show-guesser";
import { EditGuesser } from "@/components/admin/edit-guesser";

const dataProvider = simpleRestProvider('http://path.to.my.api');
```

The output is printed to the console as component code, which you then copy into your own files. The example in the README shows what that looks like for a list.

```jsx
// Example output
Guessed List:

import { DataTable } from "@/components/admin/DataTable";
import { List } from "@/components/admin/List";

export const CategoryList = () => (
    <List>
        <DataTable>
            <DataTable.Col source="id" />
            <DataTable.Col source="name" />
        </DataTable>
    </List>
);
```

The mechanism is worth pausing on. The generated code is a starting point that lives in your repository, not a runtime magic component, so you can edit the table, add a column, change the layout. What you get is the boilerplate of a list view without the boilerplate, and what you give up is any illusion that the screens are automatically correct, because the guesser only knows the shape of the data, not what a user should be able to do with it.

## Auth, dashboard and filters are all props on the same root

The three features that an admin application cannot do without are configured in the same place, through props on Admin.

Authentication uses the authProvider prop. There are many authProviders to choose from, and you can also build your own. Once the authProvider is set up and passed in, the Admin component will automatically display the login page when the user is not authenticated. That last part is the detail that saves work: the login screen is not something you assemble, and the access control and auth check are part of the same provider contract.

The dashboard uses the dashboard prop, and it can be any React component.

```tsx
const Dashboard = () => (
  <div>
    <h1>My Dashboard</h1>
  </div>
);
```

Filtering is done with the filters prop on the List component, and it needs to be an array of input components. The repository contains one such component, the AutocompleteInput, and the documentation covers the rest.

The references deserve a mention too, because they are the feature that separates an admin kit from a table of rows. View and edit references, one to many and many to one, is how you get a list of posts that can show and edit their author, rather than an integer foreign key. That is the kind of detail that either works or does not, depending on how your API models the relationship, and it is worth checking against your own backend early.

## A registry, a Storybook and tests that run in a browser

The repository layout shows what kind of project this is. Alongside src/ there is a .storybook/ directory, a website/ for the documentation site, docs/ for the documentation content, rules/ for lint rules, scripts/ for the build tooling, registry.json, components.json, and an AGENTS.md, a CLAUDE.md and a .agent/ directory.

The registry is the mechanism that makes a component kit installable. There is a build-registry target that runs node ./scripts/build_registry.mjs, a test-registry target that runs ./scripts/test_registry.sh, and a serve-registry target that serves the public directory with python3 -m http.server on port 8080. The registry is where the components are published so they can be pulled into a project.

The test setup is the part that will slow you down on the first run, and it is worth knowing about before you start. The test script is vitest run --browser.headless, and the watch variant is vitest watch --browser.headless. The tests run in a real browser, which means the environment needs Playwright browsers, and there is a Makefile target for exactly that.

```bash
install-browsers:
	@pnpm exec playwright install --with-deps chromium
```

There is also a Storybook on port 6006, a typecheck target that runs tsc --noEmit against tsconfig.app.json, a lint target, and prettier configured with its own apply and check scripts over JavaScript, JSON, TypeScript, CSS, Markdown and HTML.

## Running the demo, the docs and the registry locally

The Makefile is a thin wrapper over pnpm scripts, and it documents the whole development loop of the kit.

```bash
install: package.json ## Install dependencies
	@pnpm install

run:
	pnpm run dev

test:
	pnpm run test

typecheck: ## Run TypeScript type checking
	@pnpm run typecheck
```

The dev server is Vite, and the demo build is tsc -b followed by vite build. The build targets are layered, and the top level build depends on build-website, build-doc, build-demo and build-registry, so a full build produces the documentation site, the docs content, the demo and the registry in one pass. The doc website has its own dev server on port 5174, configured through website/vite.config.ts, and the storybook runs on 6006.

The registry can also be served locally on port 8080, which is how you check the published components before publishing them.

For a team, the practical point is that this is a component library that is developed like an application. There is a demo app to click through, a Storybook to inspect individual components, a browser based test suite, a type check, and a published registry. The cost of that rigour is a heavier setup than a plain copy and paste component, and the benefit is that the components you copy are the ones the project actually tests.

## Ra-Core alone versus the kit, and where the boundary sits

The most useful comparison is with ra-core on its own, since that is the framework the kit is built on and it is already a dependency of your project.

Ra-Core gives you the framework: the resource model, the routing, the data fetching, the auth contract. It does not give you a styled admin interface. The difference in approach is that ra-core asks you to write the screens, while shadcn-admin-kit hands you the screens, built on shadcn/ui and Base UI with Tailwind CSS, and asks you to write the data layer.

That is a much smaller gap to close for most teams, and it is why the kit's own documentation points at ra-core for the resource declaration and the provider contracts. The kit is not a competitor to ra-core, it is the styled layer on top of it, which is also why the components in src/components/admin are structured so you can read them and change them.

The limits are the usual ones of a component kit. It assumes the shape of an admin application, and a product that is mostly an admin interface with a few unusual screens will find that the kit covers the common case well and the unusual case not at all. The guessers help with the common case, and they cannot help with the unusual one.

The licence is MIT, the file is in the repository root, and the project is not archived. The last push was on 2026-10-05, and the newest release is v2.0.0 from 2026-09-04, so the kit is being worked on and shipped at the same time.

## Conclusion

shadcn-admin-kit fits a team that wants an admin interface in its own codebase, styled with shadcn/ui, and that is willing to own the component code it ships. It is the wrong choice if you want a black box admin you install and never touch, since the whole point is that the components live in your repository. Verify first that your API fits the data provider model, since the guessers and the list views are built around it, and plan for the browser based test suite, which needs Playwright browsers installed before vitest can run.

## FAQ

### What is shadcn-admin-kit?

It is a component kit to build an admin application with shadcn/ui, written in TypeScript and MIT licensed. It provides CRUD list, show, edit and create pages, a data table, forms, references, a sidebar, auth, a dashboard, i18n and light and dark mode.

### What is a data provider in shadcn-admin-kit?

It is the abstraction that connects the admin to your API, whether REST, GraphQL or another protocol. The documentation lists 50 or more data providers and you can build your own, and the Admin component takes it through the dataProvider prop.

### How do the guessers work?

The guessers generate code based on the data returned by your API and print the result to the console. You then copy the generated component code into your own files, so the list, edit and show screens become code you own and can edit.

### What do I need to run the shadcn-admin-kit tests?

The test script is vitest run --browser.headless, so the suite runs in a real browser and needs Playwright browsers installed. The Makefile provides an install-browsers target that runs pnpm exec playwright install --with-deps chromium.

### How do I add authentication and a dashboard?

You pass an authProvider prop to the Admin component, and it will display the login page automatically when the user is not authenticated. The dashboard prop accepts any React component, and filtering is done with the filters prop on the List component as an array of input components.

## Sources

- [License: MIT](https://github.com/marmelab/shadcn-admin-kit/blob/main/LICENSE)
- [marmelab/shadcn-admin-kit on GitHub](https://github.com/marmelab/shadcn-admin-kit)
- [Project website](http://marmelab.com/shadcn-admin-kit/)
- [README](https://github.com/marmelab/shadcn-admin-kit/blob/main/README.md)
- [Releases](https://github.com/marmelab/shadcn-admin-kit/releases)

---

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