This project provides a full-stack, type-safe web application combining Django REST Framework (DRF) and Next.js. It uses drf-spectacular to automatically generate an OpenAPI schema from Django serializers, and @hey-api/openapi-ts on the Next.js side to generate a fully typed TypeScript client.
With this setup:
- The backend defines the API schema via Django serializers and views.
- The frontend consumes it safely with auto-generated TypeScript clients.
- Traefik handles HTTPS routing and certificate management.
- Docker Compose orchestrates everything: Django, Next.js, PostgreSQL, Redis, and Traefik.
- End-to-End Type Safety: Django serializers → OpenAPI → TypeScript client.
- Auto-Generated API Client: Managed via
@hey-api/openapi-ts. - Cookie-Based Auth: Secure login and refresh tokens stored as HTTP-only cookies.
- Full Docker Support: Run Django, Next.js, Postgres, and Redis with a single command.
- Traefik Reverse Proxy: Automatic HTTPS and routing with Let's Encrypt.
- Live OpenAPI Docs: Auto-generated
/api/schema/swagger-ui/endpoint. - Developer-Friendly Scripts: Simplified commands for schema generation and client updates.
┌───────────────────────────┐
│ Traefik │
│ HTTPS + Reverse Proxy │
└──────────┬────────────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
┌───────────────┐ ┌────────────────┐ ┌──────────────────┐
│ Next.js │ │ Django DRF │ │ PostgreSQL │
│ (Frontend) │ │ (Backend API) │ │ (Data Storage) │
│ @hey-api │<--->│ drf-spectacular│ │ │
└───────────────┘ └────────────────┘ └──────────────────┘
│
┌──────────────┐
│ Redis │
│ (Cache/Celery│
│ Backend) │
└──────────────┘
- Docker: Install Docker
- Docker Compose: Install Docker Compose
- Domain Name: For serving HTTPS via Traefik.
- Node.js + pnpm: (only required for local development on the Next.js app)
-
Clone the Repository
git clone https://github.com/yourusername/django-next-type-safe-api.git cd django-next-type-safe-api -
Create Environment File
cp .env.example .env
Edit
.envwith your configuration values (see Environment Variables). -
Create Traefik Network
docker network create traefik-public
-
Build and Start the Stack
docker compose -f docker-compose.yml -f docker-compose-traefik.yml up --build
This builds all containers and starts the stack in the background.
| Variable | Description | Example |
|---|---|---|
| ROOT_DOMAIN | Base domain used for backend and frontend | example.com |
| NEXT_DOMAIN | Domain for the Next.js app | app.example.com |
| DJANGO_SECRET_KEY | Django secret key | supersecretkey |
| POSTGRES_DB | Database name | app_db |
| POSTGRES_USER | Database username | app_user |
| POSTGRES_PASSWORD | Database password | securepassword |
| CORS_ALLOWED_ORIGINS | Allowed origins for frontend requests | https://app.example.com |
| ACME_EMAIL | Email for Let's Encrypt certificate notifications | admin@example.com |
| Service | Description |
|---|---|
| traefik | Reverse proxy, SSL termination, auto certificates |
| django | Django REST API backend |
| next | Next.js frontend (SSR with API client) |
| postgres | PostgreSQL database |
| redis | Cache and Celery message broker |
| Volume | Purpose |
|---|---|
./django:/app |
Django source code |
./next:/app |
Next.js source code |
./postgres_data |
PostgreSQL persistent data |
traefik-public-certificates |
Let's Encrypt certificates |
- Frontend:
https://app.example.com - Backend API Root:
https://example.com/api/ - Swagger UI:
https://example.com/api/schema/swagger-ui/
# Start
docker compose up -d
# Stop
docker compose down
# Logs
docker compose logs -fdocker compose exec django python manage.py createsuperuserThe Next.js app uses the OpenAPI JSON generated by Django to build a fully typed TypeScript API client.
-
Generate Schema (from Django)
docker compose exec django python manage.py spectacular --file schema.yamlThis outputs the latest OpenAPI schema from your Django app.
-
Generate TypeScript Client
Inside the Next.js directory:
cd next pnpm openapiThis runs two scripts:
pnpm openapi:download→ downloads the latest OpenAPI JSON from Django.pnpm openapi:generate→ uses@hey-api/openapi-tsto build the typed client.
-
Use the Client in Next.js
import { apiTodosList, apiTodosCreate } from '@/client' const todos = await apiTodosList() const newTodo = await apiTodosCreate({ body: { title: 'Hello world' } })
Each service logs to standard output and can be viewed with Docker:
docker compose logs -f django
docker compose logs -f nextBackend: Django logging configuration in settings.py (JSON format optional).
Frontend: Next.js logs in container output.
Traefik: Access and error logs persisted for HTTPS routing diagnostics.
| Issue | Possible Cause | Fix |
|---|---|---|
| Traefik not accessible | Port 80/443 blocked | Ensure ports 80 and 443 are open |
| Frontend cannot fetch API | CORS or cookie config | Check CORS_ALLOWED_ORIGINS and credentials settings |
| Schema not generating | Missing drf-spectacular | Run pip install drf-spectacular and restart |
| OpenAPI client outdated | Backend schema changed | Run pnpm openapi in next/ directory |
| Django migrations fail | Postgres not ready | Re-run docker compose up -d after DB starts |
Contributions are welcome! To add new features or fix bugs:
git checkout -b feature/your-feature
git commit -m "Add your feature"
git push origin feature/your-featureThen open a Pull Request with a clear description.