A full-stack monorepo starter template for building applications with the Copera SDK. Built with Fastify, React, and MongoDB — ready for production deployment.
This monorepo contains everything you need to build, develop, and deploy a Copera-powered application:
| Workspace | Path | Description |
|---|---|---|
| API | apps/api |
Fastify REST API with MongoDB, JWT auth, and Copera SDK integration |
| Web | apps/web |
React 19 SPA with Tailwind CSS, React Query, and Zustand |
| Common | packages/common |
Shared utilities — MongoDB connection, HTTP error classes, logger |
| Layer | Technologies |
|---|---|
| Backend | Fastify 5, Typegoose (Mongoose 9), JWT, Pino, Copera SDK |
| Frontend | React 19, Vite 7, Tailwind CSS 4, React Query 5, Zustand 5, React Router 7 |
| Shared | TypeScript 5.9, Zod, Yup |
| Tooling | pnpm workspaces, Turborepo, Biome, Husky, Commitlint |
| Infrastructure | Docker, GitHub Actions, AWS S3 + CloudFront |
- Node.js >= 24.0.0 (
.nvmrc: v24.13.0) - pnpm 10.28.2 (via corepack)
- MongoDB (create a free cluster on MongoDB Atlas)
- A Copera API key (see the developer docs for how to obtain one)
# Clone the repository
git clone https://github.com/copera-ai/base-application-template.git
cd base-application-template
# Enable corepack and activate pnpm
corepack enable
corepack prepare pnpm@10.28.2 --activate
# Install dependencies
pnpm install
# Configure environment variables
cp apps/api/.env.example apps/api/.env
# Edit apps/api/.env with your values (see Environment Variables below)
# Start all apps in development mode
pnpm devThe API will be available at http://localhost:7071 and the web app at http://localhost:8087.
| Variable | Description |
|---|---|
MONGODB_URI |
MongoDB connection string (create a free cluster) |
APP_TOKEN |
Secret key used for JWT signing |
COPERA_API_KEY |
Your Copera API key (how to get one) |
| Variable | Description |
|---|---|
VITE_SERVER_URL |
API base URL (default: http://localhost:7071/api) |
| Command | Description |
|---|---|
pnpm dev |
Start all apps in development mode |
pnpm dev:api |
Start API only (port 7071) |
pnpm dev:web |
Start Web only (port 8087) |
pnpm build:api |
Build API for production |
pnpm build:web |
Build Web for production |
pnpm start:api |
Start API in production mode |
pnpm start:web |
Start Web in production mode |
pnpm test |
Run API tests (Vitest) |
pnpm lint |
Biome lint & format check |
pnpm lint --fix |
Biome lint & auto-fix |
pnpm type-check |
TypeScript type-check all packages |
base-application-template/
├── apps/
│ ├── api/ # Fastify REST API
│ │ ├── src/
│ │ │ ├── service/ # Controllers & services by domain
│ │ │ ├── models/ # Typegoose data models
│ │ │ ├── infra/ # Server & Copera SDK setup
│ │ │ ├── utils/ # Hooks, decorators, helpers
│ │ │ └── main.ts # Entry point
│ │ └── .env.example
│ └── web/ # React SPA
│ └── src/
│ ├── auth/ # AuthProvider, guards, hooks
│ ├── components/ # UI components (shadcn/ui)
│ ├── hooks/ # React Query hooks
│ ├── pages/ # Page components
│ ├── requests/ # API request functions (Axios)
│ ├── stores/ # Zustand stores
│ └── main.tsx # Entry point
├── packages/
│ └── common/ # Shared utilities
│ └── src/
│ ├── index.ts # Main exports
│ ├── core/ # MongoDB connection
│ └── api-utils/ # HTTP error classes
├── infra/
│ ├── Dockerfile.api # Production Docker image
│ ├── docker-compose.yml # Production compose config
│ └── .env.example # Production env template
├── patches/ # Patched dependencies
├── biome.json # Linter & formatter config
├── turbo.json # Turborepo task config
├── pnpm-workspace.yaml # Workspace & dependency catalogs
└── commitlint.config.js # Commit message rules
Fastify REST API using the controller/service pattern via fastify-decorators.
- Dev port: 7071 | Prod port: 3000
- Routes require JWT auth by default; use
@isPublic()to skip - Services write to Copera SDK and cache locally in MongoDB
- Logging via Pino (
no-consolerule enforced) - Path alias:
~/maps tosrc/
React 19 SPA with a shadcn/ui component library.
- Dev port: 8087
- API calls in
src/requests/, React Query hooks insrc/hooks/ - Auth via
AuthProvidercontext withAuthGuard/GuestGuardroute wrappers - Client state managed with Zustand stores
- Path aliases:
src/and@components/map tosrc/andsrc/components/
The infra/ directory contains everything needed to deploy the API:
# 1. Configure environment
cp infra/.env.example infra/.env
# Edit infra/.env with production values
# 2. Pull and start the container
cd infra
docker compose up -dThe pre-built image is published to ghcr.io/copera-ai/base-app-api:latest.
A health check endpoint is available at /health.
docker build -f infra/Dockerfile.api -t base-app-api .GitHub Actions workflows automate deployment on push to main:
- Change detection —
changed_apps.yamluses git diff to determine which apps were modified - Web — Builds with Vite, syncs to S3, and invalidates the CloudFront cache
- API — Builds a Docker image, pushes to GHCR, and deploys to a VPS via SSH
- Linting & formatting: Biome (not ESLint/Prettier) — run
pnpm lint - Pre-commit hooks: Husky + lint-staged run Biome on staged files
- Commit messages: Conventional Commits enforced by commitlint
- Format:
type(scope): message(e.g.,feat(api): add ticket filtering) - Types:
feat,fix,docs,style,refactor,test,chore, etc.
- Format:
- VS Code: Biome extension recommended for editor integration
- Fork the repository
- Create a feature branch (
git checkout -b feat/my-feature) - Make your changes following the conventions above
- Run checks before committing:
pnpm lint pnpm type-check pnpm test - Commit using conventional commits (
feat:,fix:,docs:, etc.) - Open a Pull Request
This project is licensed under the MIT License — see the LICENSE file for details.