Generate production-ready Next.js projects from natural language, with shadcn/ui components, API integration, type safety, and modern tooling.
Fast path for simple projects:
Live preview: Projects run on PM2 (port 3002), accessible at http://localhost:3002 or via nginx proxy if configured.
Default workflow: All projects use PM2 for dev server management (prevents port conflicts, ensures single instance).
sudo apt-get install chromium-browser (Debian/Ubuntu)sudo apt-get install nginx```nginx
# /etc/nginx/sites-available/
server {
listen
server_name _;
location / {
proxy_pass http://localhost:3002; # PM2 dev server
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
```
sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ && sudo systemctl reload nginx http://localhost:3002 (PM2 port)Before starting, ask user if they want to enable optional features.
Quick reference for typical requests:
(dashboard) route group, shadcn data tables, chartsapp/page.tsx, hero section, features grid, testimonialsapp/blog/[slug]/page.tsx, markdown support(auth) group), protected routes, subscription logicAsk user: What type of project are you building? (helps determine structure and components)
Core:
API Integration (default):
Optional (based on needs):
Industry-standard Next.js 14+ App Router structure with feature-based organization:
<project-name>/
├── app/ # Next.js 14 App Router
│ ├── (auth)/ # Route group (auth pages)
│ │ ├── login/
│ │ │ └── page.tsx
│ │ ├── register/
│ │ │ └── page.tsx
│ │ └── layout.tsx # Auth-specific layout
│ ├── (dashboard)/ # Route group (protected pages)
│ │ ├── dashboard/
│ │ │ ├── page.tsx
│ │ │ └── loading.tsx
│ │ ├── profile/
│ │ │ └── page.tsx
│ │ ├── settings/
│ │ │ └── page.tsx
│ │ └── layout.tsx # Dashboard layout with sidebar
│ ├── api/ # API routes
│ │ ├── auth/
│ │ │ └── [...nextauth]/route.ts
│ │ └── users/
│ │ └── route.ts
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home page
│ ├── loading.tsx # Root loading UI
│ ├── error.tsx # Root error boundary
│ ├── not-found.tsx # 404 page
│ └── providers.tsx # Client providers (React Query, etc.)
│
├── components/
│ ├── ui/ # shadcn/ui components (auto-generated)
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── input.tsx
│ │ ├── form.tsx
│ │ └── ...
│ ├── layout/ # Layout components
│ │ ├── header.tsx
│ │ ├── footer.tsx
│ │ ├── sidebar.tsx
│ │ └── mobile-nav.tsx
│ ├── features/ # Feature-specific components
│ │ ├── auth/
│ │ │ ├── login-form.tsx
│ │ │ └── register-form.tsx
│ │ ├── dashboard/
│ │ │ ├── stats-card.tsx
│ │ │ └── recent-activity.tsx
│ │ └── profile/
│ │ ├── profile-header.tsx
│ │ └── edit-profile-form.tsx
│ └── shared/ # Shared/common components
│ ├── data-table.tsx
│ ├── search-bar.tsx
│ └── pagination.tsx
│
├── lib/ # Utility functions & configurations
│ ├── api.ts # Axios instance + interceptors
│ ├── react-query.ts # React Query client config
│ ├── utils.ts # Utility functions (cn, formatters)
│ ├── validations.ts # Zod schemas
│ ├── constants.ts # App constants
│ └── auth.ts # Auth utilities (if using next-auth)
│
├── hooks/ # Custom React hooks
│ ├── use-auth.ts # Authentication hook
│ ├── use-user.ts # User data hook (React Query)
│ ├── use-posts.ts # Posts data hook (React Query)
│ ├── use-media-query.ts # Responsive design hook
│ └── use-toast.ts # Toast notifications (shadcn)
│
├── types/ # TypeScript type definitions
│ ├── index.ts # Common types
│ ├── api.ts # API response types
│ ├── user.ts # User-related types
│ └── database.ts # Database types (Prisma generated)
│
├── actions/ # Server Actions (Next.js 14+)
│ ├── auth.ts # Auth actions
│ ├── user.ts # User actions
│ └── posts.ts # Posts actions
│
├── config/ # Configuration files
│ ├── site.ts # Site metadata (name, description, etc.)
│ └── navigation.ts # Navigation menu config
│
├── prisma/ # Prisma ORM (if using database)
│ ├── schema.prisma # Database schema
│ └── migrations/ # Database migrations
│
├── public/ # Static assets
│ ├── images/
│ ├── icons/
│ └── fonts/
│
├── styles/ # Global styles
│ └── globals.css # Tailwind imports + custom styles
│
├── .env.local # Environment variables (gitignored)
├── .env.example # Environment variables template
├── .eslintrc.json # ESLint config
├── .prettierrc # Prettier config
├── components.json # shadcn/ui config
├── next.config.js # Next.js config
├── tailwind.config.ts # Tailwind config
├── tsconfig.json # TypeScript config
├── package.json # Dependencies
└── README.md # Project documentation
app/ - Next.js 14 App Router pages and layouts. Use route groups (name) for logical grouping without affecting URLs.
components/ - All React components, organized by type:
ui/ - shadcn/ui components (copy-paste, customizable)layout/ - Shared layout components (header, footer, sidebar)features/ - Feature-specific components (scoped to one feature)shared/ - Reusable components used across featureslib/ - Utility functions, configurations, and third-party library setups.
hooks/ - Custom React hooks, especially React Query hooks for API calls.
types/ - TypeScript type definitions and interfaces.
actions/ - Server Actions for form handling and server-side operations (Next.js 14+).
config/ - App configuration (site metadata, navigation menus, constants).
prisma/ - Database schema and migrations (if using Prisma).
public/ - Static files served at root URL.
styles/ - Global CSS (Tailwind imports + custom styles).
Keep user informed at every step — this is a live build log.
⚠️ Important: All projects use PM2 for dev server management (port 3002 by default). This ensures:
Ask:
Create Next.js project:
npx create-next-app@latest <project-name> \
--typescript \
--tailwind \
--app \
--no-src-dir \
--import-alias "@/*"
→ Message user: "Next.js project initialized ✓"
Create all necessary directories following industry best practices:
cd <project-name>
# Create app route groups
mkdir -p app/\(auth\)/login app/\(auth\)/register
mkdir -p app/\(dashboard\)/dashboard app/\(dashboard\)/profile app/\(dashboard\)/settings
mkdir -p app/api/auth app/api/users
# Create component directories
mkdir -p components/ui components/layout components/features components/shared
mkdir -p components/features/auth components/features/dashboard components/features/profile
# Create utility directories
mkdir -p lib hooks types actions config
# Create static asset directories
mkdir -p public/images public/icons public/fonts
# Create styles directory
mkdir styles
# Create Prisma directory (if using database)
# mkdir -p prisma
Create essential config files:
config/site.ts - Site metadata
export const siteConfig = {
name: '<Project Name>',
description: '<Project Description>',
url: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
links: {
github: 'https://github.com/...',
},
};
config/navigation.ts - Navigation menu
export const mainNav = [
{ title: 'Home', href: '/' },
{ title: 'Dashboard', href: '/dashboard' },
{ title: 'Profile', href: '/profile' },
];
export const dashboardNav = [
{ title: 'Overview', href: '/dashboard' },
{ title: 'Profile', href: '/profile' },
{ title: 'Settings', href: '/settings' },
];
.env.example - Environment variables template
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_API_BASE_URL=http://localhost:3000/api
DATABASE_URL=postgresql://...
NEXTAUTH_SECRET=...
NEXTAUTH_URL=http://localhost:3000
→ Message user: "Directory structure created ✓"
Core dependencies:
cd <project-name>
npm install axios @tanstack/react-query
npm install -D @types/node
shadcn/ui setup (recommended):
npx shadcn-ui@latest init
This will prompt for configuration. Recommended answers:
Install essential shadcn components:
npx shadcn-ui@latest add button card input label select textarea
npx shadcn-ui@latest add dropdown-menu dialog sheet tabs
npx shadcn-ui@latest add table form avatar badge separator toast
Install form dependencies (for shadcn/ui forms):
npm install react-hook-form @hookform/resolvers zod
Optional (ask user based on needs):
npm install zustand # State management
npm install next-auth # Authentication
npm install prisma @prisma/client # Database ORM
→ Message user: "Dependencies + shadcn/ui installed ✓"
lib/api.ts (axios instance)import axios from 'axios';
export const api = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3000/api',
timeout: 10000,
headers: { 'Content-Type': 'application/json' }
});
// Request interceptor (add auth tokens, etc.)
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
},
(error) => Promise.reject(error)
);
// Response interceptor (handle errors globally)
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Handle unauthorized
}
return Promise.reject(error);
}
);
lib/react-query.ts (query client)import { QueryClient } from '@tanstack/react-query';
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // 1 minute
refetchOnWindowFocus: false,
retry: 1,
},
},
});
app/providers.tsx (wrap app with providers)'use client';
import { QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { queryClient } from '@/lib/react-query';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
{children}
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}
Update app/layout.tsx to use Providers.
→ Message user: "Base configuration complete ✓"
Ask what features/pages to build. For each feature:
app//page.tsx )components/features// )hooks/use.ts ) using react-querytypes/.ts )app/api//route.ts )Example: User Profile Feature
// types/user.ts
export interface User {
id: string;
name: string;
email: string;
}
// hooks/useUser.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import type { User } from '@/types/user';
export const useUser = (id: string) => {
return useQuery({
queryKey: ['user', id],
queryFn: async () => {
const { data } = await api.get<User>(`/users/${id}`);
return data;
},
});
};
export const useUpdateUser = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (user: Partial<User>) => {
const { data } = await api.patch<User>(`/users/${user.id}`, user);
return data;
},
onSuccess: (data) => {
queryClient.invalidateQueries({ queryKey: ['user', data.id] });
},
});
};
// app/profile/[id]/page.tsx
'use client';
import { useUser, useUpdateUser } from '@/hooks/useUser';
export default function ProfilePage({ params }: { params: { id: string } }) {
const { data: user, isLoading, error } = useUser(params.id);
const updateUser = useUpdateUser();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h1>{user?.name}</h1>
<p>{user?.email}</p>
</div>
);
}
→ Message user after each feature: "Profile page complete ✓"
Use shadcn/ui components (already installed) for consistent, accessible UI. Apply Design Principles (see below).
Example: Profile page with shadcn/ui
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
export default function ProfilePage({ params }: { params: { id: string } }) {
const { data: user, isLoading } = useUser(params.id);
if (isLoading) return <Card className="w-full max-w-2xl mx-auto"><CardContent>Loading...</CardContent></Card>;
return (
<Card className="w-full max-w-2xl mx-auto">
<CardHeader>
<div className="flex items-center gap-4">
<Avatar className="h-20 w-20">
<AvatarImage src={user?.avatar} />
<AvatarFallback>{user?.name[0]}</AvatarFallback>
</Avatar>
<div>
<CardTitle>{user?.name}</CardTitle>
<p className="text-sm text-muted-foreground">{user?.email}</p>
</div>
</div>
</CardHeader>
<CardContent>
<Button>Edit Profile</Button>
</CardContent>
</Card>
);
}
When to add more components:
npx shadcn-ui@latest add form input labelnpx shadcn-ui@latest add tablenpx shadcn-ui@latest add navigation-menunpx shadcn-ui@latest add toast alert→ Message user: "UI built with shadcn/ui ✓"
Important: Use PM2 to manage the dev server (ensures only 1 instance runs, prevents port conflicts).
Start dev server with PM2:
# Stop any existing instance of this project
pm2 delete <project-name> 2>/dev/null || true
# Start with PM2 (port 3002 for nginx proxy)
PORT=3002 pm2 start npm --name "<project-name>" --cwd "$(pwd)" -- run dev
# Give PM2 a moment to start
sleep 2
Wait for server to be fully ready (critical - avoid white screen screenshots):
# Wait for "Ready in" message in PM2 logs (usually 5-15 seconds)
timeout=30
elapsed=0
while [ $elapsed -lt $timeout ]; do
if pm2 logs <project-name> --nostream --lines 50 2>/dev/null | grep -q "Ready in"; then
echo "Server ready!"
sleep 3 # Extra buffer for module loading
break
fi
sleep 1
elapsed=$((elapsed + 1))
done
# Verify server is responding
if ! curl -s http://localhost:3002 > /dev/null; then
echo "Warning: Server not responding on port 3002"
pm2 logs <project-name> --nostream --lines 20
fi
Take screenshots (requires chromium):
bash scripts/screenshot.sh "http://localhost:3002" /tmp/review-desktop.png 1400 900
bash scripts/screenshot.sh "http://localhost:3002" /tmp/review-mobile.png 390 844
Review Checklist (analyze with image tool):
If issues found: Fix responsive classes, re-run screenshots.
Common fixes:
p-4 md:p-8 lg:p-12text-2xl md:text-4xlmax-w-full or px-4→ Message user: "Review complete, sending preview..."
Create .env.local:
NEXT_PUBLIC_API_BASE_URL=https://api.example.com
DATABASE_URL=postgresql://...
NEXTAUTH_SECRET=...
Create .env.example (template for user).
→ Message user: "Environment template created ✓"
Update package.json scripts:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit"
}
}
Create README.md with:
→ Message user: "Documentation complete ✓"
Stop PM2 dev server (if running):
pm2 delete <project-name> 2>/dev/null || true
pm2 save # Persist PM2 process list
Zip the project:
cd .. && zip -r /tmp/<project-name>.zip <project-name>/
Send via message tool with filePath.
Provide deployment options:
npx vercelnpm run build && netlify deploy→ Message user: "Project ready! 🚀"
1. PM2 dev server (always running after Step 7):
# Check status
pm2 list
# View logs
pm2 logs <project-name>
# Access locally
curl http://localhost:3002
2. Live preview URLs:
http://localhost:3002http://: 3. Screenshot review (if chromium enabled):
# Desktop (1400x900)
bash scripts/screenshot.sh "http://localhost:3002" /tmp/desktop.png 1400 900
# Mobile (390x844)
bash scripts/screenshot.sh "http://localhost:3002" /tmp/mobile.png 390 844
Full test sequence:
# 1. Check PM2 status
pm2 list | grep <project-name>
# 2. Verify dev server responding
curl -I http://localhost:3002
# 3. Take screenshots for visual verification
bash scripts/screenshot.sh "http://localhost:3002" /tmp/test-desktop.png 1400 900
bash scripts/screenshot.sh "http://localhost:3002" /tmp/test-mobile.png 390 844
# 4. Check logs for errors
pm2 logs <project-name> --lines 50 | grep -i error
# 5. Test API endpoints (if using API routes)
curl http://localhost:3002/api/health # Example health check
# 6. Production build test
npm run build && npm run start # Test production build
# 7. Type check
npm run type-check
Scenario 1: Test responsive design
# Mobile, tablet, desktop
for width in 390 768 1400; do
bash scripts/screenshot.sh "http://localhost:3002" /tmp/screen-${width}.png $width 900
done
Scenario 2: Test specific page/route
# Take screenshot of specific route
bash scripts/screenshot.sh "http://localhost:3002/dashboard" /tmp/dashboard.png 1400 900
Scenario 3: Test after making changes
# PM2 auto-reloads on file changes, verify in logs
pm2 logs <project-name> --lines 20
# Wait for "compiled successfully" then take new screenshot
bash scripts/screenshot.sh "http://localhost:3002" /tmp/updated.png 1400 900
Option 1: Screenshots
Option 2: Nginx proxy + external access
http://: Option 3: Export & deploy
Use axios + react-query:
// hooks/usePosts.ts
import { useQuery, useMutation } from '@tanstack/react-query';
import { api } from '@/lib/api';
export const usePosts = () => {
return useQuery({
queryKey: ['posts'],
queryFn: async () => {
const { data } = await api.get('/posts');
return data;
},
});
};
export const useCreatePost = () => {
return useMutation({
mutationFn: async (post: { title: string; body: string }) => {
const { data } = await api.post('/posts', post);
return data;
},
});
};
Install:
npm install @apollo/client graphql
Setup Apollo Client, use useQuery and useMutation from Apollo.
For Next.js API routes with type safety:
npm install @trpc/server @trpc/client @trpc/react-query @trpc/next
For form handling without API routes:
// app/actions.ts
'use server';
export async function createPost(formData: FormData) {
const title = formData.get('title');
// ...
}
Always ask user which pattern they prefer for their use case.
Apply these consistently. These are quality standards.
p-4 or px-4 py-6 (never p-24 on mobile!)md:p-8 or md:px-6 md:py-8lg:p-12 xl:p-24text-2xl → Desktop: md:text-4xltext-lg → Desktop: md:text-2xlmax-w-full on containersbreak-wordsgrid-cols-1 md:grid-cols-2 lg:grid-cols-3 component with variants (default, destructive, outline, ghost) with react-hook-form integration component for content sections or components component for loading UI component for error messages component for tabular datashadcn/ui benefits: Accessible, customizable, copy-paste friendly, works with Tailwind
TypeScript Best Practices
- Strict mode enabled
- Explicit return types for functions
- Interface over type for objects
- Avoid
any (use unknown if needed) - Use discriminated unions for variants
Performance
- Use Next.js Image component (
next/image) - Lazy load below-the-fold content
- Code splitting (dynamic imports)
- Memoize expensive computations (useMemo, useCallback)
Common Patterns
Form Handling (with shadcn/ui)
'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import * as z from 'zod';
import { useMutation } from '@tanstack/react-query';
import { Button } from '@/components/ui/button';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { useToast } from '@/components/ui/use-toast';
const formSchema = z.object({
name: z.string().min(2, 'Name must be at least 2 characters'),
email: z.string().email('Invalid email address'),
});
export default function ContactForm() {
const { toast } = useToast();
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: { name: '', email: '' },
});
const mutation = useMutation({
mutationFn: async (data: z.infer<typeof formSchema>) => {
const res = await api.post('/contact', data);
return res.data;
},
onSuccess: () => {
toast({ title: 'Success', description: 'Message sent!' });
form.reset();
},
onError: (error) => {
toast({ title: 'Error', description: error.message, variant: 'destructive' });
},
});
return (
<Form {...form}>
<form onSubmit={form.handleSubmit((data) => mutation.mutate(data))} className="space-y-4">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="John Doe" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input type="email" placeholder="john@example.com" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" disabled={mutation.isPending}>
{mutation.isPending ? 'Sending...' : 'Send Message'}
</Button>
</form>
</Form>
);
}
Note: Run npx shadcn-ui@latest add form toast and install npm install react-hook-form @hookform/resolvers zod for this pattern.
Pagination
const usePaginatedPosts = (page: number) => {
return useQuery({
queryKey: ['posts', page],
queryFn: async () => {
const { data } = await api.get(`/posts?page=${page}`);
return data;
},
keepPreviousData: true, // Smooth transitions
});
};
Infinite Scroll
import { useInfiniteQuery } from '@tanstack/react-query';
const useInfinitePosts = () => {
return useInfiniteQuery({
queryKey: ['posts'],
queryFn: async ({ pageParam = 1 }) => {
const { data } = await api.get(`/posts?page=${pageParam}`);
return data;
},
getNextPageParam: (lastPage, pages) => lastPage.nextPage,
});
};
Common Mistakes to Avoid
- ❌ Not wrapping app with QueryClientProvider
- ❌ Using axios without interceptors (no error handling)
- ❌ Forgetting loading/error states in components
- ❌ Not invalidating queries after mutations
- ❌ Using
any instead of proper TypeScript types - ❌ Client components when server components would work
- ❌ Not using Next.js Image component (performance loss)
- ❌ Missing error boundaries
- ❌ Hardcoding API URLs (use env vars)
- ❌ No mobile testing (always check responsive at 390px width)
- ❌ Large padding on mobile (p-24 = 96px causes overflow on 390px screens)
- ❌ Not using responsive Tailwind classes (use p-4 md:p-8 lg:p-12)
- ❌ Horizontal overflow on mobile (content wider than 390px)
- ❌ Building custom components when shadcn/ui has them (Button, Card, Dialog, etc.)
- ❌ Using emoji for icons (use Lucide React icons from shadcn/ui)
- ❌ Not installing
@hookform/resolvers and zod before using shadcn forms - ❌ Forgetting to add
component when using toast notifications - ❌ Taking screenshots before dev server is fully ready (causes white screens)
- ❌ Not waiting for module loading (causes "Module not found" errors in screenshots)
Troubleshooting
White Screen Screenshots
Problem: Screenshots show blank white page
Cause: Dev server not fully initialized before screenshot
Solution:
- Wait for "Ready in" message in dev server logs
- Add 3-5 second buffer after "Ready" message
- Verify localhost:3000 loads in browser before taking screenshot
Module Not Found Errors
Problem: React error "Module not found: Can't resolve @tanstack/react-query"
Cause: Dev server started before all packages loaded
Solution:
- Restart dev server:
pkill -f "next dev" && npm run dev - Verify packages in node_modules:
ls node_modules/@tanstack/ - Wait 10-15 seconds after
npm install before starting dev server
Dev Server Won't Start
Problem: Port already in use (EADDRINUSE error)
Solution (PM2 method):
# Check what's running
pm2 list
# Stop the conflicting process
pm2 delete <project-name>
# Or check port directly
lsof -ti:3002
# Kill process on port (if not PM2-managed)
kill -9 $(lsof -ti:3002)
# Restart with PM2
PORT=3002 pm2 start npm --name "<project-name>" --cwd "$(pwd)" -- run dev
PM2 Process Management
List all PM2 processes:
pm2 list
Check logs:
pm2 logs <project-name> --lines 50
Restart a process:
pm2 restart <project-name>
Stop a process:
pm2 stop <project-name>
Delete a process:
pm2 delete <project-name>
Ensure only one instance runs:
# Always delete before starting
pm2 delete <project-name> 2>/dev/null || true
PORT=3002 pm2 start npm --name "<project-name>" --cwd "$(pwd)" -- run dev
Common PM2 scenarios:
- Project won't start → Check logs:
pm2 logs - Process keeps restarting → Module missing or port conflict, check logs
- Changes not reflecting → PM2 auto-reloads, verify in logs:
pm2 logs | grep compiled - Multiple instances running → Delete all:
pm2 delete all && pm2 list - Check resource usage →
pm2 monit (real-time monitoring) - Save PM2 process list →
pm2 save (persists across reboots)
Iteration & Updates
When user requests changes:
- Identify affected files
- Make changes
- PM2 auto-reloads (no manual restart needed for file changes)
- Run type check:
npm run type-check - Verify in logs:
pm2 logs --lines 20 - If chromium enabled: take new screenshot
- Report changes to user
Always explain what changed and why.
Quick Reference Cheat Sheet
Essential Commands
# Start dev server
pm2 delete <project-name> 2>/dev/null || true
PORT=3002 pm2 start npm --name "<project-name>" --cwd "$(pwd)" -- run dev
# Check status
pm2 list
pm2 logs <project-name>
# Take screenshots
bash scripts/screenshot.sh "http://localhost:3002" /tmp/desktop.png 1400 900
bash scripts/screenshot.sh "http://localhost:3002" /tmp/mobile.png 390 844
# Test production build
npm run build && npm run start
# Type check
npm run type-check
File Locations
- Components:
components/ui/ (shadcn), components/features/ (custom) - Pages:
app/*/page.tsx - API routes:
app/api/*/route.ts - Styles:
app/globals.css, tailwind.config.ts - Config:
next.config.ts, .env.local
Common shadcn Components
npx shadcn-ui@latest add button input form card table dialog toast
Live Preview URLs
- Local: http://localhost:3002
- Nginx proxy: http://
: - Mobile testing: Use nginx proxy or ngrok
Troubleshooting
- Port conflict →
pm2 delete then restart - White screen → Wait for "Ready in" message (check logs)
- Module errors →
npm install then restart PM2 - Type errors →
npm run type-check - Layout breaks → Check responsive classes (p-4 md:p-8 lg:p-12)
版本历史
共 1 个版本
-
v0.1.1
当前
2026-03-28 20:17
安全检测
腾讯云安全 (Keen)
队列中
腾讯云安全 (Sanbu)
队列中
🔗 相关推荐
developer-tools
CodeConductor.ai
larsonreever AI驱动平台,提供快速全栈开发、智能体、工作流自动化及低代码AI集成的可扩展产品创建。
★ 67
📥 180,046
data-analysis
UI/UX Design and Development
wing8169 根据自然语言提示生成并提供实时的 HTML/CSS/JS UI 设计。适用于用户要求设计、创建、构建或制作网站、着陆页、UI、仪表盘、网页或前端原型的场景,亦支持对已有设计进行更新或迭代。可替代传统的 UI 设计与前端开发流程。
★ 1
📥 2,786