# Introduction Nuxt Starter Kit is a professional boilerplate for building fast, robust, and adaptable web apps or sites. ::tip **TL;DR**: This starter kit is highly opinionated and is not like other flexible starter kits out there. It is built with the following technologies: - [Nuxt 4+](https://nuxt.com/){rel=""nofollow""} - The Vue.js framework - [Nuxt UI](https://ui.nuxt.com){rel=""nofollow""} - UI component library - [Better-auth](https://better-auth.com/){rel=""nofollow""} - Authentication library - [Drizzle ORM](https://orm.drizzle.team/){rel=""nofollow""} - TypeScript ORM - [PostgreSQL](https://www.postgresql.org/){rel=""nofollow""} - Database - [Polar](https://polar.sh/){rel=""nofollow""} - Payment integration - [Turborepo](https://turbo.build/repo){rel=""nofollow""} - Monorepo build system The architecture uses **Turborepo** with **pnpm workspaces** and **Nuxt 4 layers** for a modular approach. It's completely **vendor-free** - deploy to any platform that supports Node.js. :: ## Key Features ::card-group :::card --- icon: i-lucide-server title: Vendor-Free Deployment to: https://nuxtstarterkit.com/docs/getting-started/deployment --- Deploy anywhere - Vercel, Netlify, Railway, or any VPS. No vendor lock-in. ::: :::card --- icon: i-lucide-layers title: Turborepo Monorepo to: https://nuxtstarterkit.com/docs/architecture/layers --- Organized with Turborepo, pnpm workspaces, and Nuxt 4 layers for modularity. ::: :::card --- icon: i-lucide-user target: _blank title: Better-auth Authentication to: https://better-auth.com/ --- Email/password and social login - all powered by better-auth. ::: :::card --- icon: i-lucide-lock-keyhole target: _blank title: Security You Can Trust to: https://nuxt-security.vercel.app/ --- Harden your app with the Nuxt Security module. Out-of-the-box security headers, rate limiting, and best practices - just plug and play. ::: :::card --- icon: i-lucide-circle-dollar-sign target: _blank title: Payments via Polar to: https://polar.sh/ --- Built-in MoR (Merchant of Record) support makes payments effortless. ::: :::card --- icon: i-lucide-globe target: _blank title: Ready for the World with i18n to: https://i18n.nuxtjs.org/ --- Translate your app using Vue I18n integration. ::: :: # Installation ## Prerequisites - [Node.js](https://nodejs.org/en/download/){rel=""nofollow""} v22 or higher - JavaScript runtime - [pnpm](https://pnpm.io/installation){rel=""nofollow""} - A fast, disk space efficient package manager - [Git](https://git-scm.com/downloads){rel=""nofollow""} - Version control system - [PostgreSQL](https://www.postgresql.org/download/){rel=""nofollow""} - Database (local or hosted) ## Cloning the repository After you purchased my starter kit, you'll receive a link to download the repository. You can clone it using the following command: ```bash git clone https://github.com/NuxtStarterKit/nuxtstarterkit.git NAME_OF_YOUR_PROJECT ``` Replace `NAME_OF_YOUR_PROJECT` with the name of your project. Alternatively, you can click the `Use this template` button on the GitHub repository page to create a new repository based on my starter kit: ![Template GitHub](https://nuxtstarterkit.com/docs/use-this-template.png) This will create a new repository in your GitHub account with the same structure and files as my starter kit. # Setup ::steps{level="3"} ### Install dependencies ```bash pnpm install ``` ### Setup environment variables Define your environment variables in the `.env` file. You can use the `.env.example` file as a reference. The starter kit uses [@t3-oss/env-nuxt](https://www.npmjs.com/package/@t3-oss/env-nuxt){rel=""nofollow""} to typecheck the environment variables. Required environment variables: - `NUXT_PRIVATE_DATABASE_URL` - PostgreSQL connection string - `BETTER_AUTH_SECRET` - Secret for better-auth session encryption - `BETTER_AUTH_URL` - Your app URL (e.g., `http://localhost:9009` for local dev) Optional but recommended: - `NUXT_PRIVATE_POLAR_ACCESS_TOKEN` - For payment integration - `NUXT_PRIVATE_POLAR_ORGANIZATION_ID` - Your Polar organization ID - OAuth credentials for social login (Google, GitHub) ### Create database schema Generate and apply database migrations: ```bash pnpm db:generate # Generate migrations from schema pnpm db:migrate # Apply migrations to database ``` ### Start the development server Start the development server for the web app: ```bash pnpm dev:web ``` You can now access your app at `http://localhost:9009`. ### Polar Nuxt Starter Kit uses [Polar](https://polar.sh/){rel=""nofollow""} to accept payments, see [Payments](https://nuxtstarterkit.com/docs/payments) for more information. This starter kit is designed to support subscriptions (free & Pro) and lifetime deals. You should configure three products in Polar: - Pro Plan (yearly subscription) - Pro Plan (monthly subscription) - Lifetime Deal (one-time payment) :::note Any other product constellation needs adjustments in the `packages/layer-payment` layer and other parts of the codebase. ::: :: # Pull Updates To pull updates from the original repository, you need to add it as a remote. This allows you to fetch and merge changes from the original repository into your fork. ### 1. Adding the original repository as a remote ```bash git remote add origin https://github.com/NuxtStarterKit/nuxtstarterkit.git ``` This command adds the original repository as a remote named `origin`. ### 2. Fetch the latest changes Run the following command to fetch the latest changes from the original repository: ```bash git fetch origin ``` ### 3. Create a new branch I would recommend creating a new branch for the updates. This way, you can test the changes before merging them into your main branch: ```bash # Switch to the main branch git checkout main # Create a new branch for the updates git checkout -b update-branch ``` ### 4. Merge the changes Now, you can merge the changes from the original repository into your new branch: ```bash git pull origin main --allow-unrelated-histories --no-rebase ``` With this command, you are merging the changes from the `main` branch of the original repository into your current branch. The `--allow-unrelated-histories` flag allows merging two unrelated histories, and the `--no-rebase` flag prevents rebasing the changes. ### 5. Resolve any conflicts If there are any merge conflicts, Git will notify you. You will need to resolve these conflicts manually with your tool of choice (e.g., VSCode, WebStorm, etc.). ### 6. Test the changes After resolving any conflicts, it's important to test the changes to ensure everything works as expected. Run your application and check for any issues. ### 7. Merge the updates into your main branch Once you have tested the changes and resolved any conflicts, you can commit the changes to your branch: ```bash # Switch back to the main branch git checkout main # Merge the updates from the temporary branch git merge update-branch ``` # Deployment This starter kit is **vendor-free** and can be deployed to any platform that supports Node.js and PostgreSQL. ::warning Follow the [Going to production](https://nuxtstarterkit.com/docs/getting-started/going-to-production) guide before deploying your application to production. :: ## Deployment Platforms The starter kit works with any Node.js hosting platform: ### Vercel 1. Connect your repository to Vercel 2. Set up environment variables in the Vercel dashboard 3. Vercel will automatically detect it's a Nuxt app and deploy ### Netlify 1. Connect your repository to Netlify 2. Set build command: `pnpm build` 3. Set publish directory: `apps/web/.output/public` 4. Configure environment variables in Netlify ### Railway 1. Create a new project in Railway 2. Connect your GitHub repository 3. Add a PostgreSQL database 4. Set environment variables 5. Railway will auto-deploy on git push ### Any VPS (DigitalOcean, Linode, etc.) 1. Set up a server with Node.js installed 2. Clone your repository 3. Install dependencies with `pnpm install` 4. Build the application with `pnpm build` 5. Run migrations with `pnpm db:migrate` 6. Start the server with the generated output ## Environment Variables Ensure all required environment variables are set in your deployment platform: - `NUXT_PRIVATE_DATABASE_URL` - PostgreSQL connection string - `BETTER_AUTH_SECRET` - Secret for session encryption - `BETTER_AUTH_URL` - Your production URL - `NUXT_PRIVATE_POLAR_ACCESS_TOKEN` - For payments (if using Polar) - `NUXT_PRIVATE_POLAR_ORGANIZATION_ID` - Your Polar org ID - OAuth credentials (if using social login) ## Database Make sure your PostgreSQL database is accessible from your deployment platform. Most platforms offer: - Managed PostgreSQL add-ons (recommended) - Or connect to external PostgreSQL services like: - [Neon](https://neon.tech/){rel=""nofollow""} - [Supabase](https://supabase.com/){rel=""nofollow""} - [Railway](https://railway.app/){rel=""nofollow""} - [Render](https://render.com/){rel=""nofollow""} ## Build Command The build command for the monorepo is: ```bash pnpm build ``` This uses Turborepo to build all packages in the correct order. ## Post-Deploy After deployment, run the database migrations: ```bash pnpm db:migrate ``` Most platforms support running commands after deployment or you can run this manually. # Going to production These are the final steps to prepare your app for production. You can skip this step if you are using the Nuxt Starter Kit in development mode. ## Naming & Branding - Rename the app to your brand name, search for any occurrences of "Demo SaaS" and replace them with your brand name. - Update `config/siteConfig.ts` with your configurations. - Update `description` in `en.json` and `de.json` files in the `i18n` directory. - Rename `name` in `package.json` to your brand name. - Update `favicon.ico` & `logo.png` in the `public` directory. - Change to a theme that fits your brand, see [Theme](https://ui.nuxt.com/getting-started/theme){rel=""nofollow""} for more details. ## Intruder redirection In `nuxt.config.ts`, some route rules are set up to redirect intruders to a funny GIF. You should definitely change this to a more serious solution, for example, a 404 page or a custom page that matches your brand. ## Email templates Nuxt Starter Kit uses some email templates, you should customize them to match your brand. You can find the email templates in the `layers/email/components/email/template` directory. You definitely should customize the logo, brand colors and footer links. You can also customize the email subject and body to match your brand. You can preview all emails as admin user, see [Admin](https://nuxtstarterkit.com/docs/admin) for more details. You should also send a test email to yourself to make sure everything is working as expected. You can do this in the admin section as well. ## Payment Make sure the products or subscriptions you want to offer are set up correctly in the payment provider. Also verify that the webhooks are set up correctly and that the payment provider is able to send webhooks to your app. You can do this by checking the logs in the payment provider dashboard. ## SEO Verify that all pages have a meta title and description. Additionally, check that all pages are indexed and added to the sitemap. ## Legal pages Add content to all legal pages, including the privacy policy, terms of service, and cookie policy. You can find these pages in the `app/pages/legal` directory. ## Docs & Blog Add real content to the docs and blog pages or remove them if you don't need them. # Tech Stack The starter kit uses modern technologies in a **Turborepo monorepo** structure: ## Core Technologies - **[Nuxt 4+](https://nuxt.com/){rel=""nofollow""}** - The Vue.js framework for building web applications - **[Nuxt UI](https://ui.nuxt.com/){rel=""nofollow""}** - UI component library with beautiful pre-built components - **[Better-auth](https://better-auth.com/){rel=""nofollow""}** - Modern authentication library with support for email/password and social login - **[Drizzle ORM](https://orm.drizzle.team/){rel=""nofollow""}** - TypeScript-first ORM with excellent developer experience - **[PostgreSQL](https://www.postgresql.org/){rel=""nofollow""}** - Reliable, powerful relational database - **[Tailwind CSS](https://tailwindcss.com/){rel=""nofollow""}** - Utility-first CSS framework - **[Turborepo](https://turbo.build/repo){rel=""nofollow""}** - High-performance build system for monorepos - **[pnpm](https://pnpm.io/){rel=""nofollow""}** - Fast, disk space efficient package manager ## Architecture The project uses a **monorepo structure** with: - **Turborepo** for build orchestration - **pnpm workspaces** for package management - **Nuxt 4 layers** for modular application structure All packages use a **centralized catalog** in `pnpm-workspace.yaml` for dependency management. ## Main Application The main web app is located in `apps/web/` and extends multiple Nuxt layers from the `packages/` directory. ## Monorepo Scripts Key commands (run from root): ```bash pnpm dev:web # Start web app dev server pnpm build # Build all packages pnpm lint # Lint all packages pnpm lint:fix # Auto-fix linting issues pnpm typecheck # TypeScript check pnpm db:generate # Generate DB migrations pnpm db:migrate # Apply DB migrations pnpm db:studio # Open Drizzle Studio ``` ## Layer Structure The application is organized into Nuxt layers in `packages/`: - `layer-core` - Base layer with UI, i18n, SEO - `layer-auth` - Authentication with better-auth - `layer-emails` - Email templates and sending - `layer-payment` - Polar.sh payment integration - `layer-storage` - File storage handling - `layer-testimonials` - Testimonials feature - `layer-dashboard` - User dashboard - `layer-waitlist` - Waitlist management - `layer-blog` - Blog functionality - `layer-docs` - Documentation Layers are referenced by name (e.g., `'layer-auth'`), not by path, as they are workspace packages. # Layers Nuxt Layers is a powerful feature that allows you to create modular applications by composing different layers. Each layer can contain its own configuration, components, and modules, making it easy to share and reuse code across different projects. ## What layers are included in this starter kit? This starter kit contains layers in the `/packages` directory: ### Core Layers - **layer-core**: Base layer containing shared composables, components & server routes: - `useAppToast`: Toast notifications with success, error, info, warn methods - `useConfirmationModal`: Confirmation modals - `useLoadingModal`: Loading modals - `useLogger`: Client-side logging (wraps consola) - Server utilities for logging and masking sensitive data - **layer-emails**: Email templates and sending functionality: - Nuxt Email Renderer components for templates - `useEmail()` composable with pre-built email methods - Templates in `app/emails/` directory ### Feature Layers - **layer-auth**: Authentication using better-auth: - Email/password authentication - Social login (Google, GitHub) - Database schema in `server/db/schema/auth.ts` - `useAuth()` composable for client - `requireAuth()`, `useServerAuth()` for server - **layer-payment**: Payment integration with Polar.sh: - Uses `@polar-sh/better-auth` plugin - `useBilling()` composable - Server utilities for Polar customer management - **layer-storage**: File storage handling - File upload and management - Database schema in `server/db/schema/file.ts` - **layer-dashboard**: User dashboard: - Extends layer-auth, layer-payment, layer-storage, layer-testimonials - User settings, billing management - Admin panel features - **layer-testimonials**: Testimonials management: - Public testimonials display - Admin management interface - Database schema in `server/db/schema/testimonial.ts` - **layer-waitlist**: Waitlist functionality: - User signups - Email verification - Database schema in `server/db/schema/waitlist.ts` - **layer-blog**: Blog functionality: - Blog posts with Nuxt Content - RSS feed generation - **layer-docs**: Documentation pages: - Documentation with Nuxt Content - Search functionality ## Layer Dependency Graph ```text apps/web extends: ├─ layer-dashboard (requires layer-auth, layer-payment, layer-storage, layer-testimonials) ├─ layer-testimonials (requires layer-auth) ├─ layer-blog (requires layer-core) ├─ layer-waitlist (requires layer-auth) └─ layer-docs (requires layer-auth) layer-dashboard extends: ├─ layer-auth ├─ layer-payment (requires layer-auth) ├─ layer-storage (requires layer-auth) └─ layer-testimonials (requires layer-auth) layer-auth extends: ├─ layer-core (base layer) └─ layer-emails (requires layer-core) ``` ## Referencing Layers **Important**: Layers are referenced by **name only**, not by path. They're workspace packages managed by pnpm. ✅ Correct: ```typescript export default defineNuxtConfig({ extends: ['layer-auth', 'layer-core'] }) ``` ❌ Wrong: ```typescript export default defineNuxtConfig({ extends: ['../packages/layer-auth'] }) ``` ## Remove a layer To remove a layer: 1. Delete the corresponding directory in `/packages` 2. Remove it from `extends` in your `nuxt.config.ts` 3. Search for references to the layer throughout the codebase 4. Remove its dependencies from `package.json` if no longer needed 5. Update any imports that reference the layer ## Adding a new layer 1. Create a new directory in `/packages/layer-` 2. Add `package.json` with the layer name 3. Create `nuxt.config.ts` to configure the layer 4. Add the layer to `extends` in `apps/web/nuxt.config.ts` 5. Reference it by name in your extends array # PostgreSQL The starter kit uses **PostgreSQL** as the database, managed through **Drizzle ORM** for excellent developer experience and type safety. ## Database Provider You can use PostgreSQL from various providers: - **[Neon](https://neon.tech/){rel=""nofollow""}** - Serverless PostgreSQL with generous free tier - **[Supabase](https://supabase.com/){rel=""nofollow""}** - Open source Firebase alternative with PostgreSQL - **[Railway](https://railway.app/){rel=""nofollow""}** - Simple PostgreSQL hosting - **[Render](https://render.com/){rel=""nofollow""}** - Managed PostgreSQL databases - **Local PostgreSQL** - For development ## Drizzle ORM The starter kit uses [Drizzle ORM](https://orm.drizzle.team/){rel=""nofollow""} instead of raw SQL for several benefits: - **Type safety** - Full TypeScript support with auto-completion - **Migrations** - Automated schema migrations - **Relations** - Easy relationship management - **Developer experience** - Intuitive query builder ## Database Schema All database schemas are located in `packages/layer-auth/server/db/schema/`: - `auth.ts` - User, session, account tables (better-auth) - `testimonial.ts` - Testimonials feature - `waitlist.ts` - Waitlist management - `file.ts` - File storage metadata - `banner.ts` - App banner configuration ## Database Utilities Import from layer-auth server utils: ```typescript import { and, desc, eq, useDb } from 'layer-auth/server/utils/db' const db = useDb() const users = await db.select() .from(schema.user) .where(eq(schema.user.email, email)) ``` ## Commands Run these commands from the **monorepo root**: ```bash # Generate migrations from schema changes pnpm db:generate # Apply migrations to database pnpm db:migrate # Open Drizzle Studio (database GUI) pnpm db:studio ``` ## Environment Variables Set your PostgreSQL connection string in `.env`: ```bash NUXT_PRIVATE_DATABASE_URL="postgresql://user:password@host:5432/dbname" ``` For local development, you might use: ```bash NUXT_PRIVATE_DATABASE_URL="postgresql://postgres:postgres@localhost:5432/nuxtstarterkit" ``` ## Migration Workflow 1. Make changes to schema files in `packages/layer-auth/server/db/schema/` 2. Run `pnpm db:generate` to create migration files 3. Review generated migrations in `packages/layer-auth/server/db/migrations/` 4. Run `pnpm db:migrate` to apply migrations 5. Commit both schema and migration files ## Drizzle Studio Drizzle Studio provides a visual interface to browse and edit your database: ```bash pnpm db:studio ``` This opens a web interface where you can: - Browse tables and data - Run queries - Edit records - View relationships ## Type Safety Drizzle generates TypeScript types from your schema. Import and use them: ```typescript import { session, user } from 'layer-auth/server/db/schema' import type { Session, User } from 'layer-auth/shared/types/db' // Use typed queries const users: Array = await db.select().from(user) ``` ## Best Practices - Always use migrations - never modify the database schema directly - Keep schema files organized by feature - Use meaningful column and table names - Add indexes for frequently queried columns - Use transactions for multiple related operations # Overview Nuxt Starter Kit includes a simple Nuxt layer that allows you to send emails using [Plunk](https://www.useplunk.com/){rel=""nofollow""} or [Resend](https://resend.com/){rel=""nofollow""}. This layer is located in the `packages/layer-emails` directory and is responsible for managing the email connection, sending emails, and handling errors. ## Nuxt Email Renderer I use [Nuxt Email Renderer](https://nuxtemail.com){rel=""nofollow""} which provides a collection of high-quality, unstyled components for creating emails using Vue and TypeScript. The pre-defined templates are located in the `packages/layer-emails/app/emails/` directory. You can use these templates to create your own emails or modify them to fit your needs. ## Plunk ::tip My recommendation is to use a self-hosted version of [Plunk](https://www.useplunk.com/){rel=""nofollow""}. :: To enable Plunk, you need to set the following environment variables in your `.env` file: ```bash NUXT_PRIVATE_EMAIL_PROVIDER=plunk NUXT_PRIVATE_EMAIL_PLUNK_API_URL=YOUR_API_URL NUXT_PRIVATE_EMAIL_PLUNK_API_KEY=YOUR_API_KEY ``` ## Resend To enable Resend as email provider, you need to set the following environment variables in your `.env` file: ```bash NUXT_PRIVATE_EMAIL_PROVIDER=resend NUXT_PRIVATE_EMAIL_RESEND_API_TOKEN=YOUR_API_KEY ``` ## Other Providers You can easily add support for other email providers by adding a new provider in `packages/layer-emails/server/utils/getEmailProvider.ts`. This file contains the logic for selecting the appropriate email provider based on the configuration. You can add your own provider by creating a new function that implements the `EmailProvider` interface and updating the `getEmailProvider` function to include your new provider. Checkout [useEmail](https://github.com/SupersaasHQ/useEmail/tree/main/src/services){rel=""nofollow""} which includes other email providers like [SendGrid](https://sendgrid.com/){rel=""nofollow""} and [Mailgun](https://www.mailgun.com/){rel=""nofollow""}. # Overview Nuxt Starter Kit uses [better-auth](https://better-auth.com/){rel=""nofollow""} to provide a modern, type-safe authentication system. The authentication code is located in the `packages/layer-auth` directory and handles login, logout, session management, and more. ## Supported Authentication Methods - Email and password - Social login (Google & GitHub) - Passkey (WebAuthn / FIDO2) ## Better-auth Features - **Type-safe** - Full TypeScript support - **Session management** - Secure session handling - **Social providers** - Easy OAuth integration - **Database-backed** - Sessions stored in PostgreSQL - **Extensible** - Plugin system for custom features ## Environment Variables Required in `.env`: ```bash # Better-auth configuration BETTER_AUTH_SECRET=your-secret-key-min-32-chars BETTER_AUTH_URL=http://localhost:9009 # Social login (optional) NUXT_OAUTH_GITHUB_CLIENT_ID=your-github-client-id NUXT_OAUTH_GITHUB_CLIENT_SECRET=your-github-client-secret NUXT_OAUTH_GOOGLE_CLIENT_ID=your-google-client-id NUXT_OAUTH_GOOGLE_CLIENT_SECRET=your-google-client-secret ``` ## Client-side Usage Use the `useAuth()` composable (auto-imported): ```vue ``` ## Server-side Usage ### Require Authentication Use `requireAuth()` to ensure a user is authenticated: ```typescript // server/api/protected.get.ts export default defineEventHandler(async (event) => { const { session, user } = await requireAuth(event) // User is guaranteed to be authenticated here return { message: `Hello ${user.name}!` } }) ``` ### Optional Authentication Use `useServerAuth()` when authentication is optional: ```typescript // server/api/optional.get.ts export default defineEventHandler(async (event) => { const { session, user } = await useServerAuth(event) if (user) { return { message: `Hello ${user.name}!` } } return { message: 'Hello guest!' } }) ``` ## Database Schema Better-auth uses these tables (in `packages/layer-auth/server/db/schema/auth.ts`): - `user` - User accounts - `session` - Active sessions - `account` - OAuth provider accounts - `verification` - Email verification tokens ## Plugins The starter kit includes: ### Polar Plugin Integrates with Polar.sh for payments: ```typescript import { polar } from '@polar-sh/better-auth' // Already configured in layer-auth ``` ## Social Login Setup ### GitHub OAuth 1. Go to GitHub Settings > Developer settings > OAuth Apps 2. Create a new OAuth App 3. Set Authorization callback URL to: `https://your-domain.com/api/auth/callback/github` 4. Copy Client ID and Client Secret to `.env` ### Google OAuth 1. Go to [Google Cloud Console](https://console.cloud.google.com/){rel=""nofollow""} 2. Create a new project or select existing 3. Enable Google+ API 4. Create OAuth 2.0 credentials 5. Add authorized redirect URI: `https://your-domain.com/api/auth/callback/google` 6. Copy Client ID and Client Secret to `.env` ## Customization Authentication is configured in `packages/layer-auth/server/utils/auth.ts`. You can: - Add more OAuth providers - Configure session duration - Add custom plugins - Modify user schema ## Security Better-auth provides: - Secure session storage - CSRF protection - Rate limiting (when configured) - Password hashing with bcrypt - Secure cookie handling # Polar Nuxt Starter Kit uses [Polar](https://polar.sh/){rel=""nofollow""} to accept payments. Polar is a simple and secure way to accept payments online. It provides a simple API for creating and managing subscriptions, invoices, and payments. ## Getting Started To get started with Polar, you need to create an account and set up your API keys. You can do this by following the instructions in the [Polar documentation](https://polar.sh/docs/getting-started){rel=""nofollow""}. In your code, you need to set the following environment variables in your `.env` file: ```bash NUXT_PRIVATE_POLAR_ACCESS_TOKEN= NUXT_PRIVATE_POLAR_WEBHOOK_SECRET= NUXT_PRIVATE_POLAR_ORGANIZATION_ID= NUXT_PRIVATE_POLAR_SERVER= ``` ### NUXT\_PRIVATE\_POLAR\_ACCESS\_TOKEN This is your Polar access token. You can generate one in your Polar account settings. This token is used to authenticate your requests to the Polar API. ### NUXT\_PRIVATE\_POLAR\_WEBHOOK\_SECRET Follow the [Setup Webhooks](https://docs.polar.sh/integrate/webhooks/endpoints){rel=""nofollow""} guide to set up webhooks in your Polar account. Here some important notes: 1. Use the URL `https://` component for optimized images: ```vue ``` ## Static Images Place static images in the `public/` directory: ```text public/ ├── landing-page/ │ ├── hero.png │ └── features.png └── docs/ └── screenshots/ ``` ## Image Optimization Tips 1. **Use appropriate formats**: WebP for web, AVIF for modern browsers 2. **Lazy loading**: Add `loading="lazy"` for below-the-fold images 3. **Responsive images**: Use `sizes` and `srcset` attributes 4. **Compress before upload**: Pre-compress large images before adding to repository ## File Storage The starter kit includes file storage functionality through the `layer-storage` package with AWS S3 integration for handling user uploads. ### AWS S3 Configuration Set up your AWS S3 credentials in your `.env` file: ```bash NUXT_PRIVATE_AWS_S3_ACCESS_KEY_ID=your-access-key-id NUXT_PRIVATE_AWS_S3_SECRET_ACCESS_KEY=your-secret-access-key NUXT_PRIVATE_AWS_S3_BUCKET_NAME=your-bucket-name NUXT_PRIVATE_AWS_S3_REGION=us-east-1 ``` ### AWS S3 Setup 1. **Create an S3 Bucket**: - Go to [AWS S3 Console](https://console.aws.amazon.com/s3/){rel=""nofollow""} - Create a new bucket with a unique name - Configure bucket settings (versioning, encryption, etc.) 2. **Configure CORS** (if accessing files from browser): ```json [ { "AllowedHeaders": ["*"], "AllowedMethods": ["GET", "PUT", "POST", "DELETE"], "AllowedOrigins": ["https://your-domain.com"], "ExposeHeaders": [] } ] ``` 3. **Create IAM User**: - Go to IAM Console - Create a new user with programmatic access - Attach policy with S3 permissions (or use `AmazonS3FullAccess` for development) - Save the Access Key ID and Secret Access Key ### Recommended IAM Policy For production, use a more restrictive policy: ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::your-bucket-name/*", "arn:aws:s3:::your-bucket-name" ] } ] } ``` ### Storage Layer The storage functionality is located in `packages/layer-storage`: - **Server utilities**: Upload, delete, and manage files - **Database schema**: File metadata storage in `server/db/schema/file.ts` - **Client composables**: File upload utilities Files are tracked in the database with metadata including file name, path, size, content type, upload timestamp, and associated user ID. ### Uploading Files **Server-side:** ```typescript // server/api/upload.post.ts import { uploadFileToS3 } from 'layer-storage/server/utils/storage' export default defineEventHandler(async (event) => { const { user } = await requireAuth(event) const formData = await readFormData(event) const file = formData.get('file') as File const result = await uploadFileToS3(file, { folder: 'uploads', userId: user.id }) return result }) ``` **Client-side:** ```vue ``` ### File Access Files stored in S3 can be accessed via: 1. **Direct S3 URLs** - For public files 2. **Signed URLs** - For private files with temporary access 3. **CloudFront CDN** - For optimized delivery (recommended) Generate signed URLs for private files: ```typescript import { getSignedUrl } from 'layer-storage/server/utils/storage' const signedUrl = await getSignedUrl(fileKey, { expiresIn: 3600 // 1 hour }) ``` ### Storage Best Practices 1. **Validate file types** - Only allow expected file types 2. **Limit file sizes** - Set appropriate size limits 3. **Scan for malware** - Implement virus scanning for user uploads 4. **Use signed URLs** - For private files, always use signed URLs 5. **Organize files** - Use consistent folder structures (e.g., `uploads/{userId}/{filename}`) 6. **Set lifecycle policies** - Automatically delete or archive old files 7. **Enable versioning** - Protect against accidental deletions 8. **Monitor costs** - Set up CloudWatch alerts for S3 usage ### Alternative Storage Providers While the starter kit uses AWS S3 by default, you can integrate other S3-compatible storage providers: - **Cloudflare R2** - S3-compatible with no egress fees - **DigitalOcean Spaces** - S3-compatible object storage - **Backblaze B2** - Cost-effective S3-compatible storage - **Google Cloud Storage** - Google's object storage solution To use an alternative provider, update the storage utilities in `packages/layer-storage/server/utils/storage.ts` with the provider's SDK and configuration. # Overview This starter kit uses [nuxt-i18n](https://nuxt.com/modules/i18n){rel=""nofollow""} module to provide internationalization (i18n) support for your application. This allows you to easily manage translations and switch between different languages. ## What if I don't need i18n support? I would highly recommend to not remove the i18n module from your project, even if you don't need it. The i18n module is used in many places in the starter kit, and removing it will require a lot of changes to the code. Even if you don't want to support multiple languages, you can still use the i18n module to manage your translations. This is especially useful if you want to support multiple languages in the future. Of course, you can hard code any text in your app, but this is not recommended. The i18n module provides a simple and consistent API for managing translations, and it is much easier to use than hard coding text in your app. # Overview Nuxt Starter Kit uses [Nuxt SEO](https://nuxtseo.com/){rel=""nofollow""} module to provide SEO support for your application. Nuxt SEO is a collection of modules that handle all of the technical aspects in growing your sites organic traffic. # Umami This starter kit uses the [nuxt-umami](https://nuxt.com/modules/umami){rel=""nofollow""} module to track page views and events. This module is a wrapper around the [Umami](https://umami.is/){rel=""nofollow""}, making it easier to integrate with Nuxt applications. Umami is an open-source, privacy-focused web analytics tool that serves as an alternative to Google Analytics. It provides essential insights into website traffic, user behavior, and performance, all while prioritizing data privacy. ::tip My recommendation is to self-host Umami. You can find the instructions on how to do this in the [Umami documentation](https://umami.is/docs/guides/hosting){rel=""nofollow""}. :: ## Other Analytics Providers If you prefer to use a different analytics provider, you can easily do so by following these steps: 1. Uninstall the `nuxt-umami` module: ```bash pnpm remove nuxt-umami ``` 2. **Remove the nuxt-umami module**: Open your `nuxt.config.ts` file and remove the `nuxt-umami` module from the `modules` array: ```ts export default defineNuxtConfig({ modules: [ // Remove this line 'nuxt-umami', ], }) ``` 3. Remove all references of the Umami environment variables starting with `UMAMI_` from your code and deployment environment variables. 4. **Install the new analytics module**: Depending on the provider you choose, you may need to install a different Nuxt module or use a custom script tag. # Overview This starter kit uses the [nuxt-security](https://nuxt.com/modules/security){rel=""nofollow""} Nuxt module to enhance the security of your application. This module provides a set of security headers and best practices to help protect your application from common vulnerabilities and attacks. It can be configured to suit your specific needs and requirements. The module is designed to be easy to use and integrate into your existing Nuxt application. Configuration is done in the `nuxt.config.ts` file, where you can enable or disable specific security features and customize their settings: ```ts [nuxt.config.ts] export default defineNuxtConfig({ modules: ['nuxt-security'], security: { // options } }) ``` ## Rate Limiting By default, rate limiting is disabled in this starter kit: ```ts [nuxt.config.ts] export default defineNuxtConfig({ security: { rateLimiter: false } }) ``` I disabled rate limiting by default for development flexibility. Feel free to enable it in production if you need it and have tested it with your deployment platform. # E2E Testing This starter kit uses [Playwright](https://playwright.dev/){rel=""nofollow""} for end-to-end (E2E) testing. Playwright is a powerful and flexible testing framework that allows you to automate browser interactions and test your web applications across different browsers and devices. In `app/e2e` directory, you will find the following files: - `page`: This directory contains the page objects for your application. Page objects are a design pattern that helps you organize your test code by encapsulating the interactions with different pages of your application. Each page object should represent a specific page or component of your application and provide methods to interact with it. - `/`: The root directory contains your E2E test files. You can create separate test files for different features or pages of your application. Each test file should follow the naming convention `*.e2e.ts` to be recognized by Playwright. ::note The E2E tests are very basic and only check if the application is running. You can extend them to cover more complex scenarios and interactions as needed. :: ## Running E2E Tests You can run the E2E tests using the following command: ```bash pnpm test:e2e ``` This command will execute all the E2E tests in your application and generate a report with the results. The following command will run the E2E tests with the Playwright UI to visualize the test execution: ```bash pnpm test:e2e:ui ``` ## Continous Integration (CI) The E2E tests are automatically run in the CI pipeline when you push changes to your repository. This ensures that your application is always tested and verified before being deployed to production. You can find the configuration for the CI pipeline in the `.github/workflows/` directory. # Help If you need help with your Nuxt Starter Kit application, there are several ways to get support: - **AI Chat**: On the bottom right corner of this page, you will find a chat icon. You can ask questions and get help from an AI assistant. This is a great way to get quick answers to your questions. - **Documentation**: This documentation is a great place to start. It contains a lot of information about how to use the starter kit and its features. - **Discord**: If you buy this starter kit, you get access to a private Discord server where you can ask your questions. - **GitHub Discussions**: You can ask questions and get help from the community in the GitHub Discussions section of the repository. This is a great place to ask questions and get help from other users and contributors. - **GitHub Issues**: If you find a bug or have a feature request, you can open an issue in the GitHub repository. Please make sure to follow the issue template and provide as much information as possible. - **Email**: If you need to contact me directly, you can send me an email at # Troubleshooting ## JavaScript heap out of memory error during build The `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory` error occurs when the Node.js process runs out of memory during build. This is related to [this Vite issue](https://github.com/vitejs/vite/issues/2433){rel=""nofollow""}. **Solution**: Increase the memory limit by setting the `NODE_OPTIONS` environment variable: ```bash NODE_OPTIONS=--max-old-space-size=8192 pnpm build ``` For CI/CD deployments, add this environment variable in your deployment platform's settings. ## Database connection issues If you're having trouble connecting to PostgreSQL: 1. **Check connection string format**: ```bash NUXT_PRIVATE_DATABASE_URL="postgresql://user:password@host:5432/dbname" ``` 2. **Verify database is running**: ```bash psql $NUXT_PRIVATE_DATABASE_URL -c "SELECT version();" ``` 3. **Check firewall rules**: Ensure your database accepts connections from your deployment 4. **SSL/TLS issues**: Some providers require SSL. Try adding `?sslmode=require` to your connection string ## Turborepo cache issues If builds are failing or using stale code: ```bash # Clear Turborepo cache pnpm exec turbo clean # Clear node_modules and reinstall rm -rf node_modules pnpm install ``` ## Layer resolution issues If layers aren't being found: 1. **Ensure layers are built**: Run `pnpm build` from root 2. **Check workspace configuration**: Verify `pnpm-workspace.yaml` includes your layers 3. **Reference by name, not path**: Use `'layer-auth'` not `'../packages/layer-auth'` ## Better-auth session issues If users are being logged out unexpectedly: 1. **Check BETTER\_AUTH\_SECRET**: Must be at least 32 characters 2. **Verify BETTER\_AUTH\_URL**: Should match your actual domain 3. **Check database sessions**: Verify sessions table has entries ## Migration issues If migrations fail: ```bash # Reset migrations (WARNING: destroys data) pnpm db:drop pnpm db:generate pnpm db:migrate # Or manually apply SQL psql $NUXT_PRIVATE_DATABASE_URL < packages/layer-auth/server/db/migrations/XXXX.sql ``` ## Type errors in development If you're seeing TypeScript errors: ```bash # Regenerate types pnpm postinstall # Or manually nuxt prepare ``` ## Deployment fails Common deployment issues: 1. **Missing environment variables**: Double-check all required vars are set 2. **Database migrations not run**: Run `pnpm db:migrate` after deployment 3. **Build timeout**: Increase timeout in your platform settings 4. **Dependency installation**: Try `pnpm install --frozen-lockfile` ## Getting Help If you're still stuck: 1. Review the [GitHub issues](https://github.com/NuxtStarterKit/nuxtstarterkit/issues){rel=""nofollow""} 2. Contact support via email (available to customers) # LLMs This starter kit uses the [nuxt-llms](https://nuxt.com/modules/llms){rel=""nofollow""} module to automatically generate [`llms.txt`](https://llmstxt.org/){rel=""nofollow""} and `llms-full.txt` documentation files for your application. These files make your application's content discoverable and consumable by AI assistants and large language models. ## Configuration The module is configured in `nuxt.config.ts`: ```ts export default defineNuxtConfig({ modules: ['nuxt-llms'], llms: { domain: 'https://your-domain.com', title: 'Your Application', description: 'A short description of your application.', full: { title: 'Your Application – Full Documentation', description: 'Complete documentation of your application.', }, }, }) ``` After starting your application, visit `/llms.txt` and `/llms-full.txt` to see the generated documentation. ## Extending the Documentation You can dynamically extend both documentation formats via Nitro server plugins. ### llms.txt Use the `llms:generate` hook to add sections and links to `/llms.txt`: ```ts // server/plugins/llms.ts export default defineNitroPlugin((nitroApp) => { nitroApp.hooks.hook('llms:generate', async (event, options) => { options.sections.push({ title: 'API Documentation', description: 'REST API endpoints and usage.', links: [ { title: 'Authentication', description: 'API authentication methods.', href: `${options.domain}/api/auth`, }, ], }) }) }) ``` ### llms-full.txt Use the `llms:generate:full` hook to add free-form Markdown content to `/llms-full.txt`: ```ts // server/plugins/llms.ts export default defineNitroPlugin((nitroApp) => { nitroApp.hooks.hook('llms:generate:full', async (event, options, contents) => { contents.push(`## API Authentication Use a Bearer token in the \`Authorization\` header to authenticate requests.`) }) }) ``` ## Learn More - [nuxt-llms on GitHub](https://github.com/nuxt-content/nuxt-llms){rel=""nofollow""} - [llms.txt specification](https://llmstxt.org/){rel=""nofollow""} # How to Build a SaaS with Nuxt 4, better-auth, and Polar Building a SaaS on Nuxt is more approachable than ever. AI can scaffold pages, forms, and CRUD in minutes. The parts that still decide whether you ship are the same: **auth**, **payments**, **data**, and **security**. This guide outlines a modern stack: **Nuxt 4**, **better-auth**, and **Polar**. ## The product shape you are aiming for Most early SaaS apps need: 1. Users who can sign up and sign in 2. A paid plan (one-time or subscription) 3. An authenticated app area 4. An admin path for support and abuse cases 5. Deployability without locking into one host Everything else is product-specific. ## Step 1: Start with Nuxt 4 as the application shell Nuxt 4 gives you SSR/SPA flexibility, file-based routing, server routes, and a mature module ecosystem. For a SaaS, prefer: - TypeScript everywhere - Server routes for webhooks and privileged actions - Clear separation between marketing site and app (or shared layers if you use a monorepo) ## Step 2: Put better-auth at the center of identity [better-auth](https://better-auth.com/){rel=""nofollow""} is a strong fit when you want email/password, social providers, and modern auth features without owning a custom auth framework. Minimum production checklist: - Secure session cookies - Email verification / password reset flows - Rate-limited auth endpoints - Role or admin flag for privileged actions Do not treat auth as “done” when the login page works. Treat it as done when sessions, resets, and abuse controls exist. ## Step 3: Monetize with Polar as Merchant of Record [Polar](https://polar.sh/){rel=""nofollow""} is compelling for indie and solo founders because it can act as Merchant of Record — reducing tax and payment ops overhead compared to wiring everything yourself. You will still need: - Product/price configuration - Checkout links or embedded checkout - Webhook verification - Mapping Polar customers to your users The webhook handler is the heart of billing correctness. Design it to be idempotent from day one. ## Step 4: Add the unglamorous SaaS essentials These rarely show up in Twitter demos and always show up in real products: - Database migrations you trust - Admin user management - Basic auditability for support - Security headers and rate limits - Error monitoring This is also where a polished starter kit pays for itself. ## Where a starter kit saves weeks You can assemble Nuxt + better-auth + Polar yourself. Many people should. You should buy time when: - You have already rebuilt auth/payments twice - You want layer-based architecture instead of inventing structure under deadline - You would rather ship product features this month That is the problem [Nuxt Starter Kit](https://nuxtstarterkit.com) is built to solve: a production-minded Nuxt 4 SaaS foundation with auth, Polar payments, admin, and security already wired. ## Suggested build order (solo founder) 1. Auth + protected routes 2. Database models for users/plans 3. Checkout + webhook → entitlement 4. Core product loop 5. Admin + monitoring 6. Marketing pages and SEO content If step 1–3 are still open after a week, your foundation is the bottleneck — not your idea. ## Next steps - Browse the [docs](https://nuxtstarterkit.com/docs/getting-started) for the kit’s architecture - Compare scope on [pricing](https://nuxtstarterkit.com/pricing) - Or start from scratch with Nuxt, better-auth, and Polar using the checklist above # DIY vs Nuxt Starter Kit — The Real Cost of Auth and Payments “I can build that myself over a weekend” is the most expensive sentence in indie SaaS. You *can* build auth and payments yourself. The question is what it costs in calendar time — and what you postpone while you do it. ## What “DIY foundation” usually includes For a Nuxt SaaS MVP that you would trust with real customers: | Workstream | Realistic solo estimate | | ----------------------------------------- | ----------------------- | | Auth (email, social, sessions, resets) | 20–40 hours | | Payments + webhooks + entitlements | 15–30 hours | | Admin basics (users, bans, impersonation) | 10–20 hours | | Security headers, rate limits, hardening | 8–15 hours | | Monorepo/layer structure + DX polish | 10–20 hours | | Deploy, env, monitoring, edge cases | 10–20 hours | That is roughly **75–145 hours** before your actual product logic. At a conservative freelance rate of $100/hour, that is **$7.5k–$14.5k** of your time — not counting opportunity cost. ## Where DIY estimates go wrong People underestimate: - Webhook retries and duplicate events - Password reset abuse - Session invalidation after password change - Tax/MoR complexity for global sales - “Temporary” folder structure that becomes permanent debt - Upgrade work when Nuxt/auth/payment libs move AI helps generate code. It does not remove the need for correct system design. ## When DIY is the right call Build from scratch if: - Learning the full stack *is* the goal - Your product’s core IP *is* the billing/auth model - You need exotic constraints a kit cannot express - You enjoy infrastructure more than product Those are valid reasons. They are not the default for a solo founder validating a market. ## When a starter kit is the right call Buy a foundation if: - You have shipped (or abandoned) the same auth/payment setup before - You want to validate a product idea in weeks, not quarters - You value an opinionated architecture you can still own and modify - You would rather spend evenings on features users pay for ## Honest comparison | | DIY | Nuxt Starter Kit | | ----------------------- | ----------------------------- | ---------------------------------------------------------------- | | Upfront cash | $0 | One-time license ([pricing](https://nuxtstarterkit.com/pricing)) | | Time to secure baseline | Weeks | Hours to configure | | Ownership | Full | Full (you get the code) | | Risk | Unknown unknowns | Known opinionated defaults | | Best for | Learning / unique constraints | Shipping product faster | ## The decision in one sentence If foundation work delays your first paying user, DIY is probably the expensive option — even when the invoice is $0. If you want the Nuxt 4 + better-auth + Polar path without rebuilding it, start with [Nuxt Starter Kit](https://nuxtstarterkit.com) and put your hours into the product only you can build. # Nuxt Boilerplate for Solo Founders — Ship Without Rebuilding Foundations Solo founders do not lose months because they cannot write a Vue component. They lose months re-solving **shared infrastructure**: auth, billing, admin, security, and project structure. A good **Nuxt boilerplate** is leverage. A bad one is a costume party for technical debt. ## AI changed feature speed, not foundation risk In 2026, AI can generate: - CRUD screens - Marketing sections - Straightforward API handlers It still struggles to consistently deliver: - Correct auth session lifecycle - Payment webhook correctness - Safe admin impersonation - Coherent long-term architecture If your plan is “ChatGPT the whole SaaS,” you will still need a durable base. The boilerplate question is whether you invent that base or reuse one. ## What solo founders should optimize for ### 1. Time-to-first-paid-user Not stars on GitHub. Not perfect abstraction. **Days until someone can buy.** ### 2. Removable opinions You want structure, not a prison. Layers or packages you can delete beat a mega-template you must rewrite. ### 3. Vendor freedom Hosting lock-in is optional pain. Prefer a kit that deploys to common Node hosts. ### 4. One-time economics when possible Subscriptions for a boilerplate can make sense. For many founders, a one-time license matches the “own the code” mental model. ## A founder-friendly Nuxt stack A practical baseline: - **Nuxt 4** application framework - **better-auth** for authentication - **PostgreSQL + Drizzle** for data - **Polar** for payments / MoR - Security defaults (headers, rate limits) - Admin tooling for support reality That stack is what [Nuxt Starter Kit](https://nuxtstarterkit.com) packages so you start on product work sooner. ## How to use a boilerplate without becoming dependent 1. Buy/use the kit for foundations 2. Delete layers you do not need 3. Keep product domain code clearly separated 4. Pull upstream updates only when they reduce risk 5. Write your own tests around billing and auth paths you care about The goal is not “never touch infrastructure.” The goal is “do not rebuild infrastructure every project.” ## Content and distribution still matter A strong kit does not invent distribution. Once the product works, you still need: - SEO pages that answer buyer questions - A demo people can click - Proof from real projects - Places Nuxt developers already gather (This blog exists for that reason.) ## Bottom line If you are a solo founder building on Nuxt, your scarce resource is focus. Spend it on the unique product loop — not on re-implementing sessions and webhooks for the third time. Explore the [docs](https://nuxtstarterkit.com/docs/getting-started), see [what’s included](https://nuxtstarterkit.com/pricing), or open the [demo](https://demo.nuxtstarterkit.com){rel=""nofollow""} and decide if the foundation matches how you ship. # Best Nuxt SaaS Boilerplate in 2026 — What Actually Matters If you are searching for a **Nuxt SaaS boilerplate**, you are probably not looking for another “hello world” template. You want a foundation that survives real users, real payments, and real security reviews. Here is what to evaluate before you commit time (or money) to any starter. ## 1. Auth that is production-shaped, not demo-shaped Login screens are easy. Secure sessions are not. Look for: - Email/password plus social login - Session hardening (CSRF, secure cookies, rate limits) - Passkeys or MFA when you need them - Admin tools for bans, impersonation, and user management If the starter only shows a login form wired to a toy auth library, you will rebuild the hard parts later. ## 2. Payments with Merchant of Record options For solo founders, payments are rarely “just Stripe Checkout.” You also need: - Webhook handling that is idempotent - Subscription lifecycle events - Tax / MoR considerations when selling globally A serious Nuxt boilerplate should include a payment path you can ship with — not a half-finished checkout page. ## 3. Architecture you will still like in six months AI can generate features quickly. It does not invent a maintainable architecture for you. Prefer starters that give you: - Clear module boundaries (layers or packages) - Type-safe database access and migrations - A path to grow from MVP to multi-feature product Monorepo + Nuxt layers is a strong pattern when you want optional features (blog, admin, payments) without a ball of mud. ## 4. Security defaults, not a README promise Check whether the kit configures: - Secure HTTP headers / CSP direction - Rate limiting on sensitive endpoints - Sensible secrets handling Security bolted on after launch is expensive. Defaults matter. ## 5. Maintenance signal Ask: - Is it tracking Nuxt major versions? - Are dependencies current? - Can you pull upstream updates without a rewrite? An abandoned boilerplate is a liability. An actively maintained one compounds. ## How Nuxt Starter Kit fits [Nuxt Starter Kit](https://nuxtstarterkit.com) is built for solo founders who want a **Nuxt 4** foundation with **better-auth**, **Polar** payments, admin tooling, and security defaults — structured as a Turborepo of Nuxt layers you can keep or remove. If that matches your checklist, compare the full feature set on [pricing](https://nuxtstarterkit.com/pricing) or try the [live demo](https://demo.nuxtstarterkit.com){rel=""nofollow""}. ## Quick decision framework | Need | Weak starter | Strong starter | | --------- | ----------------------- | ------------------------------ | | Auth | Login UI only | Sessions, social, admin ops | | Payments | Stripe button | Webhooks + billing lifecycle | | Structure | Flat folders | Layers / monorepo boundaries | | Security | “Add later” | Headers + rate limits included | | Updates | Last commit 2 years ago | Ongoing Nuxt upgrades | Choose the right column once. Rebuilding foundations mid-product is where months disappear. ## About Nuxt Starter Kit The Nuxt SaaS boilerplate with auth, payments, admin dashboard, and security pre-configured. Save 100+ hours of setup and ship your product faster. ## Key Features - Authentication (email, social, passkeys) via better-auth - Payments and billing via Polar - Admin dashboard with user management - Security hardening with Nuxt Security - Turborepo monorepo with Nuxt 4 layers ## Links - Demo: https://demo.nuxtstarterkit.com - GitHub: https://github.com/NuxtStarterKit/nuxtstarterkit