## Tech stack
- **Vite 8** with Rolldown — multi-page app, 58 auto-discovered entry points
- **SCSS** with `@use` modules — no Bootstrap, no framework
- **Vanilla ES2022** — no jQuery, no SPA framework, no build-time JSX
- **Apache ECharts 6** — lazy-imported, modular (only chart types actually used)
- **DataTables.net 2** core — re-skinned from scratch to match the design system
- **Leaflet 1.9** — lazy-imported on the map page only
- **Inter** font from Google Fonts
- **Playwright** (devDep) — for the screenshot pipeline and smoke tests
3 production deps, 9 dev deps, **~178 MB `node_modules`** (was ~600 MB on the old Gentelella).
## Documentation
Full docs live at **** — covering every part of v4:
| Topic | Doc |
| --- | --- |
| Setup, build, deploy | [getting-started](https://gentelella.colorlib.com/docs/getting-started/) |
| Directory layout | [project-structure](https://gentelella.colorlib.com/docs/project-structure/) |
| Shell injection + lazy modules | [architecture](https://gentelella.colorlib.com/docs/architecture/) |
| Tokens, dark mode, theme generator | [theming](https://gentelella.colorlib.com/docs/theming/) |
| Adding pages + sidebar entries | [adding-pages](https://gentelella.colorlib.com/docs/adding-pages/) |
| Component playground | [playground](https://gentelella.colorlib.com/docs/playground/) |
| ECharts factories | [echarts](https://gentelella.colorlib.com/docs/echarts/) |
| DataTables, row selection, CSV | [tables](https://gentelella.colorlib.com/docs/tables/) |
| Inputs, validation, custom controls | [forms](https://gentelella.colorlib.com/docs/forms/) |
| `showModal`, `showToast`, `openMenu` | [overlays](https://gentelella.colorlib.com/docs/overlays/) |
| ⌘K | [command palette](https://gentelella.colorlib.com/docs/palette/) |
| Inbox client | [inbox](https://gentelella.colorlib.com/docs/inbox/) |
| Kanban board | [kanban](https://gentelella.colorlib.com/docs/kanban/) |
| Vite multi-page setup | [vite-build](https://gentelella.colorlib.com/docs/vite-build/) |
| Service worker, manifest, offline | [pwa](https://gentelella.colorlib.com/docs/pwa/) |
| Hosts, subpath, cache headers | [deployment](https://gentelella.colorlib.com/docs/deployment/) |
| IntelliSense via `.d.ts` | [typescript](https://gentelella.colorlib.com/docs/typescript/) |
| Seed vs HTTP backend (`?api=1`) | [data-adapter](https://gentelella.colorlib.com/docs/data-adapter/) |
| Coming from old Gentelella | [migration-v2](https://gentelella.colorlib.com/docs/migration-v2/) |
| Common questions | [FAQ](https://gentelella.colorlib.com/docs/faq/) |
## Quick start
```bash
git clone https://github.com/ColorlibHQ/gentelella.git
cd gentelella
npm install
npm run dev
```
Open [http://localhost:9173/production/index.html](http://localhost:9173/production/index.html). The dev server hot-reloads SCSS, JS, and HTML. Override the port with `PORT=4000 npm run dev`.
### Production build
```bash
npm run build
```
Outputs static HTML + hashed JS/CSS to `dist/`. Deploy the `dist/` folder to any static host (Netlify, Vercel, Cloudflare Pages, S3, GitHub Pages).
To deploy under a subpath (e.g. `https://example.com/admin/`):
```bash
BASE_PATH=/admin/ npm run build
```
### npm package
The package is consumable as an npm dependency for granular imports:
```bash
npm install gentelella
```
```js
import { mountShell, showModal, showToast } from 'gentelella';
import 'gentelella/scss/v4/main.scss';
```
Subpath exports: `gentelella/v4/*` (JS modules), `gentelella/scss/*` (styles), `gentelella/types` (TypeScript declarations).
### Scripts
```text
npm run dev Start Vite dev server (port 9173)
npm run build Production build to dist/
npm run build:dev Non-minified build (debugging)
npm run preview Serve dist/ to preview the production build (port 9174)
npm run analyze Build + open the bundle treemap
npm run new -- Scaffold a new page (see `--help` for flags)
npm run screenshots Boot Playwright + capture 44 PNGs to docs/screenshots/
npm run smoke Boot dev server, hit every page, assert HTTP 200
npm run deploy:preview Build + sync to R2 with per-file cache headers
npm run lint ESLint across src/
npm run format Prettier write across src/
```
## AI-assisted development
Gentelella v4 ships with helper files for the major AI coding tools — drop the repo open in any of them and the assistant gets immediate, accurate context about the architecture, conventions, and recipes:
| Tool | File |
| --- | --- |
| **Claude Code** | [`CLAUDE.md`](CLAUDE.md) |
| **Cursor** | [`.cursor/rules/project.mdc`](.cursor/rules/project.mdc) |
| **GitHub Copilot** | [`.github/copilot-instructions.md`](.github/copilot-instructions.md) |
| **Aider, Cline, Codex, Continue** (and other [agents.md](https://agents.md) tools) | [`AGENTS.md`](AGENTS.md) |
Each file documents the hard rules (vanilla DOM only, single entry point, shell opt-in via body attributes, NAV as one constant, overlay helpers, CSS custom properties for colors, subpath-safe URLs), anti-patterns to avoid, and copy-pasteable recipes for adding pages, charts, modals, and toasts.
## Project layout
```text
src/
├── main-v4.js Entry — mounts shell, initializes charts/tables
├── v4/
│ ├── shell.js Runtime: mobile drawer, theme toggle, dropdowns
│ ├── shell-render.js Pure: nav config + sidebar/topbar/footer HTML
│ ├── charts.js ECharts factories (revenue, sales, donut, …)
│ ├── tables.js DataTables init for [data-datatable]
│ ├── menus.js Popover menus + side panels
│ ├── modal.js Modal dialog system
│ ├── toast.js Toast notifications
│ ├── command-palette.js ⌘K fuzzy search
│ ├── calendar.js Month-grid calendar
│ ├── inbox.js Inbox folder + message list
│ ├── kanban.js Drag-and-drop kanban board
│ ├── file-manager.js Tree + grid file browser
│ ├── form-controls.js Date range, multi-select, rich text
│ ├── settings.js localStorage-backed settings page
│ ├── details.js Project / order / contact detail panels
│ ├── markup.js Pure string helpers for JS-rendered content
│ ├── data-adapter.js Seed + HTTP adapters for backend hydration
│ ├── product-images.js Product gallery zoom
│ └── product-mockups.js SVG product mockups
└── scss/v4/
├── main.scss @use aggregator
├── _tokens.scss CSS custom properties (colors, sidebar, fonts, radii)
├── _layout.scss Sidebar, topbar, main, grid, footer, responsive
├── _components.scss Buttons, cards, tables, status, toggles, progress
├── _forms.scss Inputs, selects, validation, input groups
├── _widgets.scss Stat cards, activity, donuts, sparklines, todos
├── _pages.scss Pagination, alerts, calendar, inbox, invoice, …
├── _datatable.scss DataTables UI overrides
├── _auth.scss Login + error layouts
└── _apps.scss Chat, kanban, file manager, settings
production/ 58 entry HTML pages — one per surface
public/ Static assets copied as-is
dist/ Build output (gitignored)
types/gentelella.d.ts TypeScript declarations
vite.config.js Multi-page Vite config
```
## Customization
### Design tokens
Every color, radius, sidebar dimension, and font setting lives as a CSS custom property in [`src/scss/v4/_tokens.scss`](src/scss/v4/_tokens.scss). Edit `:root`, save, the Vite dev server reloads.
Want a different brand color? Change `--primary` and `--primary-dk`. Every chart, every button, every active nav item updates — ECharts reads these variables at chart-init time.
### Adding a page
The fast way:
```sh
npm run new -- reports --title "Reports" --pretitle "Admin" \
--breadcrumb "Home > Admin > Reports" --nav-group "Admin" --icon "profile"
```
This creates `production/reports.html` with the standard skeleton and (with `--nav-group`) inserts a sidebar entry into the `NAV` array of [`src/v4/shell-render.js`](src/v4/shell-render.js). Vite auto-discovers the new entry — no config change needed. Run `npm run new -- --help` for all options, or use `--dry-run` to preview without writing.
The manual way:
1. Copy any existing page in `production/` (e.g. `profile.html`) as your starting point.
2. Update the ``, `data-page`, and `data-breadcrumb` attributes.
3. Replace the `` content with your markup using the v4 components.
4. Optionally add a new sidebar item by editing the `NAV` array in [`src/v4/shell-render.js`](src/v4/shell-render.js).
The shell auto-marks the matching nav item active based on `data-page`.
### Adding a chart
Add a factory function to [`src/v4/charts.js`](src/v4/charts.js) following the `revenueLine` / `salesBar` pattern, register it in the `charts` map, then drop a `` into any page. Colors come from the design tokens automatically.
### Adding a sortable table
Mark up a regular `
` with `` and ``. The init runs automatically. Use `
` to disable sorting on a column, and `data-page-length="25"` on the table to change the page size.
### Sidebar navigation
The sidebar is rendered from a single source — the `NAV` array in [`src/v4/shell-render.js`](src/v4/shell-render.js). Edit there, every page updates.
### TypeScript / IntelliSense
Type declarations for the public JS surface ship in [`types/gentelella.d.ts`](types/gentelella.d.ts) and are wired up via the `types` field in `package.json`. VS Code resolves IntelliSense automatically — no `tsconfig` required, no rewrite. Covers `mountShell`, `showModal`, `showToast`, `openMenu`, `seedAdapter`/`httpAdapter`, chart/table init, and the `NAV` schema.
### Markup helpers
For pages that build content from data (orders rows, inbox threads, kanban cards), [`src/v4/markup.js`](src/v4/markup.js) exposes pure string-returning helpers — `statTile()`, `statusBadge()`, `customerCell()`, `activityItem()`, `visitorRow()`, `emptyState()`, `banner()`, `skeletonRows()`, plus `escapeHtml()`. Live examples on the [Playground](https://preview.colorlib.com/theme/gentelella/playground.html#helpers-intro). Static pages keep their hand-written HTML — these are for JS-driven content where the boilerplate adds up.
## SEO and metadata
Every page is built with SEO in mind:
- **Semantic HTML5** — ``, `