Building a Modern Full-Stack Web Application - Part 2
This is Part 2 covering deployment and production workflows. Part 1 covered the tech stack and architecture.
Hosting & Deployment
Infrastructure
Fly.io hosts the application with global CDN, auto-scaling to zero when not in use, automatic health checks and restarts, and database migrations during deployment.
Cloudflare provides CDN with global edge network, DDoS protection, and automatic SSL certificates.
Neon hosts the serverless PostgreSQL database with auto-scaling compute, database branching for development and staging, automatic backups with point-in-time recovery, and connection pooling.
Docker Multi-Stage Builds
The application uses multi-stage builds for optimization:
FROM node:24-alpine AS base
WORKDIR /app
FROM base AS deps
COPY package.json package-lock.json ./
RUN npm ci --only=production
FROM base AS build
COPY . .
RUN npm run build
FROM base AS runtime
COPY --from=build /app/build ./build
COPY --from=deps /app/node_modules ./node_modules
EXPOSE 3000
CMD ["npm", "start"]
Development Workflow
# Development
npm run dev # Start development server
npm run test # Run tests
npm run typecheck # Type checking
# Database
npm run db:studio # Visual database management
npm run db:seed # Populate with sample data
npm run db:migrate # Apply schema changes
Code Quality Standards
The project uses ESLint with React and TypeScript rules, Prettier for consistent formatting, strict TypeScript with noUncheckedIndexedAccess, Husky for git hooks, Vitest for unit testing, and Playwright for end-to-end testing.
Database Development with Drizzle Kit
Schema changes follow a structured approach:
# 1. Edit app/db/schema.ts
# 2. Generate migration
npm run db:generate
# 3. Apply migration
npm run db:migrate
# Development workflow
npm run db:push # Quick schema sync (dev only)
npm run db:studio # Visual database UI
npm run db:reset # Clean database reset
Performance Considerations
Vite provides fast HMR with sub-second hot module replacement, automatic tree shaking and dead code elimination, route-based code splitting, and asset optimization with image compression.
Drizzle ORM offers prepared statements with cached query plans, connection pooling for efficient database connections, query optimization to minimize over-fetching, and type-safe migrations to prevent runtime errors.
Component libraries like Catalyst UI provided high-quality components without overhead. Infrastructure automation with Fly.io reduced operational complexity. The deployment pipeline ensures code quality with automated testing on every push, type checking and linting, database migrations during deployment, health checks post-deployment, and rollback capability for failed deployments.
This architecture provides a powerful foundation for building full-stack applications in 2025. The combination of React Router v7, Drizzle ORM, better-auth, and Fly.io creates maintainable, performant applications with excellent developer experience.