Sufee admin dashboard: a Bootstrap 5 template with tokens and build-time partials
A simple yet powerful Bootstrap 5 admin dashboard template.
At a glance
- What is it?
- Sufee is a static admin dashboard template on Bootstrap 5.3 with a real design token layer, a dark mode that actually works, and Handlebars partials that are inlined at build time so pages are composed without copy-paste. The v3 release removed around 1,800 lines of legacy code and, more usefully, documented exactly what it removed and why.
- Who is it for?
- Sufee fits a team that wants a static admin front end today and intends to build a real application on top of it, because the token layer and the build-time partials are the two things most templates leave out and this one has.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly HTML, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A template that describes itself as having a design system
The project describes Sufee as a responsive Bootstrap 5.3 admin dashboard template with a real design system, made of layered design tokens, a working dark mode, and build-time partials so you can compose dashboards without copy-paste. The v3 release modernizes the visual language and strips around 1,800 lines of legacy code.
That claim about a real design system is the one to test, because most dashboard templates ship a set of coloured cards and call it a system. Here it has a specific meaning. There are design tokens for radius, shadow, transition and focus ring, and the rule is that you change a value in variables.scss and it updates everywhere, with no more magic numbers. There is a single CSS variable namespace, with the parallel --sufee-*, --color-flat-* and --menu-* declarations removed, so theme colours come from Bootstrap's own --bs-* variables, which are in turn driven by the SCSS $primary and similar variables. Layout keeps its own --sidebar-*, --content-bg and --text-* variables.
So the theming story is a single direction of flow: you change the SCSS variable, the Bootstrap variable changes, the CSS custom property changes, and every component that uses it follows. That is a real system, and it is the difference between a template you can rebrand in an afternoon and one you rebrand by editing forty files.
The cards were modernized alongside this, with rounded corners, a subtle shadow and a hover lift, and no hard border. In dark mode a thin border is added instead, because the documentation explains that shadows fade on dark surfaces and therefore cannot carry elevation on their own. That is a small detail that indicates the dark mode was designed rather than inverted.
The primary language of the repository is HTML, which tells you what this is: pages, not an application framework.
Dark mode that persists and follows the system preference
The dark mode section is short and specific enough to be checked. The header toggle flips the data-bs-theme attribute, the choice persists in localStorage, and by default the template follows the prefers-color-scheme media query.
Following the system preference by default is the correct default, and it is worth contrasting with the common alternative, where the toggle defaults to light and a user with a dark system still sees a light page until they notice a button. The localStorage persistence is the other half, since without it every page load would re-evaluate the system preference and undo a manual choice.
The palette behind it is described as layered slate, with slate-900 for the body, slate-800 for cards and slate-700 for hover states, and the shadows are tinted with black so that they read on dark backgrounds rather than vanishing into them. That last point is the one most themes get wrong. A shadow is a darkening of the surface behind it, and on a dark surface a dark shadow has almost no contrast to work with, so elevation has to come from a border or a lighter surface instead.
Version 3.1.0 of the template was released with the title Design polish: AA contrast and working dark mode, which suggests the dark mode had real work done on it beyond inverting colours, and the release title mentions contrast specifically.
The theme toggle and the palette are only half the story though. The other half is the token layer, because a working dark mode that is not driven by the same variables as the light one is a separate stylesheet, and the next person to touch it will break it.
Build-time Handlebars partials, and a catalog page that documents them
The architectural centre of the project is the partial system, and it is a build-time system rather than a runtime one.
You drop a file into src/components/ and call it from a page with a Handlebars-style include, passing properties such as a colour and a value. The partials are inlined at build time, so there is no runtime fetch. Three partials ship: stat-card, social-card and icon-stat-card.
The distinction from the usual approach matters. The usual approach in a static admin template is that you copy a block of HTML into every page that needs a stat card, and then you have forty copies of the same markup with forty chances to diverge. Build-time partials give you one source, and the build does the copying, so the copies cannot drift.
The documentation for this is unusually well organised. There is a component catalog page at /components-catalog.html where every reusable pattern has a rendered preview, copy-pasteable markup and a props table. That is the difference between a partial system people use and a partial system people avoid because they cannot remember the property names. The catalog is generated from the same partials, so it cannot describe something that does not exist.
The other piece of the architecture is selector-based component loading, where App.COMPONENT_REGISTRY lazy-loads modules when their selector exists in the DOM, with no central data-page switch to maintain. A central switch is the pattern that turns a static site into a maintenance burden, because every new page means editing one file, and merging two feature branches means resolving conflicts in that one file. The registry approach means a component is loaded because its markup is present, which is a property of the page rather than of a switch statement.
And the page model is trivial to extend. The Vite glob-discovered HTML entries mean that dropping a .html file into src/ is enough for it to build.
The data-chart API replaces four hundred lines of Chart.js boilerplate
The chart story is the part of the template most likely to change how you work, and the numbers are striking. A data-chart API replaces around 430 lines of inline Chart.js setup on the demo page.
The mechanism is declarative attributes on a canvas element, with the chart type, labels, values, datasets and colours each supplied as an attribute. The API covers line, bar, pie, doughnut, radar, area, polarArea, horizontal and stacked variants.
Nine chart types from one attribute set, with no configuration object to write per chart, is the sort of API that turns chart usage from a two-minute job into a thirty-second job. It also means the demo pages do not demonstrate Chart.js, they demonstrate Sufee, which is the point of a template.
Chart.js 4.5.1 is the version in the release, and Chart.js remains a dependency rather than something the template reimplements, so the charts are real Chart.js charts and any Chart.js option that the attribute API does not expose is still reachable by writing the configuration yourself.
The rest of the runtime dependencies are the ones a dashboard with a map would need: Leaflet for maps, the Google Maps JavaScript API loader, flag-icons for country flags, and the Font Awesome free set for icons. Bootstrap 5.3.8 and the Open Sans variable font are there too, with the font coming from the fontsource package rather than a Google Fonts link, which is a point the bug fixes section returns to.
The toolchain is Vite 8.2.0 with a Handlebars plugin and a static copy plugin, Sass 1.102.0, ESLint 10.8.0 and Prettier 3.9.6, and the release notes claim zero vulnerabilities for that set.
The bug fix list is the most useful part of the release notes
Most template changelogs list features. This one lists what was broken, and the entries are the kind of detail that tells you what kind of project this is.
The sidebar disappearing after a mobile to desktop resize was caused by inline styles from earlier toggle code outranking the desktop CSS, and the fix is class-only toggles with leftover-style cleanup. Brand colours were not actually applied because main.js was importing the prebuilt Bootstrap CSS after the themed SCSS, so --bs-primary was Bootstrap's own #0d6efd rather than the brand #20a8d8, and the duplicate import was removed.
That second one is the most instructive, because it is a bug that no amount of looking at the SCSS would find. The theme was correctly themed, and the correct theme was being overridden by a later stylesheet load. A developer who checks the variables, sees the right colour, and concludes the template is broken would be wrong, and the fix is one import.
The self-hosted fonts were 1.6KB Google 404 HTML pages saved with .woff2 extensions. That is a specific failure that happens when someone downloads the font files by hand during a build step and the URLs are wrong, and the result is silent, because the browser falls back to a system font. The fix was to replace them with the fontsource-variable/open-sans package, which is now a runtime dependency.
The rest of the list covers a broken logo on auth pages, a confirm() call for logout replaced with a Bootstrap modal, three setTimeout(100) race-condition workarounds replaced with a deterministic await chain, and around 45 ESLint issues cleaned up.
The removal list is similarly specific: about 1,800 lines of dead code including navigation.js, search.js and dom.js, the toast and fetch-interception bloat in error-handler.js, Bootstrap 4 leftovers, unused Vite aliases, a duplicate of the themify-icons package that already existed in the public folder, a rel shortcut icon attribute and the duplicate Bootstrap CSS import.
The auth and error page shells are worth singling out. A body class of auth-page plus .auth-card, .auth-hero and .auth-btn means login, register, forgot password, 404 and 500 all share one shell, and the documentation notes that this took the project from 1,837 lines of duplicated inline CSS to a 303-line shared file. Those are shells, not working authentication, and that distinction matters when you plan around them.
Running the project is npm run dev, and the typecheck script is a placeholder
The package manifest is small enough to take in at a glance, and the scripts describe the whole workflow:
"dev": "vite",
"build": "vite build",
"preview": "vite preview",The build and preview scripts are the standard Vite pair, so the dev server, the production build and a local preview of that build are all the commands you would expect. The lint and format scripts are paired the same way, with a fix variant and a check variant for each, and a quality script that runs the check variants in sequence, plus a quality:fix counterpart.
One line in that manifest deserves attention. The typecheck script is:
"typecheck": "echo 'TypeScript not configured yet'"So despite the presence of a tsconfig file in the repository listing, there is no TypeScript type checking configured, and the script that would do it currently prints a message and exits. That is honest in the sense that it does not pretend, but it does mean the quality gate is lint plus format only.
The manifest also has a small inconsistency worth knowing about. The repository field points at git+ssh://[email protected]/sarangaem/sufee-admin-dashboard.git and the bugs field points at the same account, while the repository itself lives under the puikinsh organisation. The author field credits Aigars Silkalns. This is the kind of drift that happens when a project moves, and it matters if you are going to file an issue, because the bugs URL in the manifest does not match where the code lives.
The package is marked as an ES module project with main set to src/main.js, and it is a private package. The rest of the top level is documentation and configuration: DOCUMENTATION.md, CHANGELOG.md, CONTRIBUTING.md, CLAUDE.md, an eslint config, a prettier config, a .env file, and directories for docs, public assets, screenshots, scripts and src.
The dev dependencies are the build chain rather than a test framework, and there is no test script in the manifest. So the quality story here is lint, format and a browser preview, and the component catalog page is the closest thing to a visual regression suite.
Where a static template stops and an application begins
Three boundaries are worth drawing explicitly.
The first is that this is HTML, CSS and JavaScript with no framework. There is no component binding, no router, no state management and no data layer. The data-chart API is a convenience wrapper over Chart.js, and the component registry is a lazy loader for modules, not a reactivity system. If your requirement is a dashboard that fetches from an API, shows live data, handles routing and has a login, you are writing that layer yourself, and the template saves you the visual work only.
The second is the contrast with the commercial templates promoted alongside it in the README, and the difference in approach is instructive rather than disparaging. TailPanel is React with TypeScript, Tailwind CSS and Vite, with 9 dashboard layouts and a theme toggle built in. Admindek is Bootstrap 5 with vanilla JavaScript, 100 or more components, light and dark modes, RTL and 10 colour presets. Adminty is Bootstrap 5 with 160 or more pages and a broad component library. ArchitectUI is Bootstrap 5 with 250 or more components, a scalable modular design and 9 dashboard views.
Two things follow. Sufee sits at the small end of that spectrum deliberately, with a handful of pages and three partials, and the value is that you can read all of it. And several of the features listed for the paid alternatives, notably RTL support and multiple colour presets, are things Sufee does not have. The theme system in Sufee is a token layer for one palette, not a preset switcher.
The third boundary is maintenance. The licence is MIT, so you can fork and modify freely, but the template is maintained by one author, the README notes the author field credits Aigars Silkalns, and the repository carries a CLAUDE.md, which is a recent convention for repository instructions aimed at coding assistants. If you fork it, you own the Bootstrap 5.3 and Chart.js 4.5 upgrade path, and the release notes show the project does handle major version bumps, with v3.0.2 specifically fixing that a self-hosted Open Sans was never being applied.
The last push to the repository was on 2026-10-17 and the recent releases are v3.2.0 on 2026-09-30, v3.1.0 on 2026-08-03 and v3.0.2 on 2026-08-03. The activity is current, and the CHANGELOG.md is pointed to for complete release notes including breaking changes and migration guidance.
Editorial conclusion
Sufee fits a team that wants a static admin front end today and intends to build a real application on top of it, because the token layer and the build-time partials are the two things most templates leave out and this one has. It is the wrong choice if you want a component framework with data binding, a router and a state layer, because there is no framework here beyond Bootstrap and Chart.js, and it is the wrong choice for a project that needs RTL, a component library in the tens of components, or a Next.js or React implementation. Before adopting it, read CHANGELOG.md for the breaking changes and migration guidance in v3, check the typecheck script, which currently only echoes that TypeScript is not configured yet, and confirm that the auth and error page shells are shells rather than working authentication before you build a login flow on top of them.
Frequently asked questions
What is the Sufee admin dashboard template?
It is a responsive Bootstrap 5.3 admin dashboard template built with Vite, with layered SCSS design tokens, a dark mode that toggles data-bs-theme and persists in localStorage, build-time Handlebars partials and a Chart.js data-chart API. The licence is MIT and the current release is v3.2.0.
How do I add a new page to the Sufee template?
You drop a .html file into src/ and it builds, because the Vite HTML entries are glob-discovered. Reusable patterns are Handlebars partials in src/components/, inlined at build time with no runtime fetch, and the component catalog page at /components-catalog.html documents each one with a preview, copy-paste markup and a props table.
How does the Sufee template handle charts?
A data-chart API on the canvas element covers line, bar, pie, doughnut, radar, area, polarArea, horizontal and stacked variants, replacing around 430 lines of inline Chart.js setup on the demo page. Chart.js 4.5.1 remains a dependency, so any option the attribute API does not expose is still reachable by writing the configuration directly.
Does the Sufee template include working authentication?
It includes auth and error page shells rather than a working authentication system. A body class of auth-page plus shared classes such as .auth-card, .auth-hero and .auth-btn let login, register, forget password, 404 and 500 pages share one stylesheet, which replaced 1,837 lines of duplicated inline CSS with a 303-line shared file.
What changed in Sufee v3.0?
v3.0 introduced the design token layer, the single CSS variable namespace with theme colours coming from Bootstrap's --bs-* variables, build-time Handlebars partials, a component catalog page, selector-based component loading and the data-chart API, while removing around 1,800 lines of legacy code including Bootstrap 4 leftovers and duplicate imports.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/puikinsh-sufee-admin-dashboard)Was this useful?