Monorepo skeleton: Django + PostgreSQL API (backend/) and a React + TypeScript + Tailwind SPA (frontend/).
Generative-Platform/
├── backend/ # Django + DRF API
└── frontend/ # React + TypeScript + Tailwind SPA
No business logic lives here yet — this is just the scaffolding, wired end-to-end (the frontend calls the backend's health check to prove it).
- Python 3.12
- Node.js 18+ and npm
- PostgreSQL running locally (e.g.
brew install postgresql@16 && brew services start postgresql@16)
Create a local database for the project (only needs to be done once):
createdb generative_platformIf your local Postgres requires a specific user/password, adjust the command accordingly (e.g. createdb -U postgres generative_platform) — you'll use the same credentials in backend/.env in the next step.
cd backend
python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
cp .env.example .envOpen backend/.env and check DATABASE_URL matches your local Postgres setup:
DATABASE_URL=postgres://postgres@localhost:5432/generative_platform
Then apply migrations and start the server:
python manage.py migrate
python manage.py runserverThe API runs at http://localhost:8000. Confirm it's working:
curl http://localhost:8000/api/health/
# {"status": "ok"}Other useful commands (run from backend/ with the venv active):
pytest— run testsruff check .— lint
In a separate terminal:
cd frontend
npm install
cp .env.example .env
npm run devThe app runs at http://localhost:5173. frontend/.env's VITE_API_URL should point at the backend (defaults to http://localhost:8000, matching step 2).
Open http://localhost:5173 in a browser — you should see an "API: ok" badge, confirming the frontend successfully reached the backend.
Other useful commands (run from frontend/):
npm run lint— lintnpm run format— format with Prettiernpm run build— type-check and production build
| Package | Purpose |
|---|---|
Django |
Web framework |
djangorestframework |
REST API layer (serializers, views, the health check endpoint) |
django-environ |
Loads config (secret key, DEBUG, DATABASE_URL, allowed origins) from .env instead of hardcoding it |
django-cors-headers |
Lets the frontend (localhost:5173) call the backend (localhost:8000) from the browser |
psycopg2-binary |
PostgreSQL driver Django needs to talk to the database |
backend/requirements-dev.txt adds tools only needed while developing (installs everything in requirements.txt too):
| Package | Purpose |
|---|---|
pytest / pytest-django |
Test runner |
ruff |
Linter/formatter |
Install with pip install -r requirements-dev.txt locally. In a real deployment you'd install requirements.txt only.
| Package | Purpose |
|---|---|
react / react-dom |
UI library |
vite / @vitejs/plugin-react |
Dev server and build tool |
typescript |
Type checking |
tailwindcss / @tailwindcss/vite |
Utility-first CSS, wired into the Vite build |
oxlint |
Linter |
prettier |
Code formatter |
npm install installs all of these; dependencies vs devDependencies in package.json just marks which ones would still be needed at runtime if this were server-rendered — for a static build via npm run build, none of them ship to the browser except your own compiled code.
django.db.utils.OperationalError/ connection refused: Postgres isn't running, orDATABASE_URLinbackend/.envdoesn't match your local setup (wrong user, port, or database name).- "API: error" badge in the frontend: the backend isn't running, or
VITE_API_URLinfrontend/.envdoesn't match the port the backend is actually running on. - CORS errors in the browser console: make sure
CORS_ALLOWED_ORIGINSinbackend/.envincludes the exact origin the frontend is served from (default:http://localhost:5173). - Port already in use: another process (yours or someone else's) is bound to 8000 or 5173. Run either server on a different port, e.g.
python manage.py runserver 8010ornpm run dev -- --port 5199, and update the corresponding.envvalues to match.