A full-stack application built with React, TypeScript, Vite, GraphQL, and Nitro server.
- Frontend: React + TypeScript + Vite + Tailwind CSS
- Backend: Nitro server with GraphQL API
- GraphQL: nitro-graphql with type-safe schema
- State Management: TanStack React Query for data fetching
- Routing: React Router v7
- Docker: Multi-runtime support (Node.js & Bun)
- Type Safety: Full TypeScript support
- React - A JavaScript library for building user interfaces
- Vite - Next Generation Frontend Tooling
- Nitro - Universal JavaScript Server
- nitro-graphql - GraphQL integration for Nitro
- TanStack React Query - Powerful data synchronization for React
- React Router - Declarative routing for React
- Tailwind CSS - Utility-first CSS framework
- Node.js 24+ or Bun 1.3+
- Docker & Docker Compose (for containerized deployment)
- pnpm (recommended package manager)
pnpm installpnpm devThe app will be available at:
- Frontend & API: http://localhost:5173
- GraphQL Playground: http://localhost:5173/api/graphql
pnpm buildpnpm previewThe project supports multiple runtime environments through Docker:
- app - Node.js runtime (default)
- bun - Bun runtime (profile-based)
- dev - Development mode with hot-reload (profile-based)
# Build and run
docker compose up app --build
# Run in background
docker compose up app --build -d
# View logs
docker compose logs -f app# Build and run
docker compose --profile bun up --build
# Run in background
docker compose --profile bun up --build -d
# View logs
docker compose logs -f bun# Run both Node.js (3000) and Bun (3001)
docker compose --profile bun up app bun --build
# In background
docker compose --profile bun up app bun --build -d# Run with hot-reload (port 5173)
docker compose --profile dev up
# In background
docker compose --profile dev up -d# Stop all services
docker compose down
# View running containers
docker compose ps
# View logs
docker compose logs -f
# Restart a service
docker compose restart app
# Execute command in container
docker compose exec app sh
# Rebuild without cache
docker compose build --no-cache appThe following environment variables are set in production:
NODE_ENV=productionNITRO_PORT=3000NITRO_HOST=0.0.0.0
- Runtime: Node.js 24 Alpine
- Package Manager: pnpm
- Preset: node-server
- Output Size: ~61 KB
- Multi-stage: Yes
- Runtime: Bun 1 Alpine
- Package Manager: bun
- Preset: bun
- Output Size: ~48 KB (22% smaller)
- Multi-stage: Yes
GET /api/hello- Health check endpoint
POST /api/graphql- GraphQL endpointGET /api/graphql- GraphQL Playground
query GetUser($id: ID!) {
getUser(id: $id) {
__typename
... on User {
id
name
email
createdAt
}
... on UserNotFoundError {
message
userId
}
... on UnauthorizedError {
message
requiredPermission
}
}
}Variables:
{
"id": "1"
}mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
id
name
email
createdAt
}
}Variables:
{
"input": {
"email": "[email protected]",
"name": "John Doe"
}
}.
├── server/ # Nitro server
│ ├── graphql/ # GraphQL schema & resolvers
│ │ └── user/ # User module
│ └── routes/ # API routes
├── src/ # React application
│ ├── components/ # React components
│ ├── contexts/ # React contexts (ErrorOverlay, etc.)
│ ├── hooks/ # Custom React hooks (useUser, etc.)
│ ├── graphql/ # GraphQL client & SDK
│ ├── pages/ # Page components
│ └── router/ # React Router configuration
├── Dockerfile # Node.js production build
├── Dockerfile.bun # Bun production build
├── docker-compose.yml # Multi-service orchestration
└── vite.config.ts # Vite & Nitro configuration
- Union Types: Error handling with union types
- Type Safety: Auto-generated TypeScript types
- Code Generation: GraphQL Code Generator
- React Hooks: Custom hooks for queries/mutations with React Query
- Client-side code splitting with React lazy loading
- Optimized production builds
- Multi-stage Docker builds for minimal image size
- Static asset caching
- GraphQL query caching with TanStack React Query
MIT
Contributions are welcome! Please feel free to submit a Pull Request.