binczakmartin/nuxt-boilerplate
Production-ready Nuxt 4 starter with JWT auth, PostgreSQL/Drizzle, and full Docker Compose stack.
Nuxt 4 Boilerplate
A modern, production-ready Nuxt 4 boilerplate with authentication, dashboard navigation, and a clean dark theme design system.
๐ณ Docker Ready: Full Docker support with PostgreSQL and Adminer. See DOCKER.md for complete guide.
โจ Features
๐จ Modern Design System
- Dark Theme: Professional dark color scheme with purple gradient accents
- Responsive: Mobile-first design that works on all screen sizes
- Customizable: Centralized theme configuration in
/config/theme.ts - Smooth Animations: Polished micro-interactions and transitions
๐ Authentication System
- JWT-based: Secure authentication with HTTP-only cookies
- Protected Routes: Middleware-based route protection
- Login/Register: Pre-built authentication pages
- User Management: Profile and logout functionality
๐งญ Advanced Navigation
- Public Navbar: Clean marketing navbar with mobile drawer
- Dashboard Sidebar: Professional sidebar with nested menu support
- Config-Driven: Easy to add/remove menu items via configuration
- Auto-Active States: Highlights current route and auto-expands parent items
- Mobile Optimized: Drawer pattern for mobile navigation
๐ ๏ธ Technical Stack
- Nuxt 4: Latest Nuxt with all modern features
- Vue 3: Composition API with
<script setup> - TypeScript: Fully typed codebase
- Nuxt UI: Beautiful UI components
- Drizzle ORM: Type-safe database queries
- PostgreSQL: Production-ready database
- Tailwind CSS: Utility-first styling
๐ฆ Component Library
- Modular Components: Reusable UI components in
/components/ui/ - Layout Components: Navigation and layout components
- Auth Components: Authentication-specific components
- Demo Pages: Example dashboard pages with nested routes
๐ Quick Start
Prerequisites
- Node.js 22+
- pnpm (recommended) or npm
- Docker & Docker Compose (for Docker setup)
Option 1: Local Development
Installation
- Clone the repository
git clone <your-repo-url>
cd nuxt-boilerplate- Install dependencies
pnpm install- Set up environment variables
cp .env.example .envEdit .env and configure:
DATABASE_URL="postgresql://postgres:postgres@localhost:5433/nuxt_boilerplate"
JWT_SECRET="your-super-secret-jwt-key-change-this"- Start PostgreSQL with Docker
docker compose up postgres -d- Run database migrations
pnpm db:push- Start development server
pnpm devOpen http://localhost:3000 in your browser.
Option 2: Full Docker Setup ๐ณ
Run the entire application stack (App + PostgreSQL + Adminer) with Docker:
- Clone and configure
git clone <your-repo-url>
cd nuxt-boilerplate
cp .env.example .env- Build and start all services
docker compose up --buildThis will start:
- App: http://localhost:3000
- Adminer (Database UI): http://localhost:8080
- PostgreSQL: localhost:5433
- Access Adminer
Open http://localhost:8080 and login with:
- System: PostgreSQL
- Server: postgres
- Username: postgres
- Password: postgres
- Database: nuxt_boilerplate
- Stop services
docker compose down- Stop and remove volumes (clears database)
docker compose down -vDocker Commands
# Start only database and Adminer
docker compose up postgres adminer -d
# Start only the app (requires DB running)
docker compose up app
# View logs
docker compose logs -f app
# Rebuild app after code changes
docker compose up --build app
# Execute commands in running container
docker compose exec app pnpm db:push
docker compose exec app sh๐ Project Structure
nuxt-boilerplate/
โโโ components/
โ โโโ layout/ # Navigation components
โ โ โโโ AppNavbar.vue
โ โ โโโ DashboardSidebar.vue
โ โ โโโ DashboardMenuItem.vue
โ โ โโโ MobileDrawer.vue
โ โโโ ui/ # Reusable UI components
โ โ โโโ UiButton.vue
โ โ โโโ UiCard.vue
โ โ โโโ UiInput.vue
โ โโโ auth/ # Auth-specific components
โ โโโ AuthWrapper.vue
โ โโโ AuthPanelContent.vue
โ โโโ AuthFormHeader.vue
โ
โโโ pages/
โ โโโ index.vue # Landing page
โ โโโ login.vue # Login page
โ โโโ register.vue # Register page
โ โโโ dashboard/ # Dashboard pages
โ โโโ index.vue
โ โโโ settings.vue
โ โโโ analytics/
โ โโโ users/
โ
โโโ server/
โ โโโ api/ # API routes
โ โ โโโ auth/
โ โ โโโ user/
โ โโโ middleware/ # Server middleware
โ โโโ utils/ # Server utilities
โ
โโโ config/
โ โโโ navigation.ts # Navigation configuration
โ โโโ theme.ts # Theme configuration
โ โโโ NAVIGATION.md # Navigation docs
โ
โโโ composables/
โ โโโ useAuth.ts # Auth composable
โ
โโโ middleware/
โ โโโ auth.ts # Auth middleware
โ
โโโ db/
โ โโโ index.ts # Database connection
โ โโโ schema.ts # Database schema
โ
โโโ app.vue # Root component
๐จ Customization
Theme Configuration
Edit /config/theme.ts to customize the light/dark tokens that power the global CSS variables:
export const themeConfig = {
storageKey: 'app-theme',
cookieName: 'app-theme',
themes: {
light: {
page: '#f6f8fb',
surface: '#ffffff',
text: '#0f172a',
accent: '#6366f1',
// ...extend tokens as needed
},
dark: {
page: '#050a14',
surface: '#0f172a',
text: '#e5e7eb',
accent: '#818cf8',
// ...extend tokens as needed
}
}
}Theme System
- Toggle: Drop
<ThemeToggle />anywhere (already wired into the public navbar and dashboard sidebar). Addwith-labelto show text. - Composable:
const { theme, isDark, toggleTheme, setTheme } = useTheme()for programmatic control. - Persistence & defaults: Preference is stored in both
localStorageand aapp-themecookie; first visit falls back toprefers-color-schemewith an inline pre-paint script to avoid flashes. - Classes & variables: The active theme class (
light/dark) lives on<html>and drives the CSS variables like--bg-page,--surface,--text-primary,--accent, etc. Use these in component styles for theme-safe colors. - Extending tokens: Add new keys under
themeConfig.themes.light/darkand consume them via CSS variables or by extending the variable list inplugins/theme.tsif you introduce new tokens.
Navigation Menu
Edit /config/navigation.ts to add/remove menu items:
// Public navbar links
export const publicNavLinks: NavLink[] = [
{ label: 'Features', to: '/#features' },
{ label: 'Pricing', to: '/#pricing' },
]
// Dashboard sidebar menu
export const dashboardMenuItems: DashboardMenuItem[] = [
{
label: 'Analytics',
icon: 'i-heroicons-chart-bar',
children: [
{ label: 'Reports', to: '/dashboard/analytics/reports', icon: 'i-heroicons-document-text' },
],
},
]Adding New Pages
- Create the page file
touch pages/dashboard/your-page.vue- Add to navigation config
// In config/navigation.ts
{
label: 'Your Page',
to: '/dashboard/your-page',
icon: 'i-heroicons-sparkles',
}That's it! The navigation will automatically include your new page.
๐ Authentication
Register a New User
const { register } = useAuth()
await register({
email: 'user@example.com',
password: 'securepassword'
})Login
const { login } = useAuth()
await login({
email: 'user@example.com',
password: 'securepassword'
})Protect Routes
Add middleware: 'auth' to your page:
<script setup lang="ts">
definePageMeta({
middleware: 'auth'
})
</script>Access Current User
const { user } = useAuth()
console.log(user.value?.email)๐งช Database
Schema
The database schema is defined in /db/schema.ts using Drizzle ORM:
export const users = pgTable('users', {
id: serial('id').primaryKey(),
email: varchar('email', { length: 255 }).notNull().unique(),
password: varchar('password', { length: 255 }).notNull(),
createdAt: timestamp('created_at').defaultNow(),
})Migrations
Push schema changes to database:
pnpm db:pushGenerate migrations:
pnpm db:generate๐ฑ Responsive Design
Breakpoints
-
Mobile: < 768px
- Drawer navigation
- Stacked layouts
-
Tablet: 768px - 1023px
- Full navbar
- Drawer for dashboard
-
Desktop: โฅ 1024px
- Full navbar
- Fixed sidebar for dashboard
Mobile Navigation
Both public and dashboard layouts use a professional drawer pattern on mobile:
- Smooth slide-in animation
- Dark backdrop with blur
- Close triggers: X button, backdrop click, escape key, route change
- Body scroll prevention
๐ Production
Local Build
pnpm buildPreview
pnpm previewDocker Production Deployment
- Set production environment variables
Create a .env.production file:
DATABASE_URL="postgresql://postgres:secure_password@postgres:5432/nuxt_boilerplate"
JWT_SECRET="production-secret-min-32-characters-long"
NODE_ENV="production"- Build and deploy with Docker
# Build the production image
docker compose build app
# Start all services in production mode
docker compose up -d
# Check logs
docker compose logs -f app- Health checks
The containers include health checks for:
- PostgreSQL: Automatic readiness checks
- App: Waits for database to be ready before starting
Docker Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ Docker Compose Stack โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Nuxt App (Port 3000) โ โ
โ โ - Built with Node 20 Alpine โ โ
โ โ - Production optimized โ โ
โ โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โ connects to โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ PostgreSQL 16 (Port 5433) โ โ
โ โ - Persistent volume โ โ
โ โ - Health checks enabled โ โ
โ โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โ managed by โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Adminer (Port 8080) โ โ
โ โ - Web-based DB admin โ โ
โ โ - No setup required โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Environment Variables
Make sure to set these in production:
DATABASE_URL="your-production-database-url"
JWT_SECRET="your-production-jwt-secret"
NODE_ENV="production"๐ Documentation
- ๐ณ Docker Guide: Complete Docker setup and deployment - DOCKER.md
- Navigation System: See
/config/NAVIGATION.md - Navigation Refactoring: See
/NAVIGATION_REFACTOR.md - Theme Configuration: See
/config/README.md
๐ฏ Key Concepts
Component Naming Convention
Nuxt auto-imports components with folder prefixes:
components/layout/AppNavbar.vue โ <LayoutAppNavbar>
components/ui/UiButton.vue โ <UiButton>
components/auth/AuthWrapper.vue โ <AuthWrapper>
Route Middleware
- Global: Applied to all routes (defined in
nuxt.config.ts) - Named: Applied via
definePageMeta({ middleware: 'auth' }) - Anonymous: Inline functions in
definePageMeta
Composables
Reusable reactive logic in /composables/:
useAuth(): Authentication state and methods- Auto-imported throughout the app
๐ ๏ธ Development
Code Quality
# Type checking
pnpm typecheck
# Linting
pnpm lint
# Formatting (if configured)
pnpm formatVS Code
Recommended extensions:
- Vue - Official
- Tailwind CSS IntelliSense
- ESLint
- TypeScript Vue Plugin (Volar)
๐ License
MIT
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Built with Nuxt 4 โข Documentation โข Nuxt UI