Your First Project
Build a complete feature with Bootspring in 10 minutes. This hands-on tutorial shows you how to use agents, skills, and quality gates together.
What We'll Build#
A user authentication system with:
- Sign up and login pages
- Database schema for users
- API endpoints for auth
- Form validation
- Security best practices
Prerequisites#
- Node.js 18+ installed
- A Next.js project (or create one:
npx create-next-app@latest my-app) - An MCP-compatible AI assistant (Claude Code, Cursor, etc.)
Step 1: Authenticate and Initialize#
Open your terminal in your project directory:
# Authenticate and link to a project
bootspring auth loginThis opens your browser to:
- Sign in to your Bootspring account
- Select an existing project or create a new one
- Link this directory to your project
Then initialize Bootspring:
bootspring initYou'll see:
✓ Created bootspring.config.js
✓ Created .mcp.json
✓ Generated CLAUDE.md
Bootspring is ready! Open your AI assistant to get started.
Step 2: Open Your AI Assistant#
Open Claude Code, Cursor, or your preferred AI assistant in your project directory. The MCP connection will be established automatically.
Verify it's working by asking:
What Bootspring tools are available?
You should see a list including bootspring_agent, bootspring_skill, bootspring_quality, and more.
Step 3: Plan the Architecture#
Let's start by getting architectural guidance. Ask your AI assistant:
Use the architecture-expert agent to help me plan a user authentication system for this Next.js app. I want email/password login with JWT tokens.
The architecture-expert will respond with:
- Recommended approach (e.g., NextAuth vs custom)
- Component structure
- API route design
- Security considerations
- Database schema suggestions
Example response:
For a Next.js app with JWT authentication, I recommend:
Architecture:
- Use NextAuth.js for session management (or custom JWT if you need more control)
- Store users in PostgreSQL with Prisma
- Hash passwords with bcrypt
- Use HTTP-only cookies for tokens
Files to create:
app/ ├── (auth)/ │ ├── login/page.tsx │ └── signup/page.tsx ├── api/ │ └── auth/ │ ├── login/route.ts │ ├── signup/route.ts │ └── me/route.ts lib/ ├── auth.ts └── db.ts prisma/ └── schema.prisma
Step 4: Design the Database Schema#
Now let's design the user schema. Ask:
Use the database-expert agent to create a Prisma schema for user authentication with email verification and password reset support.
The database-expert will provide:
1// prisma/schema.prisma
2
3model User {
4 id String @id @default(cuid())
5 email String @unique
6 passwordHash String
7 name String?
8 emailVerified DateTime?
9 createdAt DateTime @default(now())
10 updatedAt DateTime @updatedAt
11
12 sessions Session[]
13 tokens VerificationToken[]
14}
15
16model Session {
17 id String @id @default(cuid())
18 userId String
19 token String @unique
20 expiresAt DateTime
21 createdAt DateTime @default(now())
22
23 user User @relation(fields: [userId], references: [id], onDelete: Cascade)
24
25 @@index([userId])
26}
27
28model VerificationToken {
29 id String @id @default(cuid())
30 userId String
31 token String @unique
32 type String // "email_verification" | "password_reset"
33 expiresAt DateTime
34 createdAt DateTime @default(now())
35
36 user User @relation(fields: [userId], references: [id], onDelete: Cascade)
37
38 @@index([userId])
39 @@index([token])
40}Apply the schema:
npx prisma db pushStep 5: Build the API Endpoints#
Use skills to generate production-ready API code:
Use the api-endpoint skill to create a POST /api/auth/signup endpoint that creates a new user with email and password.
The skill generates:
1// app/api/auth/signup/route.ts
2
3import { NextRequest, NextResponse } from 'next/server';
4import { z } from 'zod';
5import bcrypt from 'bcryptjs';
6import { prisma } from '@/lib/db';
7
8const signupSchema = z.object({
9 email: z.string().email('Invalid email address'),
10 password: z.string().min(8, 'Password must be at least 8 characters'),
11 name: z.string().min(1, 'Name is required').optional(),
12});
13
14export async function POST(request: NextRequest) {
15 try {
16 const body = await request.json();
17 const { email, password, name } = signupSchema.parse(body);
18
19 // Check if user exists
20 const existingUser = await prisma.user.findUnique({
21 where: { email },
22 });
23
24 if (existingUser) {
25 return NextResponse.json(
26 { error: 'Email already registered' },
27 { status: 400 }
28 );
29 }
30
31 // Hash password
32 const passwordHash = await bcrypt.hash(password, 12);
33
34 // Create user
35 const user = await prisma.user.create({
36 data: {
37 email,
38 passwordHash,
39 name,
40 },
41 select: {
42 id: true,
43 email: true,
44 name: true,
45 createdAt: true,
46 },
47 });
48
49 return NextResponse.json(user, { status: 201 });
50 } catch (error) {
51 if (error instanceof z.ZodError) {
52 return NextResponse.json(
53 { error: 'Validation failed', details: error.errors },
54 { status: 400 }
55 );
56 }
57
58 console.error('Signup error:', error);
59 return NextResponse.json(
60 { error: 'Internal server error' },
61 { status: 500 }
62 );
63 }
64}Now create the login endpoint:
Use the api-endpoint skill to create a POST /api/auth/login endpoint that authenticates a user and returns a JWT token.
Step 6: Build the Frontend#
Ask the frontend-expert to create the login form:
Use the frontend-expert agent to create a login form component with React Hook Form, Zod validation, loading states, and error handling. Use Tailwind CSS for styling.
Generated component:
1// components/auth/LoginForm.tsx
2
3'use client';
4
5import { useState } from 'react';
6import { useForm } from 'react-hook-form';
7import { zodResolver } from '@hookform/resolvers/zod';
8import { z } from 'zod';
9import { useRouter } from 'next/navigation';
10
11const loginSchema = z.object({
12 email: z.string().email('Please enter a valid email'),
13 password: z.string().min(1, 'Password is required'),
14});
15
16type LoginFormData = z.infer<typeof loginSchema>;
17
18export function LoginForm() {
19 const router = useRouter();
20 const [error, setError] = useState<string | null>(null);
21
22 const {
23 register,
24 handleSubmit,
25 formState: { errors, isSubmitting },
26 } = useForm<LoginFormData>({
27 resolver: zodResolver(loginSchema),
28 });
29
30 const onSubmit = async (data: LoginFormData) => {
31 setError(null);
32
33 try {
34 const response = await fetch('/api/auth/login', {
35 method: 'POST',
36 headers: { 'Content-Type': 'application/json' },
37 body: JSON.stringify(data),
38 });
39
40 if (!response.ok) {
41 const result = await response.json();
42 throw new Error(result.error || 'Login failed');
43 }
44
45 router.push('/dashboard');
46 router.refresh();
47 } catch (err) {
48 setError(err instanceof Error ? err.message : 'An error occurred');
49 }
50 };
51
52 return (
53 <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
54 {error && (
55 <div className="p-3 text-sm text-red-600 bg-red-50 border border-red-200 rounded-lg">
56 {error}
57 </div>
58 )}
59
60 <div>
61 <label htmlFor="email" className="block text-sm font-medium text-gray-700">
62 Email
63 </label>
64 <input
65 {...register('email')}
66 type="email"
67 id="email"
68 autoComplete="email"
69 className="mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
70 />
71 {errors.email && (
72 <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>
73 )}
74 </div>
75
76 <div>
77 <label htmlFor="password" className="block text-sm font-medium text-gray-700">
78 Password
79 </label>
80 <input
81 {...register('password')}
82 type="password"
83 id="password"
84 autoComplete="current-password"
85 className="mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
86 />
87 {errors.password && (
88 <p className="mt-1 text-sm text-red-600">{errors.password.message}</p>
89 )}
90 </div>
91
92 <button
93 type="submit"
94 disabled={isSubmitting}
95 className="w-full rounded-lg bg-blue-600 px-4 py-2 text-white font-medium hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
96 >
97 {isSubmitting ? 'Signing in...' : 'Sign in'}
98 </button>
99 </form>
100 );
101}Step 7: Security Review#
Before deploying, get a security review:
Use the security-expert agent to review the authentication code we just created and identify any security issues.
The security-expert will check for:
- Password hashing strength
- SQL injection vulnerabilities
- XSS prevention
- CSRF protection
- Rate limiting recommendations
- Secure cookie settings
Example findings:
Security Review Results:
✅ Password hashing with bcrypt (cost factor 12) - Good ✅ Input validation with Zod - Good ✅ Parameterized queries via Prisma - Good
⚠️ Recommendations:
- Add rate limiting to prevent brute force attacks
- Use HTTP-only, Secure, SameSite cookies for tokens
- Add CSRF protection for form submissions
- Implement account lockout after failed attempts
Step 8: Run Quality Gates#
Before committing, run quality checks:
Run the pre-commit quality gate on the auth files.
Bootspring will:
- Run TypeScript type checking
- Execute linting rules
- Check for security issues
- Verify code formatting
Quality Gate: pre-commit
========================
✓ TypeScript: No errors
✓ ESLint: 0 errors, 2 warnings
✓ Security: No vulnerabilities
✓ Format: All files formatted
Result: PASSED
Step 9: Commit Your Changes#
Now you can safely commit:
git add .
git commit -m "feat: add user authentication system"What We Accomplished#
In 10 minutes, we:
- Initialized Bootspring with context generation
- Planned architecture with the architecture-expert
- Designed database schema with the database-expert
- Built API endpoints using the api-endpoint skill
- Created frontend components with the frontend-expert
- Reviewed security with the security-expert
- Validated quality with pre-commit gates
Key Takeaways#
Agent Chaining#
For complex features, chain multiple agents:
architecture-expert- Plan the approachdatabase-expert- Design the data layerbackend-expert- Implement server logicfrontend-expert- Build the UIsecurity-expert- Review for vulnerabilitiestesting-expert- Write tests
Skills for Speed#
Use skills for common patterns:
api-endpoint- RESTful endpointsreact-component- React componentsprisma-crud- Database operationsauth-flow- Authentication patterns
Quality Gates for Confidence#
Always run quality gates before committing:
pre-commit- Quick checks (lint, types)pre-push- Thorough checks (tests, build)pre-deploy- Full audit (security, performance)
Next Steps#
- Understanding Context - Learn how CLAUDE.md works
- Using Agents - Deep dive into agents
- Using Skills - Master the pattern library
- Workflows - Automate complex processes