A fully configurable, production-ready dashboard template.
One config file. Any theme. Ship in minutes.
Quick Start • Features • Configuration • Theming • Deployment • Project Structure
Dashboard-in-a-Box is a single-config dashboard template built with Next.js 16, Tailwind CSS 4, and DaisyUI 5. It's designed to go from zero to deployed dashboard in under five minutes.
Instead of wiring up layouts, sidebars, stat cards, charts, and theme switchers from scratch, you edit one file — dashboard.config.ts — and everything just works. Rename it, rebrand it, point it at your APIs, pick a theme, and deploy.
Built as a derivative of a real production dashboard (Mission Control), battle-tested and opinionated about the things that matter, flexible about the things that don't.
| Dashboard | Analytics | Settings |
|---|---|---|
![]() |
![]() |
![]() |
📸 Screenshots coming soon. Run
npm run devto see it live.
- 🎯 Single Config File — Everything controlled from
dashboard.config.ts - 🎨 10+ Built-in Themes — Cyberpunk, Synthwave, Dracula, Night, and more via DaisyUI
- 📊 Stat Cards — Configurable metric cards with accent colors and optional API endpoints
- 📈 Chart Widgets — Bar, line, pie, area, and donut charts with demo data or live endpoints
- 🔔 Notifications — Bell icon with polling support and unread counts
- 📋 Activity Feed — Real-time event stream with configurable polling
- ⚡ Quick Actions — Customizable action buttons on the dashboard
- 📱 Responsive — Desktop sidebar + mobile bottom navigation, fully responsive layout
- 🌙 Theme Persistence — Selected theme saved to localStorage, survives reloads
- 🔗 External Links — Service links in sidebar footer (GitHub, Docs, etc.)
- 🏗️ Next.js App Router — Built on Next.js 16 with the App Router and React 19
- 🎭 Cyberpunk Fonts — Orbitron + Rajdhani loaded via
next/font - 🔧 TypeScript — Fully typed configuration with exported interfaces
- Node.js 20+ (22 recommended)
- npm 10+
# Clone the repository
git clone https://github.com/your-org/dashboard-in-a-box.git
cd dashboard-in-a-box
# Install dependencies
npm install
# Start development server
npm run devOpen http://localhost:3000 — your dashboard is live.
Open dashboard.config.ts and start editing:
const config: DashboardConfig = {
name: 'MY DASHBOARD',
tagline: 'MISSION CONTROL',
logo: '🚀',
defaultTheme: 'cyberpunk',
// ... everything else
};That's it. Save, and the dashboard updates instantly.
All configuration lives in dashboard.config.ts at the project root. The file exports a typed DashboardConfig object.
| Property | Type | Description |
|---|---|---|
name |
string |
Dashboard name — displayed in sidebar header and browser tab |
tagline |
string |
Short tagline shown under the name |
version |
string |
Version string displayed in UI |
logo |
string |
Logo emoji or text for the sidebar header |
statusText |
string |
Footer status text (e.g., "SYSTEM ONLINE") |
statusSubtext |
string |
Secondary status text (e.g., "NODE: PRIMARY") |
| Property | Type | Description |
|---|---|---|
defaultTheme |
string |
DaisyUI theme ID to use on first load |
themes |
{ id, name, preview }[] |
Available themes in the theme switcher. id is the DaisyUI theme name, name is the display label, preview is a hex color for the swatch |
themeStorageKey |
string |
localStorage key for persisting the user's theme choice |
| Property | Type | Description |
|---|---|---|
nav |
NavItem[] |
Sidebar navigation items |
externalLinks |
ExternalLink[] |
External service links in sidebar footer |
NavItem:
| Field | Type | Description |
|---|---|---|
href |
string |
Route path |
label |
string |
Display text |
icon |
string |
Emoji or text icon |
match? |
string |
Pattern for active state (defaults to href) |
ExternalLink:
| Field | Type | Description |
|---|---|---|
href |
string |
External URL |
label |
string |
Display text |
icon |
string |
Emoji or text icon |
statCards: StatCardConfig[]| Field | Type | Description |
|---|---|---|
id |
string |
Unique identifier |
label |
string |
Card title (e.g., "ACTIVE USERS") |
value |
string |
Display value (e.g., "1,284") |
subtitle |
string |
Description text below the value |
accent |
'cyan' | 'magenta' | 'yellow' | 'green' | 'orange' |
Accent color |
endpoint? |
string |
Optional API endpoint to fetch live value |
jsonPath? |
string |
JSON path to extract value from endpoint response |
charts: ChartWidgetConfig[]| Field | Type | Description |
|---|---|---|
id |
string |
Unique identifier |
title |
string |
Chart title |
type |
'bar' | 'line' | 'pie' | 'area' | 'donut' |
Chart type |
accent |
'cyan' | 'magenta' | 'yellow' | 'green' | 'orange' |
Chart accent color |
endpoint? |
string |
Optional API endpoint for live data |
demoData? |
{ label: string; value: number }[] |
Placeholder data for development/demo |
notifications: NotificationFeedConfig| Field | Type | Description |
|---|---|---|
enabled |
boolean |
Show/hide the notification bell |
endpoint? |
string |
API endpoint returning { data: Notification[], unread_count: number } |
pollInterval? |
number |
Polling interval in milliseconds (default: 30000) |
activityFeed: ActivityFeedConfig| Field | Type | Description |
|---|---|---|
enabled |
boolean |
Show/hide the activity feed |
endpoint? |
string |
API endpoint returning { events: Event[] } |
pollInterval? |
number |
Polling interval in milliseconds (default: 15000) |
layout: WidgetLayoutConfig| Field | Type | Description |
|---|---|---|
statCards |
boolean |
Show/hide the stat cards row |
charts |
boolean |
Show/hide the chart widgets row |
activityFeed |
boolean |
Show/hide the activity feed |
quickActions |
boolean |
Show/hide the quick actions row |
Dashboard-in-a-Box uses DaisyUI for theming. Every DaisyUI theme is supported.
| Theme | Preview |
|---|---|
| Cyberpunk | #ff00ff |
| Dark | #2a303c |
| Night | #0f1729 |
| Synthwave | #e779c1 |
| Dracula | #bd93f9 |
| Luxury | #dca54c |
| Business | #1c4e80 |
| Forest | #1eb854 |
| Black | #000000 |
| Dim | #373d49 |
Add an entry to the themes array in your config:
themes: [
// ... existing themes
{ id: 'retro', name: 'Retro', preview: '#ef9995' },
{ id: 'valentine', name: 'Valentine', preview: '#e96d7b' },
],The id must match a DaisyUI theme name. You can also define custom themes in your CSS — see the DaisyUI docs.
- The default theme is set via
defaultThemein config - The
<html>element getsdata-theme={theme}on load - Users can switch themes via the theme switcher in the top bar
- The selection is persisted to
localStorageunderthemeStorageKey - On next visit, the persisted theme is restored
The template also uses custom CSS variables for fine-grained control:
--dark-bg— Page background--dark-surface— Card/sidebar background--dark-border— Border color
These are defined in src/app/globals.css and can be overridden per-theme.
The fastest path to production:
# Install Vercel CLI
npm i -g vercel
# Deploy
vercelOr connect your GitHub repo to Vercel for automatic deployments on push.
Create a Dockerfile at the project root:
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]Note: For standalone Docker builds, add
output: 'standalone'to yournext.config.ts.
docker build -t dashboard-in-a-box .
docker run -p 3000:3000 dashboard-in-a-boxFor hosting on any static file server (Nginx, S3, GitHub Pages):
-
Add to
next.config.ts:const nextConfig: NextConfig = { output: 'export', };
-
Build:
npm run build
-
Serve the
out/directory with any static host.
Note: Static export disables server-side features (API routes, SSR). All data must come from client-side fetching.
dashboard-in-a-box/
├── dashboard.config.ts # ⭐ The one file you edit
├── src/
│ ├── app/
│ │ ├── layout.tsx # Root layout (fonts, theme, metadata)
│ │ ├── page.tsx # Dashboard home page
│ │ ├── globals.css # Global styles & CSS variables
│ │ ├── analytics/
│ │ │ └── page.tsx # Analytics page
│ │ ├── reports/
│ │ │ └── page.tsx # Reports page
│ │ └── settings/
│ │ └── page.tsx # Settings page
│ └── components/
│ ├── DashboardLayout.tsx # Main layout wrapper
│ ├── Sidebar.tsx # Navigation sidebar
│ ├── StatCards.tsx # Metric stat cards
│ ├── ChartWidgets.tsx # Chart components
│ ├── ActivityFeed.tsx # Activity event feed
│ ├── NotificationBell.tsx # Notification bell + dropdown
│ ├── QuickActions.tsx # Action button grid
│ ├── SubTabs.tsx # Tab navigation component
│ └── ThemeSwitcher.tsx # Theme selection dropdown
├── next.config.ts # Next.js configuration
├── postcss.config.mjs # PostCSS (Tailwind)
├── tsconfig.json # TypeScript config
└── package.json
| Command | Description |
|---|---|
npm run dev |
Start dev server at http://localhost:3000 |
npm run build |
Production build |
npm start |
Start production server |
npm run lint |
Run ESLint |
Contributions are welcome! Here's how:
- Fork the repository
- Create a branch for your feature:
git checkout -b feature/my-feature - Make your changes — follow existing code style and TypeScript conventions
- Test your changes:
npm run build && npm run lint - Commit with a clear message:
git commit -m "feat: add sparkline widget" - Push and open a Pull Request
- Keep
dashboard.config.tsas the single source of truth — new features should be config-driven - Components should be self-contained and read from the config object
- Maintain TypeScript types for all config additions
- Test with multiple DaisyUI themes to ensure compatibility
- Mobile responsiveness is required for all UI changes
We use Conventional Commits:
feat:— New featurefix:— Bug fixdocs:— Documentationstyle:— Formatting, no code changerefactor:— Code restructuringchore:— Tooling, deps, config
| Technology | Version | Role |
|---|---|---|
| Next.js | 16 | React framework (App Router) |
| React | 19 | UI library |
| Tailwind CSS | 4 | Utility-first CSS |
| DaisyUI | 5 | Component library + theming |
| TypeScript | 5 | Type safety |
MIT — do whatever you want with it.
Built with ☕ and questionable amounts of neon.


