βΆExpress vs Fastify vs NestJS β which framework should I learn?
Express: minimal, pragmatic, huge ecosystem, best for rapid API development. Fastify: faster raw performance (10-20% improvement), modern benchmarks, great for high-throughput APIs. NestJS: full-stack framework, TypeScript-first, dependency injection, enterprise patterns, steep learning curve. Start with Express to understand the fundamentals, then level up to Fastify for speed or NestJS for large teams.
βΆHow do async/await patterns work in Express and why are they critical?
Async/await = cleaner syntax for promises. Express middleware and route handlers run in sequence; if one handler doesn't complete, the request hangs. Always use `async/await` and proper error handling. Mistake: `app.get('/', (req, res) => { fetchData() })` without await. Fix: `app.get('/', async (req, res) => { const data = await fetchData(); res.json(data); })`. Missing async = request never completes.
βΆHow do I tune performance for high-traffic APIs?
Bottlenecks: database queries, synchronous code, lack of caching, inefficient middleware. Optimize: (1) use database indexes and connection pooling (Prisma's connection pool), (2) add Redis caching for frequent queries, (3) remove synchronous operations (fs, crypto sync), (4) profile with `clinic.js` or Node's built-in profiler, (5) use clustering (Node's `cluster` module) to use all CPU cores, (6) enable HTTP/2 with reverse proxy (nginx), (7) implement rate limiting and request queuing.
βΆHow do I build microservices with Express?
Express + microservices = split into multiple small services (auth, users, products, payments) each with its own Express server and database. Communicate via REST or message queues (RabbitMQ, Kafka). Use API Gateway (Kong, nginx) as entry point. Challenges: distributed transactions, debugging across services, deployment orchestration (Docker + Kubernetes). Start monolithic with Express, split only when a service needs independent scaling.
βΆWhat's the best way to deploy Express apps?
Production deployment: (1) use PM2 or `node --experimental-modules` for clustering, (2) run behind reverse proxy (nginx), (3) use environment variables for config (DATABASE_URL, API_KEYS in .env), (4) enable health checks (/health endpoint), (5) set up logging (Winston, Pino) and monitoring (New Relic, DataDog), (6) use Docker for consistency, (7) deploy via CI/CD (GitHub Actions, GitLab CI). Popular hosts: Heroku (simple), AWS (scalable), DigitalOcean (affordable), Railway, Render.
βΆHow do I handle errors properly and avoid silent failures?
Express doesn't catch errors in async functions by default. Wrap route handlers: `const asyncHandler = (fn) => (req, res, next) => fn(req, res, next).catch(next)`. Use global error handler: `app.use((err, req, res, next) => { res.status(500).json({ error: err.message }); })`. Log errors (don't just swallow), distinguish user errors (400 Bad Request) from server errors (500). Use try/catch in middleware for clarity.
βΆWhen should I use monorepo structure vs multiple repositories?
Monorepo: single repo for related services (shared types, utilities, easier refactoring). Tools: Turborepo, Nx, Pnpm workspaces. Fits: startups, tightly coupled services, shared business logic. Polyrepo: separate repos per service. Fits: independent teams, different tech stacks, strict deployment isolation. Express teams often start monorepo, split to polyrepo as they scale.