Getting Started

Technical Details

Architecture and technology stack of LaunchDayOne Nuxt boilerplate.

Technology Stack

LaunchDayOne uses Nuxt 4, Better Auth, Drizzle ORM, Nuxt UI, Zod, AWS S3, Pinia, and more.

Core Technologies

Nuxt 4

Modern Vue.js framework with SSR, SSG, and ISR support. Configured with typed pages, cookie store, and dev logs.

Better Auth

Authentication system with email/password + social providers (Google, GitHub). Includes email verification flows.

Drizzle ORM

Type-safe SQL ORM with Zod schema integration. Supports PostgreSQL with migration tooling.

Nuxt UI

Component library built on Tailwind CSS. Provides accessible, customizable UI primitives.

Zod

Runtime type validation for API routes, forms, and data schemas with TypeScript inference.

Pinia

Vue state management with SSR support, type safety, and devtools integration.

AWS S3

Cloud file storage via Nitro storage layer. Falls back to local filesystem in dev.

Nuxt Email Renderer

Email template rendering with component-based authoring and HTML output.

Project Structure

LaunchDayOne follows Nuxt conventions with organized separation of concerns:

LaunchDayOne/
├── app/                    # Application code
│   ├── assets/            # CSS, icons, images
│   ├── components/        # Vue components
│   ├── composables/       # Reusable composition functions
│   ├── layouts/           # Page layouts
│   ├── middleware/        # Route middleware
│   ├── pages/             # File-based routing
│   └── utils/             # App utilities
├── server/                # Server-side code
│   ├── api/              # API routes
│   ├── db/               # Database schema & client
│   ├── libs/             # Server libraries (auth, etc.)
│   ├── middleware/       # Server middleware
│   ├── tasks/            # Scheduled tasks
│   └── utils/            # Server utilities
├── shared/               # Shared between app & server
│   ├── schemas/          # Zod schemas
│   └── utils/            # Shared utilities
├── emails/               # Email templates
├── content/              # Nuxt Content docs
├── public/               # Static files
└── nuxt.config.ts        # Nuxt configuration
Auto-imports: Components, composables, and utilities are auto-imported. No manual imports needed.

Database & ORM

Drizzle ORM Setup

  • Driver: postgres (PostgreSQL)
  • Schema: Located in server/db/schema/
  • Zod Integration: Use createSelectSchema for type-safe validation

Storage Layer

Nitro storage abstraction handles file uploads:

  • Production: AWS S3 via s3 driver
  • Development: Local filesystem at public/.tmp/

Authentication Architecture

Located in server/libs/auth/index.ts, Better Auth provides:

  • Email/password authentication
  • Social OAuth (Google, GitHub)
  • Email verification system
  • Session management with cookies

Environment Configuration

All environment variables are validated using Zod at startup in shared/libs/env.ts. This ensures type-safety and catches missing/invalid config before runtime.

shared/libs/env.ts
const EnvSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']),
  NUXT_PUBLIC_APP_NAME: z.string(),
  DATABASE_URL: z.string(),
  BETTER_AUTH_SECRET: z.string(),
  // ...
})

const parseResult = EnvSchema.safeParse(process.env)
if (!parseResult.success) {
  console.error(z.prettifyError(parseResult.error))
  process.exit(1)
}

export default parseResult.data

Import and use validated env:

import env from '~~/shared/libs/env'

env.DATABASE_URL // Type-safe, guaranteed to exist

Email System

Nuxt Email Renderer

  • Templates in emails/ using Vue components
  • Development preview available

Email Configuration

Configured in nuxt.config.ts under runtimeConfig.mail:

nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    mail: {
      adminEmails: env.ADMIN_EMAILS,
      from: {
        email: process.env.NODE_ENV === 'development'
          ? 'no-reply@example.com'
          : `no-reply@${env.NUXT_PUBLIC_APP_DOMAIN}`,
        name: env.NUXT_PUBLIC_APP_NAME,
      },
    },
    // ...
  },
})

Scheduled Tasks

Nitro tasks run server-side on schedule:

nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    experimental: {
      tasks: true,
    },
    scheduledTasks: {
      [CRON_SCHEDULES_PRESET.EVERY_DAY]: ['liftBan'],
    },
  },
})

Task handlers in server/tasks/:

server/tasks/liftBan.ts
export default defineTask({
  meta: {
    name: 'liftBan',
    description: 'Lift user bans',
  },
  async run() {
    const result = await db.query.user.findMany({
      where: and(
        eq(tableUser.banned, true),
        isNotNull(tableUser.banExpires),
        lt(tableUser.banExpires, new Date().toISOString()),
      ),
    })

    // Lift expired bans...
    return { result: userIds }
  },
})

Deployment

Zero-Config Hosting

See Nuxt deployment docs for all hosting options.

Developer Experience

Code Quality

Modularity

Nuxt Modules Installed

Adding/Removing Features

Most features can be removed by:

  1. Removing the module from nuxt.config.ts
  2. Deleting related code in app/, server/
  3. Cleaning up dependencies in package.json
Core features (Better Auth, Drizzle, Zod) are tightly integrated. Removal requires significant refactoring.

Copyright © 2025