A modern, production-ready starter template for building full-stack applications with Next.js 15.3, Supabase, TypeScript, and Tailwind CSS v4.
- Next.js 15.3 with App Router and Server Components
- Supabase for authentication and database
- TypeScript with strict mode for type safety
- Tailwind CSS v4 for modern styling
- shadcn/ui component library
- Authentication - Complete auth flow with sign up, sign in, and protected routes
- Database Migrations - Migration-first development with type generation
- Vitest for testing
- Zod for schema validation
- Pre-configured development tools (ESLint, Prettier)
- Node.js 18+
- npm/yarn/pnpm
- Supabase CLI (
brew install supabase/tap/supabase
)
git clone <your-repo-url>
cd my-app
npm install
Start local Supabase development stack:
npm run db:start
This will output your local Supabase credentials. Update .env.local
:
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
npm run dev
Open http://localhost:3000 to see your app.
├── app/ # Next.js App Router
│ ├── (auth)/ # Auth routes (signin, signup)
│ ├── (dashboard)/ # Protected dashboard routes
│ └── layout.tsx # Root layout
├── components/
│ ├── ui/ # shadcn/ui components
│ └── features/ # Feature-specific components
│ └── auth/ # Auth form components
├── lib/
│ ├── supabase/ # Supabase client configs
│ ├── env.ts # Environment validation
│ └── utils.ts # Utility functions
├── server/
│ ├── actions/ # Server Actions
│ │ └── auth.ts # Auth actions (signUp, signIn, signOut)
│ └── queries/ # Database queries
├── hooks/ # React hooks
├── supabase/
│ ├── migrations/ # Database migrations
│ └── config.toml # Supabase configuration
├── types/ # TypeScript types
│ └── supabase.ts # Generated DB types
└── middleware.ts # Auth middleware
# Development
npm run dev # Start dev server with Turbopack
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLint
# Database
npm run db:start # Start local Supabase
npm run db:stop # Stop local Supabase
npm run db:reset # Reset database
npm run db:types # Generate TypeScript types
npm run db:push # Push migrations to remote
# Testing
npm run test # Run tests in watch mode
npm run test:ui # Open Vitest UI
- Create a migration:
supabase migration new create_posts_table
- Apply locally and regenerate types:
npm run db:reset
npm run db:types
npx shadcn@latest add button card dialog
- Use Server Components by default
- Add
'use client'
only when needed - Separate server and client Supabase instances
- Use Server Actions for mutations
Write tests for:
- Business logic in utilities and hooks
- Server Actions with mocked Supabase
- Component behavior (not visual appearance)
- Error states and edge cases
npm run test
// ✅ Server Component (default)
export default async function Page() {
const data = await getServerData()
return <ClientComponent initialData={data} />
}
// Client-side (browser)
import { createClient } from '@/lib/supabase/client'
// Server-side (Node.js)
import { createClient } from '@/lib/supabase/server'
import type { Database } from '@/types/supabase'
type Post = Database['public']['Tables']['posts']['Row']
The starter includes a complete auth setup:
- Sign up/in pages at
/signup
and/signin
- Protected routes under
(dashboard)
- Server actions for auth operations
- Automatic profile creation on signup
- Session management via middleware
- Always regenerate types after schema changes
- Use migrations for all database changes
- Enable RLS on all tables
- Validate environment variables with Zod
- Test business logic, not implementation details
Required environment variables:
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
- Create feature branch
- Make changes following the patterns in CLAUDE.md
- Write/update tests
- Submit PR
MIT