Awesome-omni-skill fullstack-dev
Comprehensive fullstack development skill combining architecture, testing, security, DevOps, and code quality best practices for building modern web applications from frontend to backend.
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/fullstack-dev" ~/.claude/skills/diegosouzapw-awesome-omni-skill-fullstack-dev && rm -rf "$T"
skills/development/fullstack-dev/SKILL.mdFullstack Development Skill
This skill provides expert guidance for building complete, production-ready web applications. It combines best practices from Clean Architecture, Domain-Driven Design, Test-Driven Development, security principles, and DevOps practices.
When to Use This Skill
- Building new web applications (frontend + backend)
- Implementing features with architectural best practices
- Setting up testing strategies (unit, integration, e2e)
- Improving code quality and security
- Deploying applications to cloud infrastructure
- Optimizing application performance
- Creating data visualizations and dashboards
- Writing maintainable, scalable code
Core Principles
1. Architecture & Design (Clean Architecture + DDD)
Project Structure:
src/ ├── domain/ # Core business logic (entities, value objects) ├── application/ # Use cases, services, DTOs ├── infrastructure/ # Database, external services, APIs ├── presentation/ # HTTP handlers, controllers, middleware └── shared/ # Utilities, constants, helpers
Naming Conventions:
- ✅ Use domain-specific names:
,OrderCalculator
,UserAuthenticatorPaymentProcessor - ❌ Avoid generic names:
,utils.js
,helpers.jscommon.js
Key Rules:
- Early return pattern: Always use early returns for better readability
- Single Responsibility: Each class/function has ONE clear purpose
- Dependency Injection: Pass dependencies explicitly, don't create inside functions
- Library-First: Search for existing solutions BEFORE writing custom code
- Auth → Use Auth0, Supabase, or NextAuth
- Retry Logic → Use cockatiel or p-retry
- Form Validation → Use Zod, Yup, or Joi
- State Management → Use Redux, Zustand, or Jotai
- ORM → Use Prisma, TypeORM, or Sequelize
Code Size Limits:
- Functions: max 50 lines
- Components: max 80 lines
- Files: max 200 lines
- Nesting: max 3 levels deep
2. Frontend Development (React + Modern Stack)
React Components:
// ✅ GOOD: Functional component with clear purpose interface UserCardProps { userId: string; onEdit: (id: string) => void; } export function UserCard({ userId, onEdit }: UserCardProps) { const user = useQuery(['user', userId], fetchUser); if (user.isLoading) return <Skeleton />; if (user.isError) return <ErrorFallback error={user.error} />; return ( <div className="card"> <h3>{user.data.name}</h3> <button onClick={() => onEdit(userId)}>Edit</button> </div> ); } // ❌ AVOID: Overly complex, mixed concerns function UserComponent({ data, onAction, ...props }) { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); // ... 200 lines of mixed logic }
Component Structure:
- Keep components focused (max 80 lines)
- Use React hooks properly (useQuery, useState, useEffect)
- Extract complex logic to custom hooks or services
- Use TypeScript for type safety
- Apply styling consistently (Tailwind CSS recommended)
State Management:
- Local state (useState) for simple component state
- React Query (TanStack Query) for server state
- Zustand/Redux for complex global state
- Context API for theme/auth state
3. Backend Development (Node.js/Express or Framework of Choice)
API Design:
// Use RESTful conventions and proper HTTP methods GET /api/users // List all users POST /api/users // Create user GET /api/users/:id // Get single user PUT /api/users/:id // Update user DELETE /api/users/:id // Delete user
Error Handling:
// ✅ Structured error handling try { const user = await userService.getUser(id); if (!user) { throw new NotFoundError(`User ${id} not found`); } return user; } catch (error) { if (error instanceof NotFoundError) { res.status(404).json({ error: error.message }); } else if (error instanceof ValidationError) { res.status(400).json({ error: error.message }); } else { res.status(500).json({ error: 'Internal server error' }); } }
Database:
- Use an ORM (Prisma, TypeORM, Sequelize) - never write raw SQL
- Apply migrations for schema changes
- Use proper indexes for performance
- Implement soft deletes where appropriate
- Use transactions for multi-step operations
Authentication & Security:
// Use established libraries // Auth: NextAuth, Auth0, Supabase, Passport // Session: express-session + redis or JWT with refresh tokens // Password hashing: bcrypt // API keys: stored in secure vault (HashiCorp Vault, AWS Secrets Manager) // ✅ Always validate and sanitize input const schema = z.object({ email: z.string().email(), password: z.string().min(8), }); const validated = schema.parse(req.body);
4. Testing Strategy (Test-Driven Development)
Testing Pyramid:
UI/E2E Tests (10%) / \\ / \\ Integration Tests (30%) / \\ / \\ Unit Tests (60%)
Unit Tests:
// Test individual functions/methods describe('OrderCalculator', () => { it('should calculate total with tax', () => { const order = { items: [{ price: 100 }] }; const total = calculateTotal(order); expect(total).toBe(115); // 100 + 15% tax }); it('should apply discount', () => { const order = { items: [{ price: 100 }], discount: 0.1 }; const total = calculateTotal(order); expect(total).toBe(103.5); // (100 - 10) * 1.15 }); });
Integration Tests:
// Test multiple components working together describe('User Service with Database', () => { it('should create and retrieve user', async () => { const user = await userService.create({ email: 'test@example.com' }); const retrieved = await userService.getById(user.id); expect(retrieved.email).toBe('test@example.com'); }); });
E2E Tests (Playwright):
// Test complete user flows test('user should be able to register and login', async ({ page }) => { await page.goto('http://localhost:3000/register'); await page.fill('input[name="email"]', 'test@example.com'); await page.fill('input[name="password"]', 'SecurePassword123'); await page.click('button[type="submit"]'); expect(page.url()).toContain('/dashboard'); });
Test Libraries:
- Unit: Jest, Vitest
- Integration: Jest with database
- E2E: Playwright, Cypress
- Mocking: Jest, MSW (Mock Service Worker)
5. Security & Vulnerability Testing
FFUF Web Fuzzing for Penetration Testing:
# Directory discovery ffuf -w wordlist.txt -u https://target.com/FUZZ -ac # API endpoint discovery ffuf -w api-endpoints.txt -u https://api.target.com/v1/FUZZ -ac # Parameter fuzzing (requires authentication) ffuf --request authenticated_req.txt -w params.txt -ac # IDOR testing (finds insecure direct object references) ffuf --request req.txt -w user_ids.txt -ac -mc 200
Security Checklist:
- ✅ Use HTTPS everywhere
- ✅ Implement CORS correctly
- ✅ Use secure headers (CSP, X-Frame-Options, etc.)
- ✅ Hash passwords with bcrypt (12 rounds minimum)
- ✅ Validate and sanitize all inputs
- ✅ Use parameterized queries (ORM handles this)
- ✅ Implement rate limiting on APIs
- ✅ Log security events
- ✅ Regular dependency updates
- ✅ Use security scanning tools (npm audit, Snyk)
6. Data Visualization (D3.js or Chart Libraries)
Chart Selection:
- Line/Area charts: Time series, trends
- Bar charts: Comparisons, categories
- Pie/Donut charts: Proportions
- Scatter: Correlations
- Heatmaps: Density, patterns
- Network graphs: Relationships
Example with Recharts (Simpler Alternative):
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip } from 'recharts'; export function SalesChart({ data }) { return ( <LineChart width={800} height={400} data={data}> <CartesianGrid strokeDasharray="3 3" /> <XAxis dataKey="name" /> <YAxis /> <Tooltip /> <Line type="monotone" dataKey="sales" stroke="#8884d8" /> </LineChart> ); }
7. DevOps & Deployment
CI/CD Pipeline:
# Example GitHub Actions name: Deploy on: push: branches: [main] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' - run: npm install - run: npm run lint - run: npm run test - run: npm run build deploy: needs: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Deploy to AWS run: | aws s3 cp dist/ s3://my-bucket --recursive aws cloudfront create-invalidation --distribution-id $DIST_ID --paths "/*"
Deployment Environments:
- Development: Local machine + Docker
- Staging: AWS/Vercel/Railway with latest code
- Production: AWS/Vercel/Railway with tagged releases
Infrastructure as Code (AWS CDK):
// Define infrastructure in code const app = new cdk.App(); const stack = new cdk.Stack(app, 'fullstack-stack'); const bucket = new s3.Bucket(stack, 'frontend-bucket', { websiteIndexDocument: 'index.html', publicReadAccess: true, }); const distribution = new cloudfront.Distribution(stack, 'distribution', { defaultBehavior: { origin: new S3Origin(bucket) }, });
8. Git Workflow
Branching Strategy (Git Flow):
main (production) ├── release/v1.0.0 │ └── hotfix/critical-bug └── develop (staging) ├── feature/user-auth ├── feature/payment-integration └── feature/dashboard
Commit Messages:
feat: add user authentication fix: correct payment calculation docs: update API documentation test: add tests for auth service refactor: simplify order service chore: update dependencies
Git Worktrees for Parallel Work:
# Create isolated workspace for feature git worktree add ../feature-branch feature/new-feature # Switch between features without stashing cd ../feature-branch # Work on feature... # Cleanup git worktree remove ../feature-branch
9. Performance Optimization
Frontend:
- Code splitting: Load only needed JavaScript
- Lazy loading: Images, components on-demand
- Caching: Static assets with long-lived cache headers
- Minification: Reduce bundle size
- Critical rendering path: Optimize above-fold content
Backend:
- Database indexing: Fast queries
- Caching: Redis for frequently accessed data
- Connection pooling: Reuse database connections
- Async operations: Non-blocking I/O
- Load balancing: Distribute traffic
Monitoring:
// Use Application Performance Monitoring // Services: New Relic, DataDog, Sentry, LogRocket // Track key metrics metrics.recordLatency('api.users.get', duration); metrics.incrementCounter('api.errors'); metrics.recordGauge('db.connections.active', activeConnections);
Workflow for Building Features
Step 1: Plan & Design
- Define requirements and acceptance criteria
- Sketch API endpoints and data models
- Design database schema
- Plan component structure (frontend)
Step 2: Write Tests First (TDD)
// Write test before implementation describe('createUser', () => { it('should create user with valid email', async () => { const user = await createUser({ email: 'test@example.com' }); expect(user.id).toBeDefined(); expect(user.email).toBe('test@example.com'); }); });
Step 3: Implement Backend
- Create database schema/migration
- Implement service layer
- Create API endpoints
- Add authentication/authorization
- Write integration tests
Step 4: Implement Frontend
- Create React components
- Integrate with API
- Add form validation
- Handle errors gracefully
- Write E2E tests
Step 5: Security Review
# Run security checks npm audit npx snyk test # Run FFUF tests on staging ffuf -w api-wordlist.txt -u https://staging.app/api/FUZZ -ac
Step 6: Deploy & Monitor
- Run full test suite
- Build for production
- Deploy to staging
- Run E2E tests on staging
- Deploy to production
- Monitor metrics and logs
Step 7: Iterate
- Gather user feedback
- Monitor performance
- Fix bugs and security issues
- Plan improvements
Technology Stack Recommendations
Frontend
- Framework: React 18+ with TypeScript
- State Management: TanStack Query + Zustand
- Styling: Tailwind CSS
- UI Components: shadcn/ui, Radix UI
- Testing: Vitest + React Testing Library
- E2E: Playwright
Backend
- Runtime: Node.js 18+ or Bun
- Framework: Express, NestJS, or FastAPI
- Database: PostgreSQL with Prisma ORM
- Authentication: NextAuth, Auth0, or Supabase
- API Documentation: OpenAPI/Swagger
- Testing: Jest, Supertest
- Logging: Winston, Pino
DevOps & Infrastructure
- Hosting: AWS, Vercel, Railway, Render
- Container: Docker
- CI/CD: GitHub Actions, GitLab CI
- Infrastructure as Code: AWS CDK or Terraform
- Monitoring: DataDog, New Relic, or Sentry
- Database Hosting: AWS RDS, Railway, or Supabase
Common Patterns
Error Handling
// Create custom error classes class AppError extends Error { constructor(public statusCode: number, message: string) { super(message); } } class ValidationError extends AppError { constructor(message: string) { super(400, message); } } // Use in middleware app.use((err, req, res, next) => { if (err instanceof AppError) { res.status(err.statusCode).json({ error: err.message }); } else { res.status(500).json({ error: 'Internal server error' }); } });
Async/Await Best Practices
// ✅ Good: Parallel operations when possible const [user, posts] = await Promise.all([ getUser(id), getPosts(userId), ]); // ❌ Avoid: Sequential when parallel is possible const user = await getUser(id); const posts = await getPosts(user.id);
API Response Format
// Consistent response structure interface ApiResponse<T> { success: boolean; data?: T; error?: { code: string; message: string; }; meta?: { timestamp: string; version: string; }; }
Tools & Resources
Code Quality
- ESLint: Linting
- Prettier: Code formatting
- TypeScript: Type safety
- SonarQube: Code analysis
Testing
- Jest: Unit testing
- Playwright: E2E testing
- Mock Service Worker: API mocking
- Storybook: Component testing
Performance
- Lighthouse: Web performance auditing
- WebPageTest: Detailed performance analysis
- Chrome DevTools: Browser debugging
- Bundle Analyzer: JavaScript bundle analysis
Security
- FFUF: Web fuzzing
- npm audit: Dependency vulnerabilities
- Snyk: Security scanning
- OWASP Top 10: Security best practices
Notes for Claude
- When building features, emphasize TDD approach
- Always recommend using established libraries instead of custom code
- Ensure proper error handling and validation
- Consider security implications at every step
- Optimize for performance and user experience
- Use TypeScript for type safety
- Follow SOLID principles and Clean Architecture
- Implement proper logging and monitoring
- Write comprehensive tests (unit, integration, E2E)
- Use git best practices and semantic commits
- Document API endpoints with OpenAPI/Swagger
- Consider accessibility (a11y) in frontend development
- Plan for scalability from the start