C CoolAdmin v3.3.0

Architecture

CoolAdmin is a Bootstrap 5 + vanilla JavaScript admin template. 35 static HTML pages ship pre-built so end users can clone and open index.html with no Node required. Contributors get a Pug + SCSS source pipeline with a Vite dev server.

Last updated May 22, 2026

CoolAdmin’s design has two distinct audiences:

  1. End users clone the repo and open index.html. The 35 HTML files at the root are real, committed artifacts — they work without npm install.
  2. Contributors edit Pug templates and SCSS partials under src/, then run a build that regenerates those same root *.html and css/*.css files.

Both modes ship together. There is no dist/ directory; the “build artifacts” are the repo.

File layout

CoolAdmin/
├── *.html                       # 35 pages — built artifacts (committed)
│   ├── index.html               # Operations dashboard
│   ├── index2.html              # Sales pipeline
│   ├── index3.html              # Marketing analytics
│   ├── index4.html              # Projects dashboard
│   ├── inbox.html / kanban.html / calendar.html / data-table.html
│   └── …
├── css/
│   ├── theme.css                # Legacy stylesheet (~188 KB, ~12.3k lines)
│   ├── app.css                  # Modern overlay (~188 KB, ~8.5k lines), opt-in via body.app
│   └── font-face.css            # Poppins font-face declarations
├── js/
│   ├── vanilla-utils.js         # jQuery-shaped shim ($, $$, on, ready, …)
│   ├── bootstrap5-init.js       # Tooltips + popovers only (everything else self-instantiates)
│   ├── main-vanilla.js          # Chart configs + sidebar/dropdown/UI behaviors + ⌘K + theme switcher + toast
│   └── modern-plugins.js        # Counters, modern progress bars, lightbox
├── vendor/                      # Bootstrap, Chart.js, FullCalendar, Font Awesome (vendored)
├── images/
├── src/                         # Source for contributors
│   ├── pug/
│   │   ├── layouts/             # _default, _auth, _error
│   │   ├── partials/            # _head, _nav-data, sidebar, header-desktop, footer-scripts
│   │   ├── partials/content/    # Per-page inner HTML (35 fragments)
│   │   └── pages/               # 35 Pug pages — one per route
│   └── scss/
│       ├── theme.scss + 20 ITCSS partials → css/theme.css
│       └── app.scss + 36 partials under app/ → css/app.css
├── scripts/
│   ├── build-pug.js             # Walks src/pug/pages/, renders each to root *.html
│   └── migrate-page.js          # Convert a root HTML file back into Pug (v3.2 migration helper)
├── package.json
└── vite.config.js               # Dev server only — no production bundling

The two-stylesheet system

The most distinctive thing about CoolAdmin v3 is that it ships two complete design systems side by side:

  • css/theme.css — the original CoolAdmin design. Loaded on every page. Wraps everything in standard cascade — no special body class needed.
  • css/app.css — the 2026 modern overlay. Activated by <body class="app">. Establishes a fresh design system (Inter font, brand-blue palette, modern cards, kanban, email reader, theme switcher).

Every demo page in the repo opts in via body.app. If you want the legacy design, remove the class — theme.css keeps working on its own.

The migration story: an existing CoolAdmin v2 user can pull v3.3 and their pages keep their old look because theme.css is unchanged. Adding class="app" to one page lets them try the new design on that page only. Migrating the whole app means setting class="app" on every page.

Script load order

Every page loads scripts at the bottom of <body> in this exact order. Later files depend on globals from earlier ones, so don’t shuffle:

<script src="js/vanilla-utils.js"></script>
<script src="vendor/bootstrap-5.3.8.bundle.min.js"></script>
<script src="vendor/chartjs/chart.umd.js-4.5.1.min.js"></script>
<script src="js/bootstrap5-init.js"></script>
<script src="js/main-vanilla.js"></script>
<script src="js/modern-plugins.js"></script>
  1. vanilla-utils.js must load first — defines globals ($, $$, on, addClass, ready, …) used by every other file
  2. Bootstrap bundle — provides window.bootstrap (modals, dropdowns, collapse — self-instantiated via data-bs-toggle)
  3. Chart.js UMD bundle — note the .umd in the filename. Don’t swap to the ES module build; pages load scripts as classic <script> not modules, and the ES build will throw “Cannot use import statement outside a module”
  4. bootstrap5-init.js explicitly instantiates only tooltips and popovers (those don’t self-instantiate). Everything else uses data-bs-toggle and works without manual init
  5. main-vanilla.js — Chart.js configs, sidebar/dropdown/hamburger UI, ⌘K palette, theme switcher, toast system. Charts use withCanvas(id, fn) guards so the file is safe to include on pages without those canvases
  6. modern-plugins.js — counters, modern progress bars, lightbox

Per-page additions:

  • map.html and index2.html load Leaflet from unpkg.com (CDN, with SRI)
  • calendar.html loads FullCalendar as an additional vendor script
  • chart.html loads no extras — Chart.js is already in the base set

The shell — sidebar + topbar + content

Every default-layout page follows the same skeleton:

<body class="app" data-page="dashboard">
  <a href="#main-content" class="visually-hidden-focusable skip-link">Skip to main content</a>

  <aside class="sidebar">
    <!-- rendered by src/pug/partials/sidebar.pug at build time -->
  </aside>

  <header class="header-desktop">
    <!-- topbar: search, dropdowns, account menu -->
  </header>

  <main id="main-content" class="main-content">
    <!-- page-specific markup -->
  </main>
</body>

The sidebar and topbar render at build time from Pug templates — they’re plain HTML in the final output, not runtime-injected. That means search engines see the full navigation on first paint and there’s no client-side render step.

The sidebar’s active state is set by the Pug build based on each page’s activePage local variable. Edit _nav-data.pug once, every page rebuilds with the new menu.

JS architecture conventions

  • No jQuery. vanilla-utils.js provides a jQuery-shaped shim. Use $, $$, on, addClass, removeClass, slideUp/slideDown, ready instead of writing raw DOM — keeps the existing code idiomatic.
  • No module bundler for JS. Plain <script> tags, globals on window. Vite is dev-only — it serves the static HTML with HMR for SCSS/Pug changes, but doesn’t bundle the runtime JS into chunks.
  • Bootstrap 5 components self-instantiate. Don’t new bootstrap.Modal(el) unless you need programmatic control. The data-bs-toggle attribute pattern is enough.
  • Chart factory pattern. New charts in main-vanilla.js use withCanvas(id, fn) to guard against missing canvases, and reuse sparklineOptions() / lightTooltip / percentTooltip() for shared chart config. See Charts for details.
  • No console.log in shipped code. The v3.0 audit pass stripped all 35 calls; don’t reintroduce them.
  • Font Awesome 7 onlyfa-solid fa-* / fa-regular fa-*. Legacy fa fa-*, fas fa-*, -o suffix, and zmdi-* were all removed.

What was removed in v3.0

The v3.0 audit pass (May 2026) dropped ~260 KB of unused JS per page:

  • AOS — scroll animations, never instantiated
  • Perfect Scrollbar — replaced with native browser scrollbars styled via CSS (the .js-scrollbar1 class is now markup-only and harmless)
  • Swiper — touch sliders, never instantiated
  • Material Iconic Font (zmdi-*) — replaced by Font Awesome 7 across all 353 icon usages
  • 718 obsolete vendor-prefix declarations in CSS — -webkit-border-radius, etc., all dead

theme.css shrank by 33 KB just from the CSS sweep. The remaining -webkit-* rules are all live ones (scrollbars, font-smoothing, placeholder pseudo-aliases).

See also

  • Pug + SCSS pipeline — how the source pipeline works and how to add a new page
  • Theming — design tokens, the body.app overlay, dark mode hook
  • Charts — the Chart.js factory pattern
  • Deployment — shipping the static build