Development Tips
Improve your development workflow with these tips and best practices.
Development Environment
VS Code Setup
Recommended Extensions:
- ESLint
- Prettier - Code formatter
- Tailwind CSS IntelliSense
- TypeScript Error Lens
- PostgreSQL
- GitLens
Workspace Settings (.vscode/settings.json):
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}Terminal Setup
Use multiple terminals:
# Terminal 1: Web app
pnpm dev:web
# Terminal 2: CxC app
pnpm dev:cxc
# Terminal 3: Documentation
pnpm dev:docsOr use tmux/screen for session management.
Hot Reloading
Fast Refresh
Next.js automatically reloads on changes:
- Component changes: Instant update
- Page changes: Page reloads
- Config changes: Server restart required
Force Reload
If changes don’t reflect:
# Clear Next.js cache
rm -rf apps/web/.next
rm -rf apps/cxc/.next
# Restart dev server
pnpm devDebugging
Console Logging
Server-side logs (appear in terminal):
// app/api/route.ts
export async function GET() {
console.log("API called"); // Shows in terminal
return NextResponse.json({ data: "test" });
}Client-side logs (appear in browser):
"use client";
export function Component() {
console.log("Component rendered"); // Shows in browser
return <div>Content</div>;
}VS Code Debugger
Launch configuration (.vscode/launch.json):
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "pnpm dev:web"
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
}
]
}React DevTools
Install browser extension for React debugging:
- Inspect component tree
- View props and state
- Track re-renders
- Profile performance
Code Quality
Linting
# Check all packages
pnpm lint
# Fix auto-fixable issues
pnpm lint --fix
# Lint specific package
cd apps/web
pnpm lintFormatting
# Format all files
pnpm format
# Format specific files
pnpm format "apps/web/**/*.tsx"Type Checking
# Check types
pnpm tsc --noEmit
# Watch mode
pnpm tsc --noEmit --watchPerformance Optimization
Next.js Bundle Analysis
# Install analyzer
pnpm add -D @next/bundle-analyzer
# Update next.config.mjs
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
module.exports = withBundleAnalyzer(nextConfig)
# Analyze
ANALYZE=true pnpm buildComponent Optimization
import { memo } from "react";
// Memoize expensive components
export const ExpensiveComponent = memo(function ExpensiveComponent({ data }) {
// Heavy computation
return <div>{data}</div>;
});
// Use useMemo for expensive calculations
import { useMemo } from "react";
export function Component({ items }) {
const sortedItems = useMemo(() => {
return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);
return <div>{sortedItems.map(...)}</div>;
}Database Development
db-mate Workflow
# Create new migration
cd packages/server/web
db-mate new add_user_bio
# Edit migration files:
# - 001_add_user_bio.up.sql (apply)
# - 001_add_user_bio.down.sql (rollback)
# Apply migrations
db-mate up
# Rollback last migration
db-mate down
# Check migration status
db-mate statusDatabase Seeding
// packages/server/web/src/db/seed.ts
import { pool } from "@uwdsc/server/core/database/connection";
async function main() {
await pool.query(
`INSERT INTO users (email, name)
VALUES ($1, $2)`,
["test@example.com", "Test User"]
);
}
main()
.catch(console.error)
.finally(async () => {
await pool.end();
});# Run seed
cd packages/server/web
tsx src/db/seed.tsTesting
Unit Tests
// Component test
import { render, screen } from "@testing-library/react";
import { Button } from "@uwdsc/ui";
describe("Button", () => {
it("renders children", () => {
render(<Button>Click me</Button>);
expect(screen.getByText("Click me")).toBeInTheDocument();
});
it("calls onClick handler", () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click</Button>);
screen.getByText("Click").click();
expect(handleClick).toHaveBeenCalledTimes(1);
});
});Integration Tests
// API test
import { GET } from "@/app/api/health/route";
describe("Health API", () => {
it("returns health status", async () => {
const response = await GET();
const data = await response.json();
expect(data.status).toBe("healthy");
});
});Git Workflow
Branch Strategy
# Create feature branch
git checkout -b feature/add-user-profile
# Make changes and commit
git add .
git commit -m "feat: add user profile component"
# Push to remote
git push origin feature/add-user-profileCommit Messages
Follow Conventional Commits:
feat:- New featurefix:- Bug fixdocs:- Documentationstyle:- Code stylerefactor:- Code refactoringtest:- Testschore:- Maintenance
Examples:
git commit -m "feat: add user authentication"
git commit -m "fix: resolve navigation menu bug"
git commit -m "docs: update API documentation"
git commit -m "refactor: simplify profile service"Productivity Tips
Command Aliases
Add to .bashrc or .zshrc:
alias dev="pnpm dev"
alias devw="pnpm dev:web"
alias devc="pnpm dev:cxc"
alias devd="pnpm dev:docs"
alias build="pnpm build"
alias lint="pnpm lint"Package Scripts
Create convenience scripts in package.json:
{
"scripts": {
"clean": "rm -rf .next node_modules",
"reset": "pnpm clean && pnpm install",
"type-check": "tsc --noEmit",
"test:watch": "jest --watch"
}
}Code Snippets
VS Code snippets (.vscode/snippets.json):
{
"React Component": {
"prefix": "rfc",
"body": [
"export function ${1:Component}() {",
" return <div>$0</div>;",
"}"
]
},
"API Route": {
"prefix": "api",
"body": [
"import { NextResponse } from 'next/server';",
"",
"export async function GET() {",
" return NextResponse.json({ data: $0 });",
"}"
]
}
}Common Issues
Port Already in Use
# Find process using port
lsof -i :3000
# Kill process
kill -9 <PID>pnpm Lock File Conflicts
# Resolve conflicts
pnpm install --no-frozen-lockfileType Errors
# Regenerate types
pnpm build
# Restart TypeScript server in VS Code
# Cmd/Ctrl + Shift + P -> "TypeScript: Restart TS Server"Module Not Found
# Clear cache and reinstall
rm -rf node_modules
rm pnpm-lock.yaml
pnpm installKeyboard Shortcuts
VS Code
Cmd/Ctrl + P- Quick file openCmd/Ctrl + Shift + P- Command paletteCmd/Ctrl + B- Toggle sidebar- `Cmd/Ctrl + “ - Toggle terminal
F2- Rename symbolAlt + Up/Down- Move line up/down
Browser DevTools
Cmd/Ctrl + Shift + C- Inspect elementCmd/Ctrl + Shift + J- Open consoleCmd/Ctrl + Shift + M- Toggle device modeCmd/Ctrl + R- Reload pageCmd/Ctrl + Shift + R- Hard reload
Resources
Documentation
Tools
- React DevTools
- pgAdmin - PostgreSQL administration tool
- Postman - API testing
Best Practices
âś… Do
- Use TypeScript strictly
- Write clear commit messages
- Test your changes locally
- Keep components small and focused
- Document complex logic
- Use proper error handling
❌ Don’t
- Commit broken code
- Skip type checking
- Ignore linter warnings
- Push directly to main
- Leave debug code in commits
Next Steps
- Adding Components - Build UI components
- Creating API - Build backend features
- Database Setup - Work with db-mate and pg