A modern monorepo starter template with web frontend, API backend, and PostgreSQL database.
- 🚀 Modern Stack: React/NextJs, Express.js, PostgreSQL
- 📦 Monorepo Structure: Using pnpm workspaces
- 🐳 Docker Support: Development and production ready
- ☸️ Kubernetes Support: Production-grade deployment
- 🔄 TypeScript: Full type safety
- 📝 Prisma: Type-safe database access
- 🧪 Testing: Vitest for unit and integration tests
.
├── apps/
│ ├── web/ # React frontend
│ └── api/ # Express.js backend
├── packages/ # Shared packages
│ ├── auth/ # Authentication package
│ ├── db/ # Database package
│ ├── logger/ # Logging package
│ ├── ui/ # UI components
│ └── typescript-config/ # TypeScript configuration
├── docs/ # Documentation
│ ├── architecture.md # Architecture documentation
│ └── kubernetes.md # Kubernetes documentation
├── kubernetes/ # Kubernetes configurations
└── docker-compose.yml
- Node.js 22+
- pnpm
- Docker and Docker Compose
- Kubernetes (for production deployment)
- Install dependencies:
pnpm install- Start development environment:
docker-compose up -d- Start development servers:
# Terminal 1 - Web
pnpm --filter web dev
# Terminal 2 - API
pnpm --filter api devThe application will be available at:
- Web: http://localhost:3000
- API: http://localhost:3001
- Database: localhost:5432
docker-compose -f docker-compose.prod.yml up -dSee Kubernetes Deployment Guide for detailed instructions.
The application consists of three main components:
- Web Frontend: React application with Tailwind CSS
- API Backend: Express.js server with Prisma ORM
- Database: PostgreSQL for data persistence
See Architecture Documentation for detailed diagrams and explanations.
# Install dependencies
pnpm install
# Start development servers
pnpm dev
# Build all packages and applications
pnpm build
# Run tests
pnpm test
# Lint code
pnpm lint
# Type check
pnpm typecheck# Generate Prisma client
pnpm --filter api prisma generate
# Run database migrations
pnpm --filter api prisma migrate dev
# Reset database
pnpm --filter api prisma migrate reset# Run all tests
pnpm test
# Run tests for specific package
pnpm --filter @repo/api test- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Run the following command:
git clone https://github.com/jellydn/monorepo-starteror
pnpm dlx create-turbo@latest -m pnpm -e https://github.com/jellydn/monorepo-starter YOUR_PROJECTThis Turborepo includes the following:
web: a Next.js appapi: an Express server@repo/ui: a React component library@repo/typescript-config: tsconfig.json's used throughout the monorepo
Each package/app is 100% TypeScript.
This repo is configured to be built with Docker, and Docker compose. To build all apps in this repo:
# Install dependencies
pnpm install
# Create a network, which allows containers to communicate
# with each other, by using their container name as a hostname
docker network create app_network
# Build prod using new BuildKit engine
COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose -f docker-compose.yml build
# Start prod in detached mode
docker-compose -f docker-compose.yml up -dOpen http://localhost:3000.
To shutdown all runnin containers:
# Stop all running containers
docker kill $(docker ps -q) && docker rm $(docker ps -a -q)This repo is configured to publish Docker images to GitHub Container Registry (GHCR). The images are automatically built and published when you push to the main branch or create a new tag.
The GitHub Actions workflow builds and publishes Docker images in parallel for faster execution:
- The web and API images are built simultaneously in separate jobs
- Each build supports multi-architecture images
- A summary job runs after all builds are complete to report the status
The Docker images are built for multiple architectures:
linux/amd64- For Intel/AMD processors (standard x86_64 architecture)linux/arm64- For ARM processors (Apple Silicon M1/M2/M3, AWS Graviton, etc.)
This ensures that the images can run on various platforms without compatibility issues.
Instead of building Docker images locally, you can use the pre-built images from GHCR:
- Create a
.envfile based on the.env.exampletemplate:
cp .env.example .env- Edit the
.envfile with your GitHub username and repository name:
GHCR_USERNAME=your-github-username
GHCR_REPO=monorepo-starter
GHCR_REGISTRY=ghcr.io
GHCR_TAG=latest
- Log in to GitHub Container Registry:
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin- Start the containers using the pre-built images:
docker-compose up -dFor convenience, a helper script is provided to simplify working with GHCR images:
./use-ghcr-images.shThis interactive script provides the following options:
- Pull and use GHCR images with docker-compose
- Pull and use GHCR images with Kubernetes
- Check available tags for images
- Login to GitHub Container Registry
The script will automatically create a .env file with default values if one doesn't exist.
The following tags are available for the Docker images:
latest: The latest build from themainbranchmain: The latest build from themainbranchvX.Y.Z: Specific version tags (e.g.,v1.0.0)sha-XXXXXXX: Specific commit SHA
This repo includes Kubernetes manifests and scripts to deploy the application to any Kubernetes cluster, whether local, cloud-based, or on-premises.
This repository offers two Kubernetes deployment templates:
If you're new to Kubernetes, you can use the basic template available at basic-k8s branch. This template provides a simpler structure with all configuration in a single k8s directory.
# Clone the repository with the basic-k8s branch
git clone -b basic-k8s https://github.com/jellydn/monorepo-starter.git
cd monorepo-starter
# Set up a local Kubernetes cluster with kind
./k8s/setup-local.sh
# Deploy the application to the local cluster
./k8s/deploy.shThe main branch uses a more sophisticated structure with Kustomize overlays for different environments. This approach is better suited for production deployments and multi-environment setups.
To set up a local Kubernetes environment:
# Set up a local Kubernetes cluster with kind
./kubernetes/scripts/setup-local.sh
# Deploy the application to the local cluster
./kubernetes/scripts/deploy-local.shFor production deployment with Cloudflare as a proxy:
# Deploy with Cloudflare integration
REGISTRY_URL=your-registry.example.com \
CONTEXT=your-production-context \
DOMAIN=next-app-demo.itman.fyi \
API_DOMAIN=express-api-demo.itman.fyi \
./kubernetes/scripts/deploy-production.shFor more details, see the Kubernetes Documentation.
Tip
Vercel Remote Cache is free for all plans. Get started today at vercel.com.
This example includes optional remote caching. In the Dockerfiles of the apps, uncomment the build arguments for TURBO_TEAM and TURBO_TOKEN. Then, pass these build arguments to your Docker build.
You can test this behavior using a command like:
docker build -f apps/web/Dockerfile . --build-arg TURBO_TEAM="your-team-name" --build-arg TURBO_TOKEN="your-token" --no-cache
This Turborepo has some additional tools already setup for you:
- TypeScript for static type checking
- Biome for format, lint, and more in a fraction of a second.