Free, MIT-licensed React admin template based on Bootstrap 5.
npm run dev: dev server on http://localhost:5173npm run build: production build intodist/;npm run previewserves itnpm run lint: ESLint, Prettier,tscand the stats check; must passnpm test: Playwright smoke and axe tests ondist/(build first;npm run test:installonce)npm run format: Prettier writenpm run stats: regeneratesrc/data/stats.jsonand the README counts
- React 19, Vite 8, React Router 8 (declarative, single-page app), strict TypeScript. Mock data, no server.
BASE_PATHsets a base path (vite.config.ts). - One file per page in
src/routes, named after its URL (index.tsxis/). Every page is listed insrc/data/pages.jsonwith its title, description and layout (dashboardorauth);src/app.tsxbuilds the routes from it, andsrc/layouts/page-meta.tsxsets the document title. - Structure:
src/routesholds only the pages;src/layoutsthe dashboard and auth layouts;src/componentsthe shared parts (bootstrap,plugins,navbar,sidebar,ui) and, underpages/<section>/<page>/, what only one page uses;src/mocksdemo data;src/dataapp data (pages, navigation, stats). src/components/bootstrapreplaces Bootstrap's JavaScript with React components on Bootstrap's markup (Alert,Dropdown,Modal,Offcanvas);src/components/pluginswraps the plugins;src/scssis AdminKit's Sass, with the plugin overrides in5-vendor.- The script in
index.htmlruns before the first paint (color mode, the hidden state of the cards that fade in); it must not import anything.
- Only CSS custom properties get a prefix:
--ak-*, like Bootstrap's--bs-*. Classes, Sass variables, functions, mixins and data attributes never do. - Never query or change the DOM React renders; keep it in state.
- No Bootstrap JavaScript, no react-bootstrap, no Tailwind. Plugins that need the browser load in
useEffectwithimport(), or withReact.lazy, and show aSkeletonuntil they draw. - Light and dark mode:
data-bs-themeon<html>. Change the mode only throughuseColorMode(src/lib/config.ts). Colors that follow the mode use custom properties (var(--bs-body-color),var(--ak-surface-bg)); dark-only overrides go in@include color-mode(dark) { ... }at the end of the partial. Check both modes. - Charts and maps read colors from the
themeargument:<ChartJs config={(theme) => ...} />,<VectorMap options={(theme) => ...} />. - Icons are
lucide-reactcomponents (circle-check-bigis<CircleCheckBig />). Images are<img>withwidth,heightandsrc={asset("/img/...")}, so the base path applies. - Counts come from
src/data/stats.json, and AdminKit PRO's fromsrc/data/editions/pro.json(a snapshot); a page description writes them as{icons.lucide}. Never type a count by hand. A new dependency goes insrc/data/plugins.json, as a plugin or innotPlugins, or lint fails. - Motion: write transitions with
@include transition(...); under reduced motion nothing moves (a fade is fine). Cards inside.reveal-cardsand.revealelements fade in on scroll without extra code (PageEffects,data-revealed). - Layout shift stays 0: reserve the final size of anything a script draws, give images
widthandheight. - Accessibility: WCAG 2.2 AA in both modes, no console errors (
npm test). Text colors come fromreadable($color, $background), text on a fill fromtext-on($background). Icon-only buttons get anaria-label; card titles areh2.card-title.
- Conventional Commits, see
CONTRIBUTING.md; lefthook enforces them. - A PR that changes behaviour adds a short, user-facing line under
UnreleasedinCHANGELOG.md, like "Add pricing page (/pages-pricing)" or "Upgrade dependencies".