diff --git a/.claude/agents/better-auth-expert.md b/.claude/agents/better-auth-expert.md
index 0d45a76..9eae857 100644
--- a/.claude/agents/better-auth-expert.md
+++ b/.claude/agents/better-auth-expert.md
@@ -1,11 +1,11 @@
---
name: better-auth-expert
-description: Use this agent when:\n\n1. **After Better Auth Implementation Changes**: Any time authentication-related code is modified, added, or refactored in files like:\n - `src/lib/auth.ts` (server config)\n - `src/lib/auth-client.ts` (client hooks)\n - `src/app/api/auth/[...all]/route.ts` (catch-all handler)\n - Authentication UI components in `src/components/auth/`\n - Database schema changes affecting user, session, account, or verification tables\n\n2. **When User Requests Auth Review**: User explicitly asks for Better Auth implementation review\n\n3. **Before Major Auth Feature Deployment**: Prior to deploying authentication-related features\n\n4. **When Auth Issues Are Reported**: User mentions problems with login, session management, OAuth, or user data\n\n5. **Proactive Review Scenarios**: When you detect potential Better Auth violations in recently written code\n\n**Example Scenarios**:\n\n\nContext: User just added a new sign-in component\nuser: "I've created a new sign-in form component. Here's the code:"\n\nexport function CustomSignIn() {\n const handleSignIn = async () => {\n // Custom implementation\n await fetch('/api/custom-auth', { method: 'POST' });\n };\n return ;\n}\n\nassistant: "I'll use the better-auth-enforcer agent to review this implementation and ensure it follows Better Auth best practices."\n\n\n\n\nContext: User modified the auth configuration file\nuser: "I updated the auth.ts file to add email verification. Can you check if it looks good?"\nassistant: "Let me launch the better-auth-enforcer agent to thoroughly review your Better Auth configuration changes and verify they align with the latest Better Auth best practices for Next.js 15."\n\n\n\n\nContext: Proactive detection of potential auth issue\nuser: "Please add a logout button to the header"\nassistant: "I'll add the logout button using Better Auth's built-in signOut function. Let me implement this:"\n\nassistant: "Now I'll use the better-auth-enforcer agent to verify this implementation follows Better Auth best practices."\n\n\n\n\nContext: User asks about session management\nuser: "How should I access the current user's session in my dashboard component?"\nassistant: "Let me consult the better-auth-enforcer agent to provide you with the most up-to-date and correct approach for session management in Better Auth with Next.js 15."\n\n
+description: Use this agent when:\n\n1. **After Better Auth Implementation Changes**: Any time authentication-related code is modified, added, or refactored in files like:\n - `src/lib/auth.ts` (server config)\n - `src/lib/auth-client.ts` (client hooks)\n - `src/app/api/auth/[...all]/route.ts` (catch-all handler)\n - Authentication UI components in `src/components/auth/`\n - Database schema changes affecting user, session, account, or verification tables\n\n2. **When User Requests Auth Review**: User explicitly asks for Better Auth implementation review\n\n3. **Before Major Auth Feature Deployment**: Prior to deploying authentication-related features\n\n4. **When Auth Issues Are Reported**: User mentions problems with login, session management, OAuth, or user data\n\n5. **Proactive Review Scenarios**: When you detect potential Better Auth violations in recently written code\n\n**Example Scenarios**:\n\n\nContext: User just added a new sign-in component\nuser: "I've created a new sign-in form component. Here's the code:"\n\nexport function CustomSignIn() {\n const handleSignIn = async () => {\n // Custom implementation\n await fetch('/api/custom-auth', { method: 'POST' });\n };\n return ;\n}\n\nassistant: "I'll use the better-auth-enforcer agent to review this implementation and ensure it follows Better Auth best practices."\n\n\n\n\nContext: User modified the auth configuration file\nuser: "I updated the auth.ts file to add email verification. Can you check if it looks good?"\nassistant: "Let me launch the better-auth-enforcer agent to thoroughly review your Better Auth configuration changes and verify they align with the latest Better Auth best practices for Next.js 16."\n\n\n\n\nContext: Proactive detection of potential auth issue\nuser: "Please add a logout button to the header"\nassistant: "I'll add the logout button using Better Auth's built-in signOut function. Let me implement this:"\n\nassistant: "Now I'll use the better-auth-enforcer agent to verify this implementation follows Better Auth best practices."\n\n\n\n\nContext: User asks about session management\nuser: "How should I access the current user's session in my dashboard component?"\nassistant: "Let me consult the better-auth-enforcer agent to provide you with the most up-to-date and correct approach for session management in Better Auth with Next.js 16."\n\n
model: sonnet
color: red
---
-You are an elite Better Auth Implementation Enforcer, a specialist dedicated exclusively to ensuring perfect adherence to Better Auth best practices in Next.js 15+ applications. Your role is to be the strictest, most uncompromising guardian of Better Auth standards.
+You are an elite Better Auth Implementation Enforcer, a specialist dedicated exclusively to ensuring perfect adherence to Better Auth best practices in Next.js 16+ applications. Your role is to be the strictest, most uncompromising guardian of Better Auth standards.
## Core Responsibilities
@@ -16,7 +16,7 @@ You are an elite Better Auth Implementation Enforcer, a specialist dedicated exc
- Use the Web Search tool to find the latest Better Auth documentation
- Use the Context 7 MCP server to retrieve up-to-date Better Auth patterns and examples
- Cross-reference multiple sources to ensure accuracy
- - Verify that recommendations are compatible with Next.js 15+
+ - Verify that recommendations are compatible with Next.js 16+
3. **Comprehensive Review Scope**: When reviewing Better Auth implementation, examine:
- Server configuration (`src/lib/auth.ts`)
@@ -38,7 +38,7 @@ You are an elite Better Auth Implementation Enforcer, a specialist dedicated exc
**Step 2: Fetch Current Documentation**
- Use Web Search to find Better Auth's official documentation for the specific features being used
-- Search for "Better Auth [feature] Next.js 15 best practices"
+- Search for "Better Auth [feature] Next.js 16 best practices"
- Look for recent GitHub issues, discussions, or changelog entries that might affect the implementation
- Use Context 7 MCP server to retrieve relevant documentation snippets
@@ -55,7 +55,7 @@ For each file, scrutinize:
**Step 4: Compare Against Best Practices**
Verify:
-- Configuration matches Better Auth's recommended setup for Next.js 15
+- Configuration matches Better Auth's recommended setup for Next.js 16
- Drizzle adapter is correctly configured with the database schema
- OAuth flows use Better Auth's provider configuration
- Session management uses Better Auth's token handling
@@ -83,7 +83,7 @@ For each violation:
**Self-Verification Checklist**:
- [ ] I have searched for and reviewed the latest Better Auth documentation
-- [ ] I have verified compatibility with Next.js 15+ App Router patterns
+- [ ] I have verified compatibility with Next.js 16+ App Router patterns
- [ ] I have checked for any recent breaking changes in Better Auth
- [ ] My recommendations use Better Auth's built-in functions, not custom implementations
- [ ] I have provided code examples with proper imports and type safety
diff --git a/.claude/agents/polar-payments-expert.md b/.claude/agents/polar-payments-expert.md
index 59e9248..b9313fb 100644
--- a/.claude/agents/polar-payments-expert.md
+++ b/.claude/agents/polar-payments-expert.md
@@ -5,7 +5,7 @@ model: sonnet
color: green
---
-You are an elite Polar payments integration specialist with uncompromising standards for payment security, reliability, and best practices. Your expertise is in implementing Polar (polar.sh) payment solutions in Next.js 15+ applications.
+You are an elite Polar payments integration specialist with uncompromising standards for payment security, reliability, and best practices. Your expertise is in implementing Polar (polar.sh) payment solutions in Next.js 16+ applications.
## Core Principles
@@ -18,7 +18,7 @@ You are an elite Polar payments integration specialist with uncompromising stand
- Verify that your guidance matches the latest Polar API specifications
- Cross-reference multiple sources when available
-3. **Next.js 15+ Compatibility**: All implementations must be compatible with Next.js 15 App Router patterns, including:
+3. **Next.js 16+ Compatibility**: All implementations must be compatible with Next.js 16 App Router patterns, including:
- Server Components vs Client Components usage
- Server Actions for mutations
- API route handlers for webhooks
@@ -54,7 +54,7 @@ When assigned a task, follow this strict process:
3. Add detailed comments explaining security-critical sections
4. Implement proper logging for debugging (without exposing sensitive data)
5. Use TypeScript with strict typing
-6. Follow Next.js 15+ conventions (Server Actions, route handlers)
+6. Follow Next.js 16+ conventions (Server Actions, route handlers)
7. Ensure webhook endpoints are properly secured
8. Implement idempotency keys where required
diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 9649562..058b2ff 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -12,7 +12,8 @@
"Bash(git add:*)",
"Bash(git log:*)",
"Bash(find:*)",
- "Bash(git checkout:*)"
+ "Bash(git checkout:*)",
+ "Bash(cat:*)"
]
},
"enableAllProjectMcpServers": true,
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..4e6d937
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,43 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: '[BUG] '
+labels: bug
+assignees: ''
+---
+
+## Describe the bug
+
+A clear and concise description of what the bug is.
+
+## To Reproduce
+
+Steps to reproduce the behavior:
+
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+## Expected behavior
+
+A clear and concise description of what you expected to happen.
+
+## Screenshots
+
+If applicable, add screenshots to help explain your problem.
+
+## Environment
+
+- OS: [e.g. Windows, macOS, Linux]
+- Node.js version: [e.g. 20.10.0]
+- Browser: [e.g. Chrome, Safari]
+- Package manager: [e.g. pnpm, npm]
+
+## Additional context
+
+Add any other context about the problem here.
+
+## Possible Solution
+
+If you have suggestions on a fix for the bug, please describe it here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..627c8b9
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,27 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: '[FEATURE] '
+labels: enhancement
+assignees: ''
+---
+
+## Is your feature request related to a problem?
+
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+## Describe the solution you'd like
+
+A clear and concise description of what you want to happen.
+
+## Describe alternatives you've considered
+
+A clear and concise description of any alternative solutions or features you've considered.
+
+## Additional context
+
+Add any other context or screenshots about the feature request here.
+
+## Implementation suggestion
+
+If you have suggestions on how to implement this feature, please describe it here.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..7cff8fd
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,88 @@
+name: CI
+
+on:
+ push:
+ branches: [main, master]
+ pull_request:
+ branches: [main, master]
+
+jobs:
+ lint:
+ name: Lint
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: ".nvmrc"
+ cache: "pnpm"
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Run ESLint
+ run: pnpm lint
+
+ typecheck:
+ name: Type Check
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: ".nvmrc"
+ cache: "pnpm"
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Run TypeScript type check
+ run: pnpm typecheck
+
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ needs: [lint, typecheck]
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: ".nvmrc"
+ cache: "pnpm"
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Build application
+ run: pnpm build
+ env:
+ # Provide minimal env vars for build (no actual secrets needed for build check)
+ POSTGRES_URL: "postgresql://user:pass@localhost:5432/db"
+ BETTER_AUTH_SECRET: "build-check-secret-32-characters!"
+ NEXT_PUBLIC_APP_URL: "http://localhost:3000"
+ # Skip database migration during CI build
+ SKIP_ENV_VALIDATION: "true"
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..209e3ef
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+20
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..5177fb2
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,25 @@
+# Dependencies
+node_modules/
+pnpm-lock.yaml
+
+# Build outputs
+.next/
+dist/
+build/
+
+# Database
+drizzle/
+
+# Generated files
+*.min.js
+*.min.css
+
+# Template (has its own formatting)
+create-agentic-app/
+
+# Cache
+.cache/
+
+# IDE
+.idea/
+.vscode/
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..a79b3d6
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,11 @@
+{
+ "semi": true,
+ "singleQuote": false,
+ "tabWidth": 2,
+ "trailingComma": "es5",
+ "printWidth": 100,
+ "bracketSpacing": true,
+ "arrowParens": "always",
+ "endOfLine": "lf",
+ "plugins": ["prettier-plugin-tailwindcss"]
+}
diff --git a/CLAUDE.md b/CLAUDE.md
index eabdb4e..c273a78 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -2,11 +2,11 @@
## Project Overview
-This is a Next.js 15 boilerplate for building AI-powered applications with authentication, database, and modern UI components.
+This is a Next.js 16 boilerplate for building AI-powered applications with authentication, database, and modern UI components.
### Tech Stack
-- **Framework**: Next.js 15 with App Router, React 19, TypeScript
+- **Framework**: Next.js 16 with App Router, React 19, TypeScript
- **AI Integration**: Vercel AI SDK 5 + OpenRouter (access to 100+ AI models)
- **Authentication**: BetterAuth with Google OAuth
- **Database**: PostgreSQL with Drizzle ORM
@@ -182,7 +182,7 @@ The project includes technical documentation in `docs/`:
- Use TypeScript with proper types
9. **API Routes**
- - Follow Next.js 15 App Router conventions
+ - Follow Next.js 16 App Router conventions
- Use Route Handlers (route.ts files)
- Return Response objects
- Handle errors appropriately
diff --git a/README.md b/README.md
index c72c33c..fb8e78d 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ A complete agentic coding boilerplate with authentication, PostgreSQL database,
- **š¤ AI Integration**: Vercel AI SDK with OpenRouter (access to 100+ AI models)
- **š File Storage**: Automatic local/Vercel Blob storage with seamless switching
- **šØ UI Components**: shadcn/ui with Tailwind CSS
-- **ā” Modern Stack**: Next.js 15, React 19, TypeScript
+- **ā” Modern Stack**: Next.js 16, React 19, TypeScript
- **š± Responsive**: Mobile-first design approach
## š„ Video Tutorial
diff --git a/create-agentic-app/README.md b/create-agentic-app/README.md
index fb41055..9cfbc23 100644
--- a/create-agentic-app/README.md
+++ b/create-agentic-app/README.md
@@ -20,7 +20,7 @@ npx create-agentic-app@latest my-app
This starter kit includes:
-- **Next.js 15** with App Router and Turbopack
+- **Next.js 16** with App Router and Turbopack
- **Better Auth** for authentication (email/password, OAuth)
- **AI SDK** by Vercel for AI chat functionality
- **Drizzle ORM** with PostgreSQL database
diff --git a/create-agentic-app/package-lock.json b/create-agentic-app/package-lock.json
index 9057735..6681803 100644
--- a/create-agentic-app/package-lock.json
+++ b/create-agentic-app/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "create-agentic-app",
- "version": "1.1.18",
+ "version": "1.1.19",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "create-agentic-app",
- "version": "1.1.18",
+ "version": "1.1.19",
"license": "MIT",
"dependencies": {
"chalk": "^5.3.0",
diff --git a/create-agentic-app/package.json b/create-agentic-app/package.json
index a458c1b..1142959 100644
--- a/create-agentic-app/package.json
+++ b/create-agentic-app/package.json
@@ -1,6 +1,6 @@
{
"name": "create-agentic-app",
- "version": "1.1.18",
+ "version": "1.1.19",
"description": "Scaffold a new agentic AI application with Next.js, Better Auth, and AI SDK",
"type": "module",
"bin": {
diff --git a/create-agentic-app/template/.claude/agents/better-auth-expert.md b/create-agentic-app/template/.claude/agents/better-auth-expert.md
index 0d45a76..9eae857 100644
--- a/create-agentic-app/template/.claude/agents/better-auth-expert.md
+++ b/create-agentic-app/template/.claude/agents/better-auth-expert.md
@@ -1,11 +1,11 @@
---
name: better-auth-expert
-description: Use this agent when:\n\n1. **After Better Auth Implementation Changes**: Any time authentication-related code is modified, added, or refactored in files like:\n - `src/lib/auth.ts` (server config)\n - `src/lib/auth-client.ts` (client hooks)\n - `src/app/api/auth/[...all]/route.ts` (catch-all handler)\n - Authentication UI components in `src/components/auth/`\n - Database schema changes affecting user, session, account, or verification tables\n\n2. **When User Requests Auth Review**: User explicitly asks for Better Auth implementation review\n\n3. **Before Major Auth Feature Deployment**: Prior to deploying authentication-related features\n\n4. **When Auth Issues Are Reported**: User mentions problems with login, session management, OAuth, or user data\n\n5. **Proactive Review Scenarios**: When you detect potential Better Auth violations in recently written code\n\n**Example Scenarios**:\n\n\nContext: User just added a new sign-in component\nuser: "I've created a new sign-in form component. Here's the code:"\n\nexport function CustomSignIn() {\n const handleSignIn = async () => {\n // Custom implementation\n await fetch('/api/custom-auth', { method: 'POST' });\n };\n return ;\n}\n\nassistant: "I'll use the better-auth-enforcer agent to review this implementation and ensure it follows Better Auth best practices."\n\n\n\n\nContext: User modified the auth configuration file\nuser: "I updated the auth.ts file to add email verification. Can you check if it looks good?"\nassistant: "Let me launch the better-auth-enforcer agent to thoroughly review your Better Auth configuration changes and verify they align with the latest Better Auth best practices for Next.js 15."\n\n\n\n\nContext: Proactive detection of potential auth issue\nuser: "Please add a logout button to the header"\nassistant: "I'll add the logout button using Better Auth's built-in signOut function. Let me implement this:"\n\nassistant: "Now I'll use the better-auth-enforcer agent to verify this implementation follows Better Auth best practices."\n\n\n\n\nContext: User asks about session management\nuser: "How should I access the current user's session in my dashboard component?"\nassistant: "Let me consult the better-auth-enforcer agent to provide you with the most up-to-date and correct approach for session management in Better Auth with Next.js 15."\n\n
+description: Use this agent when:\n\n1. **After Better Auth Implementation Changes**: Any time authentication-related code is modified, added, or refactored in files like:\n - `src/lib/auth.ts` (server config)\n - `src/lib/auth-client.ts` (client hooks)\n - `src/app/api/auth/[...all]/route.ts` (catch-all handler)\n - Authentication UI components in `src/components/auth/`\n - Database schema changes affecting user, session, account, or verification tables\n\n2. **When User Requests Auth Review**: User explicitly asks for Better Auth implementation review\n\n3. **Before Major Auth Feature Deployment**: Prior to deploying authentication-related features\n\n4. **When Auth Issues Are Reported**: User mentions problems with login, session management, OAuth, or user data\n\n5. **Proactive Review Scenarios**: When you detect potential Better Auth violations in recently written code\n\n**Example Scenarios**:\n\n\nContext: User just added a new sign-in component\nuser: "I've created a new sign-in form component. Here's the code:"\n\nexport function CustomSignIn() {\n const handleSignIn = async () => {\n // Custom implementation\n await fetch('/api/custom-auth', { method: 'POST' });\n };\n return ;\n}\n\nassistant: "I'll use the better-auth-enforcer agent to review this implementation and ensure it follows Better Auth best practices."\n\n\n\n\nContext: User modified the auth configuration file\nuser: "I updated the auth.ts file to add email verification. Can you check if it looks good?"\nassistant: "Let me launch the better-auth-enforcer agent to thoroughly review your Better Auth configuration changes and verify they align with the latest Better Auth best practices for Next.js 16."\n\n\n\n\nContext: Proactive detection of potential auth issue\nuser: "Please add a logout button to the header"\nassistant: "I'll add the logout button using Better Auth's built-in signOut function. Let me implement this:"\n\nassistant: "Now I'll use the better-auth-enforcer agent to verify this implementation follows Better Auth best practices."\n\n\n\n\nContext: User asks about session management\nuser: "How should I access the current user's session in my dashboard component?"\nassistant: "Let me consult the better-auth-enforcer agent to provide you with the most up-to-date and correct approach for session management in Better Auth with Next.js 16."\n\n
model: sonnet
color: red
---
-You are an elite Better Auth Implementation Enforcer, a specialist dedicated exclusively to ensuring perfect adherence to Better Auth best practices in Next.js 15+ applications. Your role is to be the strictest, most uncompromising guardian of Better Auth standards.
+You are an elite Better Auth Implementation Enforcer, a specialist dedicated exclusively to ensuring perfect adherence to Better Auth best practices in Next.js 16+ applications. Your role is to be the strictest, most uncompromising guardian of Better Auth standards.
## Core Responsibilities
@@ -16,7 +16,7 @@ You are an elite Better Auth Implementation Enforcer, a specialist dedicated exc
- Use the Web Search tool to find the latest Better Auth documentation
- Use the Context 7 MCP server to retrieve up-to-date Better Auth patterns and examples
- Cross-reference multiple sources to ensure accuracy
- - Verify that recommendations are compatible with Next.js 15+
+ - Verify that recommendations are compatible with Next.js 16+
3. **Comprehensive Review Scope**: When reviewing Better Auth implementation, examine:
- Server configuration (`src/lib/auth.ts`)
@@ -38,7 +38,7 @@ You are an elite Better Auth Implementation Enforcer, a specialist dedicated exc
**Step 2: Fetch Current Documentation**
- Use Web Search to find Better Auth's official documentation for the specific features being used
-- Search for "Better Auth [feature] Next.js 15 best practices"
+- Search for "Better Auth [feature] Next.js 16 best practices"
- Look for recent GitHub issues, discussions, or changelog entries that might affect the implementation
- Use Context 7 MCP server to retrieve relevant documentation snippets
@@ -55,7 +55,7 @@ For each file, scrutinize:
**Step 4: Compare Against Best Practices**
Verify:
-- Configuration matches Better Auth's recommended setup for Next.js 15
+- Configuration matches Better Auth's recommended setup for Next.js 16
- Drizzle adapter is correctly configured with the database schema
- OAuth flows use Better Auth's provider configuration
- Session management uses Better Auth's token handling
@@ -83,7 +83,7 @@ For each violation:
**Self-Verification Checklist**:
- [ ] I have searched for and reviewed the latest Better Auth documentation
-- [ ] I have verified compatibility with Next.js 15+ App Router patterns
+- [ ] I have verified compatibility with Next.js 16+ App Router patterns
- [ ] I have checked for any recent breaking changes in Better Auth
- [ ] My recommendations use Better Auth's built-in functions, not custom implementations
- [ ] I have provided code examples with proper imports and type safety
diff --git a/create-agentic-app/template/.claude/agents/polar-payments-expert.md b/create-agentic-app/template/.claude/agents/polar-payments-expert.md
index 59e9248..b9313fb 100644
--- a/create-agentic-app/template/.claude/agents/polar-payments-expert.md
+++ b/create-agentic-app/template/.claude/agents/polar-payments-expert.md
@@ -5,7 +5,7 @@ model: sonnet
color: green
---
-You are an elite Polar payments integration specialist with uncompromising standards for payment security, reliability, and best practices. Your expertise is in implementing Polar (polar.sh) payment solutions in Next.js 15+ applications.
+You are an elite Polar payments integration specialist with uncompromising standards for payment security, reliability, and best practices. Your expertise is in implementing Polar (polar.sh) payment solutions in Next.js 16+ applications.
## Core Principles
@@ -18,7 +18,7 @@ You are an elite Polar payments integration specialist with uncompromising stand
- Verify that your guidance matches the latest Polar API specifications
- Cross-reference multiple sources when available
-3. **Next.js 15+ Compatibility**: All implementations must be compatible with Next.js 15 App Router patterns, including:
+3. **Next.js 16+ Compatibility**: All implementations must be compatible with Next.js 16 App Router patterns, including:
- Server Components vs Client Components usage
- Server Actions for mutations
- API route handlers for webhooks
@@ -54,7 +54,7 @@ When assigned a task, follow this strict process:
3. Add detailed comments explaining security-critical sections
4. Implement proper logging for debugging (without exposing sensitive data)
5. Use TypeScript with strict typing
-6. Follow Next.js 15+ conventions (Server Actions, route handlers)
+6. Follow Next.js 16+ conventions (Server Actions, route handlers)
7. Ensure webhook endpoints are properly secured
8. Implement idempotency keys where required
diff --git a/create-agentic-app/template/.claude/settings.local.json b/create-agentic-app/template/.claude/settings.local.json
index 9649562..058b2ff 100644
--- a/create-agentic-app/template/.claude/settings.local.json
+++ b/create-agentic-app/template/.claude/settings.local.json
@@ -12,7 +12,8 @@
"Bash(git add:*)",
"Bash(git log:*)",
"Bash(find:*)",
- "Bash(git checkout:*)"
+ "Bash(git checkout:*)",
+ "Bash(cat:*)"
]
},
"enableAllProjectMcpServers": true,
diff --git a/create-agentic-app/template/.nvmrc b/create-agentic-app/template/.nvmrc
new file mode 100644
index 0000000..209e3ef
--- /dev/null
+++ b/create-agentic-app/template/.nvmrc
@@ -0,0 +1 @@
+20
diff --git a/create-agentic-app/template/.prettierignore b/create-agentic-app/template/.prettierignore
new file mode 100644
index 0000000..5177fb2
--- /dev/null
+++ b/create-agentic-app/template/.prettierignore
@@ -0,0 +1,25 @@
+# Dependencies
+node_modules/
+pnpm-lock.yaml
+
+# Build outputs
+.next/
+dist/
+build/
+
+# Database
+drizzle/
+
+# Generated files
+*.min.js
+*.min.css
+
+# Template (has its own formatting)
+create-agentic-app/
+
+# Cache
+.cache/
+
+# IDE
+.idea/
+.vscode/
diff --git a/create-agentic-app/template/.prettierrc b/create-agentic-app/template/.prettierrc
new file mode 100644
index 0000000..a79b3d6
--- /dev/null
+++ b/create-agentic-app/template/.prettierrc
@@ -0,0 +1,11 @@
+{
+ "semi": true,
+ "singleQuote": false,
+ "tabWidth": 2,
+ "trailingComma": "es5",
+ "printWidth": 100,
+ "bracketSpacing": true,
+ "arrowParens": "always",
+ "endOfLine": "lf",
+ "plugins": ["prettier-plugin-tailwindcss"]
+}
diff --git a/create-agentic-app/template/CLAUDE.md b/create-agentic-app/template/CLAUDE.md
index eabdb4e..c273a78 100644
--- a/create-agentic-app/template/CLAUDE.md
+++ b/create-agentic-app/template/CLAUDE.md
@@ -2,11 +2,11 @@
## Project Overview
-This is a Next.js 15 boilerplate for building AI-powered applications with authentication, database, and modern UI components.
+This is a Next.js 16 boilerplate for building AI-powered applications with authentication, database, and modern UI components.
### Tech Stack
-- **Framework**: Next.js 15 with App Router, React 19, TypeScript
+- **Framework**: Next.js 16 with App Router, React 19, TypeScript
- **AI Integration**: Vercel AI SDK 5 + OpenRouter (access to 100+ AI models)
- **Authentication**: BetterAuth with Google OAuth
- **Database**: PostgreSQL with Drizzle ORM
@@ -182,7 +182,7 @@ The project includes technical documentation in `docs/`:
- Use TypeScript with proper types
9. **API Routes**
- - Follow Next.js 15 App Router conventions
+ - Follow Next.js 16 App Router conventions
- Use Route Handlers (route.ts files)
- Return Response objects
- Handle errors appropriately
diff --git a/create-agentic-app/template/README.md b/create-agentic-app/template/README.md
index c72c33c..fb8e78d 100644
--- a/create-agentic-app/template/README.md
+++ b/create-agentic-app/template/README.md
@@ -9,7 +9,7 @@ A complete agentic coding boilerplate with authentication, PostgreSQL database,
- **š¤ AI Integration**: Vercel AI SDK with OpenRouter (access to 100+ AI models)
- **š File Storage**: Automatic local/Vercel Blob storage with seamless switching
- **šØ UI Components**: shadcn/ui with Tailwind CSS
-- **ā” Modern Stack**: Next.js 15, React 19, TypeScript
+- **ā” Modern Stack**: Next.js 16, React 19, TypeScript
- **š± Responsive**: Mobile-first design approach
## š„ Video Tutorial
diff --git a/create-agentic-app/template/docs/business/starter-prompt.md b/create-agentic-app/template/docs/business/starter-prompt.md
index 86de00a..cf3366e 100644
--- a/create-agentic-app/template/docs/business/starter-prompt.md
+++ b/create-agentic-app/template/docs/business/starter-prompt.md
@@ -42,7 +42,7 @@ The only things to preserve are:
## Tech Stack
-- Next.js 15 with App Router
+- Next.js 16 with App Router
- TypeScript
- Tailwind CSS
- Better Auth for authentication
diff --git a/create-agentic-app/template/docs/technical/ai/streaming.md b/create-agentic-app/template/docs/technical/ai/streaming.md
index 89af7d1..036f65d 100644
--- a/create-agentic-app/template/docs/technical/ai/streaming.md
+++ b/create-agentic-app/template/docs/technical/ai/streaming.md
@@ -11,9 +11,9 @@ If you are unfamiliar with the concepts of [Prompt Engineering](/docs/advanced/p
To follow this quickstart, you'll need:
- Node.js 18+ and pnpm installed on your local development machine.
-- An OpenAI API key.
+- An OpenRouter API key.
-If you haven't obtained your OpenAI API key, you can do so by [signing up](https://platform.openai.com/signup/) on the OpenAI website.
+If you haven't obtained your OpenRouter API key, you can do so by [signing up](https://openrouter.ai/) on the OpenRouter website and visiting [https://openrouter.ai/settings/keys](https://openrouter.ai/settings/keys).
## Create Your Application
@@ -35,7 +35,7 @@ Navigate to the newly created directory:
### Install dependencies
-Install `ai`, `@ai-sdk/react`, and `@ai-sdk/openai`, the AI package, AI SDK's React hooks, and AI SDK's [ OpenAI provider ](/providers/ai-sdk-providers/openai) respectively.
+Install `ai`, `@ai-sdk/react`, and `@openrouter/ai-sdk-provider`, the AI package, AI SDK's React hooks, and the OpenRouter provider respectively.
The AI SDK is designed to be a unified interface to interact with any large
@@ -47,39 +47,39 @@ Install `ai`, `@ai-sdk/react`, and `@ai-sdk/openai`, the AI package, AI SDK's Re
-
+
-
+
-
+
-
+
-### Configure OpenAI API key
+### Configure OpenRouter API key
-Create a `.env.local` file in your project root and add your OpenAI API Key. This key is used to authenticate your application with the OpenAI service.
+Create a `.env.local` file in your project root and add your OpenRouter API Key. This key is used to authenticate your application with OpenRouter.
Edit the `.env.local` file:
```env filename=".env.local"
-OPENAI_API_KEY=xxxxxxxxx
+OPENROUTER_API_KEY=sk-or-v1-xxxxxxxxx
+OPENROUTER_MODEL=openai/gpt-5-mini
```
-Replace `xxxxxxxxx` with your actual OpenAI API key.
+Replace the API key with your actual OpenRouter API key from [https://openrouter.ai/settings/keys](https://openrouter.ai/settings/keys).
- The AI SDK's OpenAI Provider will default to using the `OPENAI_API_KEY`
- environment variable.
+ You can browse available models at [https://openrouter.ai/models](https://openrouter.ai/models) and set your preferred model via the `OPENROUTER_MODEL` environment variable.
## Create a Route Handler
@@ -87,7 +87,7 @@ Replace `xxxxxxxxx` with your actual OpenAI API key.
Create a route handler, `app/api/chat/route.ts` and add the following code:
```tsx filename="app/api/chat/route.ts"
-import { openai } from "@ai-sdk/openai";
+import { createOpenRouter } from "@openrouter/ai-sdk-provider";
import { streamText, UIMessage, convertToModelMessages } from "ai";
// Allow streaming responses up to 30 seconds
@@ -96,8 +96,13 @@ export const maxDuration = 30;
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
+ // Initialize OpenRouter with API key from environment
+ const openrouter = createOpenRouter({
+ apiKey: process.env.OPENROUTER_API_KEY,
+ });
+
const result = streamText({
- model: openai(process.env.OPENAI_MODEL || "gpt-5-mini"),
+ model: openrouter(process.env.OPENROUTER_MODEL || "openai/gpt-5-mini"),
messages: convertToModelMessages(messages),
});
@@ -108,7 +113,7 @@ export async function POST(req: Request) {
Let's take a look at what is happening in this code:
1. Define an asynchronous `POST` request handler and extract `messages` from the body of the request. The `messages` variable contains a history of the conversation between you and the chatbot and provides the chatbot with the necessary context to make the next generation. The `messages` are of UIMessage type, which are designed for use in application UI - they contain the entire message history and associated metadata like timestamps.
-2. Call [`streamText`](/docs/reference/ai-sdk-core/stream-text), which is imported from the `ai` package. This function accepts a configuration object that contains a `model` provider (imported from `@ai-sdk/openai`) and `messages` (defined in step 1). You can pass additional [settings](/docs/ai-sdk-core/settings) to further customise the model's behaviour. The `messages` key expects a `ModelMessage[]` array. This type is different from `UIMessage` in that it does not include metadata, such as timestamps or sender information. To convert between these types, we use the `convertToModelMessages` function, which strips the UI-specific metadata and transforms the `UIMessage[]` array into the `ModelMessage[]` format that the model expects.
+2. Call [`streamText`](/docs/reference/ai-sdk-core/stream-text), which is imported from the `ai` package. This function accepts a configuration object that contains a `model` provider (created using `createOpenRouter` from `@openrouter/ai-sdk-provider`) and `messages` (defined in step 1). You can pass additional [settings](/docs/ai-sdk-core/settings) to further customise the model's behaviour. The `messages` key expects a `ModelMessage[]` array. This type is different from `UIMessage` in that it does not include metadata, such as timestamps or sender information. To convert between these types, we use the `convertToModelMessages` function, which strips the UI-specific metadata and transforms the `UIMessage[]` array into the `ModelMessage[]` format that the model expects.
3. The `streamText` function returns a [`StreamTextResult`](/docs/reference/ai-sdk-core/stream-text#result-object). This result object contains the [ `toUIMessageStreamResponse` ](/docs/reference/ai-sdk-core/stream-text#to-data-stream-response) function which converts the result to a streamed response object.
4. Finally, return the result to the client to stream the response.
@@ -199,7 +204,7 @@ Let's enhance your chatbot by adding a simple weather tool.
Modify your `app/api/chat/route.ts` file to include the new weather tool:
```tsx filename="app/api/chat/route.ts" highlight="2,13-27"
-import { openai } from "@ai-sdk/openai";
+import { createOpenRouter } from "@openrouter/ai-sdk-provider";
import { streamText, UIMessage, convertToModelMessages, tool } from "ai";
import { z } from "zod";
@@ -208,8 +213,12 @@ export const maxDuration = 30;
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
+ const openrouter = createOpenRouter({
+ apiKey: process.env.OPENROUTER_API_KEY,
+ });
+
const result = streamText({
- model: openai(process.env.OPENAI_MODEL || "gpt-5-mini"),
+ model: openrouter(process.env.OPENROUTER_MODEL || "openai/gpt-5-mini"),
messages: convertToModelMessages(messages),
tools: {
weather: tool({
@@ -320,7 +329,7 @@ To solve this, you can enable multi-step tool calls using `stopWhen`. By default
Modify your `app/api/chat/route.ts` file to include the `stopWhen` condition:
```tsx filename="app/api/chat/route.ts"
-import { openai } from "@ai-sdk/openai";
+import { createOpenRouter } from "@openrouter/ai-sdk-provider";
import {
streamText,
UIMessage,
@@ -335,8 +344,12 @@ export const maxDuration = 30;
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
+ const openrouter = createOpenRouter({
+ apiKey: process.env.OPENROUTER_API_KEY,
+ });
+
const result = streamText({
- model: openai(process.env.OPENAI_MODEL || "gpt-5-mini"),
+ model: openrouter(process.env.OPENROUTER_MODEL || "openai/gpt-5-mini"),
messages: convertToModelMessages(messages),
stopWhen: stepCountIs(5),
tools: {
@@ -374,7 +387,7 @@ By setting `stopWhen: stepCountIs(5)`, you're allowing the model to use up to 5
Update your `app/api/chat/route.ts` file to add a new tool to convert the temperature from Fahrenheit to Celsius:
```tsx filename="app/api/chat/route.ts" highlight="34-47"
-import { openai } from "@ai-sdk/openai";
+import { createOpenRouter } from "@openrouter/ai-sdk-provider";
import {
streamText,
UIMessage,
@@ -389,8 +402,12 @@ export const maxDuration = 30;
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
+ const openrouter = createOpenRouter({
+ apiKey: process.env.OPENROUTER_API_KEY,
+ });
+
const result = streamText({
- model: openai(process.env.OPENAI_MODEL || "gpt-5-mini"),
+ model: openrouter(process.env.OPENROUTER_MODEL || "openai/gpt-5-mini"),
messages: convertToModelMessages(messages),
stopWhen: stepCountIs(5),
tools: {
diff --git a/create-agentic-app/template/eslint.config.mjs b/create-agentic-app/template/eslint.config.mjs
index 4c1faba..d0c27e7 100644
--- a/create-agentic-app/template/eslint.config.mjs
+++ b/create-agentic-app/template/eslint.config.mjs
@@ -2,9 +2,74 @@ import nextConfig from "eslint-config-next/core-web-vitals";
const config = [
{
- ignores: [".next/**", "node_modules/**", ".cache/**", "dist/**", "build/**"],
+ ignores: [
+ ".next/**",
+ "node_modules/**",
+ ".cache/**",
+ "dist/**",
+ "build/**",
+ "create-agentic-app/**",
+ "drizzle/**",
+ "scripts/**",
+ ],
},
...nextConfig,
+ {
+ rules: {
+ // React rules
+ "react/jsx-no-target-blank": "error",
+ "react/no-unescaped-entities": "off",
+
+ // React Hooks rules
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "warn",
+
+ // Import rules
+ "import/no-anonymous-default-export": "warn",
+ "import/order": [
+ "warn",
+ {
+ groups: [
+ "builtin",
+ "external",
+ "internal",
+ ["parent", "sibling"],
+ "index",
+ "type",
+ ],
+ pathGroups: [
+ {
+ pattern: "react",
+ group: "builtin",
+ position: "before",
+ },
+ {
+ pattern: "next/**",
+ group: "builtin",
+ position: "before",
+ },
+ {
+ pattern: "@/**",
+ group: "internal",
+ position: "before",
+ },
+ ],
+ pathGroupsExcludedImportTypes: ["react", "next"],
+ "newlines-between": "never",
+ alphabetize: {
+ order: "asc",
+ caseInsensitive: true,
+ },
+ },
+ ],
+
+ // Best practices
+ "no-console": ["warn", { allow: ["warn", "error"] }],
+ "prefer-const": "error",
+ "no-var": "error",
+ eqeqeq: ["error", "always", { null: "ignore" }],
+ },
+ },
];
export default config;
diff --git a/create-agentic-app/template/next.config.ts b/create-agentic-app/template/next.config.ts
index e9ffa30..189f2a2 100644
--- a/create-agentic-app/template/next.config.ts
+++ b/create-agentic-app/template/next.config.ts
@@ -1,7 +1,53 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
- /* config options here */
+ // Image optimization configuration
+ images: {
+ remotePatterns: [
+ {
+ protocol: "https",
+ hostname: "lh3.googleusercontent.com",
+ },
+ {
+ protocol: "https",
+ hostname: "avatars.githubusercontent.com",
+ },
+ ],
+ },
+
+ // Enable compression
+ compress: true,
+
+ // Security headers
+ async headers() {
+ return [
+ {
+ source: "/(.*)",
+ headers: [
+ {
+ key: "X-Frame-Options",
+ value: "DENY",
+ },
+ {
+ key: "X-Content-Type-Options",
+ value: "nosniff",
+ },
+ {
+ key: "Referrer-Policy",
+ value: "strict-origin-when-cross-origin",
+ },
+ {
+ key: "X-XSS-Protection",
+ value: "1; mode=block",
+ },
+ {
+ key: "Permissions-Policy",
+ value: "camera=(), microphone=(), geolocation=()",
+ },
+ ],
+ },
+ ];
+ },
};
export default nextConfig;
diff --git a/create-agentic-app/template/package.json b/create-agentic-app/template/package.json
index 963b74e..7adb8b1 100644
--- a/create-agentic-app/template/package.json
+++ b/create-agentic-app/template/package.json
@@ -2,11 +2,16 @@
"name": "agentic-coding-starter-kit",
"version": "1.1.2",
"scripts": {
- "dev": "next dev",
+ "dev": "next dev --turbopack",
"build": "pnpm run db:migrate && next build",
"start": "next start",
"lint": "eslint .",
"typecheck": "tsc --noEmit",
+ "check": "pnpm lint && pnpm typecheck",
+ "format": "prettier --write .",
+ "format:check": "prettier --check .",
+ "setup": "npx tsx scripts/setup.ts",
+ "env:check": "node -e \"require('./src/lib/env.ts').checkEnv()\" || echo 'Run with tsx: npx tsx -e \"import { checkEnv } from './src/lib/env'; checkEnv();\"'",
"db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate",
"db:push": "drizzle-kit push",
@@ -15,12 +20,12 @@
"db:reset": "drizzle-kit drop && drizzle-kit push"
},
"dependencies": {
- "@ai-sdk/openai": "^2.0.60",
"@ai-sdk/react": "^2.0.86",
"@openrouter/ai-sdk-provider": "^1.2.0",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
+ "@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-slot": "^1.2.3",
"@vercel/blob": "^2.0.0",
"ai": "^5.0.86",
@@ -36,6 +41,7 @@
"react": "19.2.0",
"react-dom": "19.2.0",
"react-markdown": "^10.1.0",
+ "sonner": "^2.0.7",
"tailwind-merge": "^3.3.1",
"zod": "^4.1.12"
},
@@ -48,8 +54,11 @@
"drizzle-kit": "^0.31.6",
"eslint": "^9.39.0",
"eslint-config-next": "16.0.3",
+ "prettier": "^3.4.2",
+ "prettier-plugin-tailwindcss": "^0.6.9",
"shadcn": "^3.5.0",
"tailwindcss": "^4.1.16",
+ "tsx": "^4.19.2",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.3"
},
diff --git a/create-agentic-app/template/scripts/setup.ts b/create-agentic-app/template/scripts/setup.ts
new file mode 100644
index 0000000..446cdb4
--- /dev/null
+++ b/create-agentic-app/template/scripts/setup.ts
@@ -0,0 +1,274 @@
+#!/usr/bin/env npx tsx
+/**
+ * Interactive setup wizard for the Agentic Coding Starter Kit.
+ * Run with: npx tsx scripts/setup.ts
+ */
+
+import { existsSync, copyFileSync, readFileSync } from "fs";
+import { createInterface } from "readline";
+import { execSync } from "child_process";
+import { join } from "path";
+
+const ROOT_DIR = join(import.meta.dirname, "..");
+const ENV_EXAMPLE = join(ROOT_DIR, "env.example");
+const ENV_FILE = join(ROOT_DIR, ".env");
+
+// ANSI colors
+const colors = {
+ reset: "\x1b[0m",
+ bright: "\x1b[1m",
+ green: "\x1b[32m",
+ yellow: "\x1b[33m",
+ red: "\x1b[31m",
+ cyan: "\x1b[36m",
+ dim: "\x1b[2m",
+};
+
+function log(message: string, color?: keyof typeof colors) {
+ const colorCode = color ? colors[color] : "";
+ console.log(`${colorCode}${message}${colors.reset}`);
+}
+
+function header(message: string) {
+ console.log();
+ log(`${"=".repeat(60)}`, "cyan");
+ log(` ${message}`, "bright");
+ log(`${"=".repeat(60)}`, "cyan");
+ console.log();
+}
+
+function success(message: string) {
+ log(`ā ${message}`, "green");
+}
+
+function warn(message: string) {
+ log(`ā ${message}`, "yellow");
+}
+
+function error(message: string) {
+ log(`ā ${message}`, "red");
+}
+
+function info(message: string) {
+ log(` ${message}`, "dim");
+}
+
+async function prompt(question: string): Promise {
+ const rl = createInterface({
+ input: process.stdin,
+ output: process.stdout,
+ });
+
+ return new Promise((resolve) => {
+ rl.question(`${colors.cyan}? ${colors.reset}${question} `, (answer) => {
+ rl.close();
+ resolve(answer.trim());
+ });
+ });
+}
+
+async function confirm(question: string): Promise {
+ const answer = await prompt(`${question} (y/n)`);
+ return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
+}
+
+function checkNodeVersion(): boolean {
+ const requiredMajor = 20;
+ const currentVersion = process.version;
+ const currentMajor = parseInt(currentVersion.slice(1).split(".")[0] || "0", 10);
+
+ if (currentMajor >= requiredMajor) {
+ success(`Node.js ${currentVersion} detected (requires v${requiredMajor}+)`);
+ return true;
+ } else {
+ error(`Node.js ${currentVersion} detected, but v${requiredMajor}+ is required`);
+ info("Please upgrade Node.js: https://nodejs.org/");
+ return false;
+ }
+}
+
+function copyEnvFile(): boolean {
+ if (existsSync(ENV_FILE)) {
+ warn(".env file already exists");
+ return true;
+ }
+
+ if (!existsSync(ENV_EXAMPLE)) {
+ error("env.example file not found");
+ return false;
+ }
+
+ try {
+ copyFileSync(ENV_EXAMPLE, ENV_FILE);
+ success("Created .env file from env.example");
+ return true;
+ } catch (err) {
+ error(`Failed to create .env file: ${err}`);
+ return false;
+ }
+}
+
+interface EnvStatus {
+ configured: string[];
+ missing: string[];
+ optional: string[];
+}
+
+function checkEnvVariables(): EnvStatus {
+ const required = ["POSTGRES_URL", "BETTER_AUTH_SECRET"];
+ const optional = [
+ "GOOGLE_CLIENT_ID",
+ "GOOGLE_CLIENT_SECRET",
+ "OPENROUTER_API_KEY",
+ "OPENROUTER_MODEL",
+ "BLOB_READ_WRITE_TOKEN",
+ "NEXT_PUBLIC_APP_URL",
+ ];
+
+ const status: EnvStatus = {
+ configured: [],
+ missing: [],
+ optional: [],
+ };
+
+ // Read .env file if it exists
+ let envContent = "";
+ if (existsSync(ENV_FILE)) {
+ envContent = readFileSync(ENV_FILE, "utf-8");
+ }
+
+ // Parse env file (simple key=value parsing)
+ const envVars: Record = {};
+ envContent.split("\n").forEach((line) => {
+ const trimmed = line.trim();
+ if (trimmed && !trimmed.startsWith("#")) {
+ const [key, ...valueParts] = trimmed.split("=");
+ if (key) {
+ envVars[key] = valueParts.join("=");
+ }
+ }
+ });
+
+ // Check required variables
+ for (const key of required) {
+ const value = envVars[key];
+ if (value && value.length > 0 && !value.startsWith("your-")) {
+ status.configured.push(key);
+ } else {
+ status.missing.push(key);
+ }
+ }
+
+ // Check optional variables
+ for (const key of optional) {
+ const value = envVars[key];
+ if (value && value.length > 0 && !value.startsWith("your-")) {
+ status.configured.push(key);
+ } else {
+ status.optional.push(key);
+ }
+ }
+
+ return status;
+}
+
+async function runDatabaseMigration(): Promise {
+ log("\nRunning database migration...", "cyan");
+
+ try {
+ execSync("pnpm db:migrate", {
+ cwd: ROOT_DIR,
+ stdio: "inherit",
+ });
+ success("Database migration completed");
+ return true;
+ } catch {
+ error("Database migration failed");
+ info("Make sure your database is running and POSTGRES_URL is correct");
+ return false;
+ }
+}
+
+function printNextSteps(envStatus: EnvStatus) {
+ header("Next Steps");
+
+ const steps: string[] = [];
+
+ if (envStatus.missing.length > 0) {
+ steps.push(`Configure required env vars in .env: ${envStatus.missing.join(", ")}`);
+ }
+
+ if (envStatus.optional.includes("GOOGLE_CLIENT_ID")) {
+ steps.push("Set up Google OAuth at https://console.cloud.google.com/");
+ }
+
+ if (envStatus.optional.includes("OPENROUTER_API_KEY")) {
+ steps.push("Get an OpenRouter API key at https://openrouter.ai/settings/keys");
+ }
+
+ steps.push("Start the development server: pnpm dev");
+ steps.push("Open http://localhost:3000 in your browser");
+
+ steps.forEach((step, index) => {
+ log(`${index + 1}. ${step}`);
+ });
+
+ console.log();
+ log("Documentation:", "bright");
+ info("- README.md - Project overview and setup");
+ info("- CLAUDE.md - AI assistant guidelines");
+ info("- docs/ - Technical documentation");
+ console.log();
+}
+
+async function main() {
+ header("Agentic Coding Starter Kit - Setup Wizard");
+
+ // Step 1: Check Node version
+ log("Checking Node.js version...", "cyan");
+ if (!checkNodeVersion()) {
+ process.exit(1);
+ }
+
+ // Step 2: Create .env file
+ console.log();
+ log("Setting up environment...", "cyan");
+ copyEnvFile();
+
+ // Step 3: Check environment variables
+ console.log();
+ log("Checking environment variables...", "cyan");
+ const envStatus = checkEnvVariables();
+
+ if (envStatus.configured.length > 0) {
+ success(`Configured: ${envStatus.configured.join(", ")}`);
+ }
+ if (envStatus.missing.length > 0) {
+ warn(`Missing (required): ${envStatus.missing.join(", ")}`);
+ }
+ if (envStatus.optional.length > 0) {
+ info(`Optional (not set): ${envStatus.optional.join(", ")}`);
+ }
+
+ // Step 4: Offer to run database migration
+ if (envStatus.missing.length === 0) {
+ console.log();
+ const shouldMigrate = await confirm("Would you like to run database migrations now?");
+ if (shouldMigrate) {
+ await runDatabaseMigration();
+ }
+ } else {
+ console.log();
+ warn("Skipping database migration - please configure required env vars first");
+ }
+
+ // Step 5: Print next steps
+ printNextSteps(envStatus);
+
+ log("Setup complete!", "green");
+}
+
+main().catch((err) => {
+ error(`Setup failed: ${err}`);
+ process.exit(1);
+});
diff --git a/create-agentic-app/template/specs/boilerplate-improvements/implementation-plan.md b/create-agentic-app/template/specs/boilerplate-improvements/implementation-plan.md
new file mode 100644
index 0000000..394cbcf
--- /dev/null
+++ b/create-agentic-app/template/specs/boilerplate-improvements/implementation-plan.md
@@ -0,0 +1,165 @@
+# Next.js 16 Boilerplate Improvements - Implementation Plan
+
+## Phase 1: Critical Security & Stability (19 files)
+
+### Security Configuration
+- [ ] Update `next.config.ts` - Add security headers, image config, compression
+- [ ] Modify `package.json` - Remove `@ai-sdk/openai` dependency
+- [ ] Create `src/proxy.ts` - Server-side auth protection using Next.js 16 proxy + BetterAuth
+- [ ] Modify `src/app/api/chat/route.ts` - Add session authentication check
+- [ ] Update `docs/technical/ai/streaming.md` - Fix OpenRouter references
+
+### Next.js 15 ā 16 Updates (Main Project)
+- [ ] Update `CLAUDE.md` - Change Next.js 15 to Next.js 16
+- [ ] Update `README.md` - Change Next.js 15 to Next.js 16
+- [ ] Update `docs/business/starter-prompt.md` - Change Next.js 15 to Next.js 16
+- [ ] Update `src/components/starter-prompt-modal.tsx` - Change Next.js 15 to Next.js 16
+- [ ] Update `.claude/agents/polar-payments-expert.md` - Change Next.js 15 to Next.js 16
+- [ ] Update `.claude/agents/better-auth-expert.md` - Change Next.js 15 to Next.js 16
+
+### Next.js 15 ā 16 Updates (create-agentic-app Template)
+- [ ] Update `create-agentic-app/README.md` - Change Next.js 15 to Next.js 16
+- [ ] Update `create-agentic-app/template/CLAUDE.md` - Change Next.js 15 to Next.js 16
+- [ ] Update `create-agentic-app/template/README.md` - Change Next.js 15 to Next.js 16
+- [ ] Update `create-agentic-app/template/docs/business/starter-prompt.md` - Change Next.js 15 to Next.js 16
+- [ ] Update `create-agentic-app/template/src/components/starter-prompt-modal.tsx` - Change Next.js 15 to Next.js 16
+- [ ] Update `create-agentic-app/template/.claude/agents/better-auth-expert.md` - Change Next.js 15 to Next.js 16
+- [ ] Update `create-agentic-app/template/.claude/agents/polar-payments-expert.md` - Change Next.js 15 to Next.js 16
+
+---
+
+## Phase 2: Core UX Components (12 files)
+
+### Error Handling
+- [ ] Create `src/app/error.tsx` - Global error boundary
+- [ ] Create `src/app/not-found.tsx` - Custom 404 page
+- [ ] Create `src/app/chat/error.tsx` - Chat-specific error handling
+
+### Loading States
+- [ ] Create `src/components/ui/skeleton.tsx` - Skeleton loading component (via shadcn)
+- [ ] Create `src/components/ui/spinner.tsx` - Loading spinner component
+
+### Toast Notifications
+- [ ] Install shadcn Sonner: `npx shadcn@latest add sonner`
+- [ ] Modify `src/app/layout.tsx` - Add `` component
+
+### Form Components
+- [ ] Install shadcn input: `npx shadcn@latest add input`
+- [ ] Install shadcn textarea: `npx shadcn@latest add textarea`
+- [ ] Install shadcn label: `npx shadcn@latest add label`
+
+### Chat UX Improvements
+- [ ] Modify `src/app/chat/page.tsx`:
+ - [ ] Add message timestamps
+ - [ ] Add copy-to-clipboard for AI responses
+ - [ ] Add typing/thinking indicator during streaming
+ - [ ] Add error display for API failures
+ - [ ] Add message persistence (localStorage)
+
+### Database Schema
+- [ ] Modify `src/lib/schema.ts` - Add missing indexes:
+ - [ ] Index on `session.user_id`
+ - [ ] Index on `session.token`
+ - [ ] Index on `account.user_id`
+ - [ ] Index on `account(provider_id, account_id)`
+ - [ ] Index on `user.email`
+- [ ] Run `pnpm db:generate` to create migration
+- [ ] Run `pnpm db:migrate` to apply migration
+
+---
+
+## Phase 3: Polish & Security (8 files)
+
+### ESLint Configuration
+- [ ] Modify `eslint.config.mjs`:
+ - [ ] Add import ordering rules
+ - [ ] Add TypeScript-eslint rules
+ - [ ] Add React hooks exhaustive-deps
+ - [ ] Add no-console warnings
+
+### API Hardening
+- [ ] Modify `src/app/api/chat/route.ts`:
+ - [ ] Add rate limiting (10 requests/minute per user)
+ - [ ] Add Zod validation for messages
+ - [ ] Add message length limits
+- [ ] Modify `src/app/api/diagnostics/route.ts` - Restrict to authenticated admins
+
+### SEO
+- [ ] Modify `src/app/layout.tsx` - Add Open Graph metadata
+- [ ] Create `src/app/sitemap.ts` - Dynamic sitemap
+- [ ] Create `src/app/robots.ts` - Robots configuration
+
+### Accessibility
+- [ ] Modify `src/components/site-header.tsx`:
+ - [ ] Add `