@vernaillen/harmonic-saas
| Install | |
|---|---|
npm install @vernaillen/harmonic-saas |
|
| Latest Version: | 0.9.0 |
| Vue: | 3 |
| License: | MIT |
| Last Updated: | Sep 11, 2026 |
| Links: | npm |
Harmonic SaaS
A production-ready Nuxt Layer providing core SaaS functionality - authentication, database management, internationalization, and more. Build your next SaaS application on a solid, extensible foundation.
Features
✨ Authentication - Email/password, OAuth (GitHub, Google), magic links, passkeys 🗄️ Database - PostgreSQL with Drizzle ORM, extensible schema 🌍 Internationalization - Dutch & English, easy to add more languages 🎨 Modern UI - Nuxt UI with Tailwind CSS v4 📧 Email Integration - Resend for transactional emails 🧪 Testing - Comprehensive E2E tests with Playwright 🔒 Security - Email verification, password reset, account management 📦 Layer-based - Extend and customize without forking
Quick Start
Installation
# Install the layer
pnpm add @vernaillen/harmonic-saas
# Or with npm
npm install @vernaillen/harmonic-saas
Optional packages
Everything the layer imports at runtime ships as a regular dependency, so a plain install builds and runs. Only the native mobile tooling is left to you:
| You want | Install |
|---|---|
| An Android build | @capacitor/android, @capawesome/capacitor-android-edge-to-edge-support |
| An iOS build | @capacitor/ios |
| Generated app icons and splash screens | @capacitor/assets |
These are optional peer dependencies. They are only used by the Capacitor CLI
and the native Gradle/Xcode projects, never imported from app/ or server/,
so a web-only app can skip them.
The integrations below are still hard dependencies even when you do not enable
them, which makes the install heavier than it should be:
Stripe, Pusher, Resend, Nodemailer, AWS S3, Vercel Blob and @capacitor/core.
Each is imported statically by the module that wraps it, so they cannot become
optional until those imports are made lazy.
Configuration
Add the layer to your nuxt.config.ts:
export default defineNuxtConfig({
extends: ['@vernaillen/harmonic-saas']
})
Environment Setup
Create a .env file with required variables:
# Database
NUXT_DATABASE_URL=postgresql://user:password@localhost:5432/dbname
# Authentication (Better Auth)
NUXT_BETTER_AUTH_SECRET=your-secret-key
NUXT_BETTER_AUTH_URL=http://localhost:3000
# OAuth Providers (optional)
NUXT_GITHUB_CLIENT_ID=your-github-client-id
NUXT_GITHUB_CLIENT_SECRET=your-github-client-secret
NUXT_GOOGLE_CLIENT_ID=your-google-client-id
NUXT_GOOGLE_CLIENT_SECRET=your-google-client-secret
# Email (Resend or SMTP)
NUXT_RESEND_API_KEY=your-resend-api-key
NUXT_FROM_EMAIL=noreply@yourdomain.com
NUXT_APP_NAME=Your App Name
# CORS Configuration (Production only)
# Comma-separated list of allowed origins for API access
# Capacitor app origins are always allowed automatically
ALLOWED_ORIGINS=https://yourdomain.com,https://app.yourdomain.com
See Email Integration Guide for detailed email setup.
Security Note: In production, CORS is restricted to origins listed in ALLOWED_ORIGINS plus Capacitor app origins. See CORS Configuration Guide for details.
Firebase Setup (Android/iOS)
If you're building mobile apps with Capacitor and using Firebase (for push notifications, etc.):
⚠️ IMPORTANT: The android/app/google-services.json file contains sensitive API keys and should NEVER be committed to version control.
- Download your
google-services.jsonfrom Firebase Console - Place it in
android/app/google-services.json(already in.gitignore) - See Firebase Setup Guide for detailed instructions
Database Setup
# Generate migrations
pnpm db:generate
# Run migrations
pnpm db:migrate
# Or push schema directly in development
pnpm db:push
Development
# Start development server
pnpm dev
# Run tests
pnpm test
# Run E2E tests
pnpm test:e2e
# Lint code
pnpm lint
# Type check
pnpm typecheck
Technology Stack
- Framework: Nuxt 4 with Vue.js and TypeScript
- Database: PostgreSQL with Drizzle ORM
- Authentication: Better Auth
- UI: Nuxt UI with Tailwind CSS v4
- Email: Resend
- Testing: Vitest + Playwright
- Package Manager: pnpm
Architecture
Layer-Based Design
Harmonic SaaS is a Nuxt Layer - a reusable, composable foundation that you extend rather than fork. Your application inherits all the core functionality while maintaining full customization control.
your-app/
├── nuxt.config.ts # extends: ['@vernaillen/harmonic-saas']
├── app/
│ ├── pages/ # Your custom pages
│ └── components/ # Your custom components
└── server/
├── api/ # Your custom API routes
└── database/ # Extend the schema
Extending the Database Schema
// server/database/registerTables.ts
import { registerTables } from '@vernaillen/harmonic-saas/server/database'
import { myCustomTable } from './schema'
registerTables({
customTable: myCustomTable
})
Protected Routes
Routes in /app/pages/dashboard/ are automatically protected. To make a page public:
<script setup lang="ts">
definePageMeta({ auth: false })
</script>
Documentation
- 📖 Full Documentation - Comprehensive guides and references
- 🚀 E2E Testing Guide - Getting started with tests
- 📧 Email Integration - Email setup guide
- 🧑💻 CLAUDE.md - Developer onboarding and architecture
- 📝 CHANGELOG.md - Version history
Development Workflow
Working on the Layer
The .playground directory is your development environment for testing the layer:
# Start .playground development server
pnpm dev
# This boots the .playground directory which imports the layer
Testing
# Unit tests
pnpm test
# E2E tests
pnpm test:e2e
# Test coverage
pnpm coverage
See Testing Documentation for detailed testing documentation.
Quality Assurance
# Run all checks before committing
pnpm lint # ESLint with stylistic rules
pnpm typecheck # TypeScript type checking
pnpm test # Run test suite
pnpm coverage # Ensure test coverage
Release Process
# Full release workflow
pnpm release # Lint + coverage + version bump + publish
This runs the complete release workflow including linting, testing, coverage checks, and publishing to NPM.
Project Structure
harmonic-saas/
├── app/ # Frontend application
│ ├── components/ # Vue components
│ ├── composables/ # Composable functions
│ ├── middleware/ # Route middleware
│ └── pages/ # Application pages
├── server/ # Backend API
│ ├── api/ # API routes
│ ├── database/ # Database schema & utilities
│ └── utils/ # Server utilities
├── emails/ # Email templates (Vue Email)
├── docs/ # Documentation site (Nuxt Content)
│ ├── content/en/ # English documentation
│ │ ├── guides/ # Setup guides
│ │ ├── testing/ # Testing documentation
│ │ └── reference/ # Reference materials
│ └── public/ # Static assets
├── test/ # Test suites
│ ├── e2e/ # Playwright E2E tests
│ └── unit/ # Vitest unit tests
├── i18n/ # Internationalization
│ └── locales/ # Language files
└── .playground/ # Development environment
Contributing
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
License
Links
Built with ❤️ using Nuxt 4 and Better Auth
Related Packages
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.9.0 | ^3.5.42 | MIT | |
| 0.8.1 | latest | ||
| 0.8.0 | latest | ||
| 0.7.1 | latest | ||
| 0.7.0 | latest | ||
| 0.6.0 | latest | ||
| 0.5.3 | latest | ||
| 0.5.2 | latest | ||
| 0.5.1 | latest | ||
| 0.5.0 | latest | ||
| 0.4.2 | latest | ||
| 0.4.1 | latest | ||
| 0.4.0 | latest | ||
| 0.3.11 | latest | ||
| 0.3.10 | latest | ||
| 0.3.9 | latest | ||
| 0.3.8 | latest | ||
| 0.3.7 | latest | ||
| 0.3.6 | latest | ||
| 0.3.5 | latest | ||
| 0.3.4 | latest | ||
| 0.3.3 | latest | ||
| 0.3.2 | latest | ||
| 0.3.1 | latest | ||
| 0.3.0 | latest | ||
| 0.2.6 | latest | ||
| 0.2.5 | latest | ||
| 0.2.4 | latest | ||
| 0.2.3 | latest | ||
| 0.2.2 | latest |
Showing the latest 30 of 50. See every release on npm