A modern, production-ready starter template for building full-stack web applications with FastAPI (Python) backend and React (TypeScript) frontend, featuring Supabase authentication.
- React 18 with TypeScript
- Vite for build tooling
- TailwindCSS for styling
- shadcn/ui for UI components
- React Router for navigation
- Framer Motion for animations
- Supabase Client for authentication
- Lucide React for icons
- FastAPI (Python 3.11+)
- Uvicorn ASGI server
- Supabase Python Client for database operations
- Pydantic for data validation
- uv for Python virtual environment and package management
- concurrently for running frontend and backend simultaneously
- Node.js 22 (managed via nvm)
- Node.js 22+ (recommended: use nvm)
- Python 3.11+ (recommended: use pyenv)
- uv for Python package management
- A Supabase project (create one here)
# Install Node.js dependencies
npm install
# Setup backend (creates virtual environment and installs Python packages)
npm run setup:backendCreate environment files (these are gitignored and won't be committed):
Root .env file (for backend):
# Supabase Configuration
SUPABASE_URL=your_supabase_project_url
SUPABASE_SERVICE_KEY=your_supabase_service_role_keyfrontend/.env file (for frontend):
# Supabase Configuration
VITE_SUPABASE_URL=your_supabase_project_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_keyWhere to find Supabase keys:
- Go to your Supabase project dashboard
- Navigate to Settings → API
- Copy the
URLandanonkey for frontend - Copy the
service_rolekey for backend (keep this secret!)
# Run both frontend and backend simultaneously
npm run dev:bothOr run them separately:
# Terminal 1: Backend (runs on http://localhost:8000)
npm run backend
# Terminal 2: Frontend (runs on http://localhost:5173)
npm run frontend- Frontend: http://localhost:5173
- Backend API: http://localhost:8000
- API Docs: http://localhost:8000/docs
.
├── backend/
│ ├── app/
│ │ ├── core/
│ │ │ └── database.py # Supabase database client
│ │ ├── routes/
│ │ │ └── health.py # Health check endpoint
│ │ └── main.py # FastAPI application
│ └── requirements.txt # Python dependencies
├── frontend/
│ ├── src/
│ │ ├── api/
│ │ │ └── supabase.ts # Supabase client configuration
│ │ ├── components/
│ │ │ ├── ui/ # shadcn/ui components
│ │ │ └── Navbar.tsx # Navigation component
│ │ ├── pages/
│ │ │ ├── Login.tsx # Authentication page
│ │ │ ├── Dashboard.tsx # Protected dashboard
│ │ │ └── NotFound.tsx # 404 page
│ │ ├── App.tsx # Main app component with routing
│ │ └── main.tsx # Entry point
│ └── package.json
├── scripts/
│ ├── run-backend.js # Backend runner script
│ └── setup-backend.js # Backend setup script
└── README.md
- Email/password sign up and login
- Google OAuth authentication
- Password reset functionality
- Protected routes with automatic redirects
- Session management via Supabase Auth
- Pre-configured shadcn/ui components
- Responsive design with TailwindCSS
- Dark mode support (via shadcn/ui)
- Smooth animations with Framer Motion
- FastAPI with automatic API documentation
- CORS configured for development
- Health check endpoint
- Minimal database client setup
npm run dev- Start Vite dev servernpm run build- Build for productionnpm run preview- Preview production build
npm run setup:backend- Setup Python virtual environment and install dependenciesnpm run backend- Run FastAPI server with hot reload
npm run dev:both- Run both frontend and backend simultaneously
- Create a new file in
backend/app/routes/:
from fastapi import APIRouter
router = APIRouter()
@router.get("/example")
async def example():
return {"message": "Hello World"}- Include it in
backend/app/main.py:
from .routes import example
app.include_router(example.router, prefix="/example", tags=["Example"])- Create a new component in
frontend/src/pages/ - Add route in
frontend/src/App.tsx:
import NewPage from './pages/NewPage'
<Route path="/new-page" element={<NewPage />} />from app.core.database import db
# Access Supabase client
if db.client:
response = db.client.table("your_table").select("*").execute()
data = response.dataimport { supabase } from './api/supabase'
// Query data
const { data, error } = await supabase
.from('your_table')
.select('*')- Update
frontend/src/components/Navbar.tsx- change "App" to your app name - Update
frontend/src/pages/Login.tsx- change "Welcome" title
- Backend: Add to
.envin project root, access viaos.getenv() - Frontend: Add to
.envinfrontend/directory, prefix withVITE_, access viaimport.meta.env.VITE_YOUR_VAR
- TailwindCSS config:
frontend/tailwind.config.ts - Global styles:
frontend/src/styles/index.css - Component styles: Use Tailwind classes or CSS modules
- Build:
npm run build - Deploy the
frontend/distdirectory - Set environment variables in your hosting platform
- Ensure
requirements.txtis up to date - Set environment variables
- Deploy with Python 3.11+ runtime
- Run:
uvicorn app.main:app --host 0.0.0.0 --port $PORT
- Virtual environment not found: Run
npm run setup:backend - Import errors: Ensure you're in the
backend/directory or using the venv Python - Supabase connection fails: Check
.envfile has correctSUPABASE_URLandSUPABASE_SERVICE_KEY
- Supabase auth not working: Verify
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEYinfrontend/.env - Build errors: Clear
node_modulesand reinstall:rm -rf node_modules && npm install - Port already in use: Change port in
frontend/vite.config.tsor kill the process using the port
MIT
This is a starter template. Feel free to fork and customize for your needs!