Put your wardrobe in rows. Snap. Organize. Wear.
Built with Claude Code Next.js FastAPI TypeScript Python
Features • Quick Start • Languages • Deployment • Architecture • Contributing
Google Play - Coming Soon App Store
Self-hosted wardrobe management with AI-powered outfit recommendations. Take photos of your clothes, let AI tag them, and get daily outfit suggestions based on weather and occasion.
- Photo-based wardrobe - Upload photos, AI extracts clothing details automatically
- Smart recommendations - Outfits matched to weather, occasion, and your preferences
- Scheduled notifications - Daily outfit suggestions via ntfy/Mattermost/email
- Family support - Manage wardrobes for household members
- Wear tracking - History, ratings, and outfit feedback
- Analytics - See what you wear, what you don't, color distribution
- Fully self-hosted - Your data stays on your hardware
- Works with any AI - OpenAI, Ollama, LocalAI, or any OpenAI-compatible API
- 8 languages - English, Chinese (Simplified & Traditional), Korean, Japanese, French, German, Italian
Wardrowbe's UI is fully translated into 8 languages via next-intl. Pick a language from Settings, or let it follow your browser automatically.
| Language | Locale code |
|---|---|
| English | en |
| 中文简体 (Chinese, Simplified) | zh-CN |
| 中文繁體 (Chinese, Traditional) | zh-TW |
| 한국어 (Korean) | ko |
| 日本語 (Japanese) | ja |
| Français (French) | fr |
| Deutsch (German) | de |
| Italiano (Italian) | it |
Want to add a language or improve a translation? See Internationalization in the contributing guide.
| Grid View | Item Details & AI Analysis |
|---|---|
| Wardrobe | Item Details |
| Wash Tracking | Suggestions |
|---|---|
| Wash Tracking | Suggest |
| History Calendar | Analytics |
|---|---|
| History | Analytics |
| Pairing View | Pairing Modal |
|---|---|
| Pairing | Pairing Modal |
- Docker and Docker Compose installed
- At least 4GB of RAM available
- An AI service (Ollama recommended for free local AI, or OpenAI API key)
Option A: Using Ollama (Recommended - Free, runs locally)
# Install Ollama from https://ollama.ai # Then pull required models: ollama pull gemma3 # Multimodel LLM (for image analysis and outfit recommendations) # Verify it's running: curl http://localhost:11434/api/tags
Option B: Using OpenAI (Paid API)
Get your API key from https://platform.openai.com/api-keys
# Clone the repository git clone https://github.com/yourusername/wardrowbe.git cd wardrowbe # Copy environment template cp .env.example .env # IMPORTANT: Edit .env and configure AI settings # For Ollama (default in .env.example): # AI_BASE_URL=http://host.docker.internal:11434/v1 # AI_VISION_MODEL=gemma3:latest # AI_TEXT_MODEL=gemma3:latest # # For OpenAI, uncomment and set: # AI_BASE_URL=https://api.openai.com/v1 # AI_API_KEY=sk-your-api-key-here # AI_VISION_MODEL=gpt-4o # AI_TEXT_MODEL=gpt-4o # Optional: Generate secure secrets for production # SECRET_KEY=$(openssl rand -hex 32) # NEXTAUTH_SECRET=$(openssl rand -hex 32)
docker-compose.yml pulls pre-built multi-arch images (linux/amd64 and linux/arm64, so Raspberry Pi and other ARM hosts work) from GitHub Container Registry. No local build tooling is required on the host.
# Pull the latest published images, then start all containers docker compose pull docker compose up -d # Wait for services to be healthy (30 seconds) docker compose ps # Run database migrations (REQUIRED) docker compose exec backend alembic upgrade head # Verify everything is working curl http://localhost:8000/api/v1/health # Should return: {"status":"healthy"}
To build the images from source instead of pulling them, use the development stack below (docker-compose.dev.yml), which builds locally and enables hot reload.
- Frontend: http://localhost:3000
- API Docs: http://localhost:8000/docs
- Login: Click "Login" - uses dev credentials by default (no password needed)
For hot reloading during development (auto-rebuilds on code changes):
# Start in dev mode docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d # Run migrations (first time only) docker compose exec backend alembic upgrade head # View logs docker compose logs -f frontend backend
Wardrowbe works with any OpenAI-compatible API. You need two types of models:
- Vision model: Analyzes clothing images to extract colors, patterns, styles
- Text model: Generates outfit recommendations and descriptions
Internal AI is optional. Set AI_INTERNAL_ENABLED=false to run the backend with
no internal AI provider at all — it boots and serves without AI_BASE_URL,
AI_API_KEY, or model names configured, and defers tagging/suggestions/pairings
to an external agent. You can also disable a single capability with
AI_VISION_ENABLED=false (auto-tagging) or AI_TEXT_ENABLED=false
(suggestions/pairings); unset switches inherit the master. The effective state is
reported at GET /api/v1/capabilities. Defaults keep internal AI on, so
existing deployments are unaffected.
Free, runs locally, no API key needed, works offline
-
Install Ollama
-
Pull models:
ollama pull gemma3:latest # multimodel LLM (3.4GB) - analyze images and generates recommendations # Alternative text models you can use: # ollama pull llama3:latest # Good all-around model # ollama pull qwen2.5:latest # Fast and efficient # ollama pull mistral:latest # Great for creative text
-
Configure in
.env:AI_BASE_URL=http://host.docker.internal:11434/v1 AI_API_KEY=not-needed AI_VISION_MODEL=gemma3:latest AI_TEXT_MODEL=gemma3:latest
Note: Use host.docker.internal instead of localhost so Docker containers can reach your host's Ollama.
Paid API, requires internet connection
- Get API key from https://platform.openai.com/api-keys
- Configure in
.env:AI_BASE_URL=https://api.openai.com/v1 AI_API_KEY=sk-your-api-key-here AI_VISION_MODEL=gpt-4o AI_TEXT_MODEL=gpt-4o
Self-hosted OpenAI alternative
AI_BASE_URL=http://localai:8080/v1 AI_API_KEY=not-needed AI_VISION_MODEL=gpt-4-vision-preview AI_TEXT_MODEL=gpt-3.5-turbo
Some models can handle both vision and text (like qwen2-vl, llama3.2-vision):
AI_VISION_MODEL=llama3.2-vision:11b AI_TEXT_MODEL=llama3.2-vision:11b # Same model for both tasks
┌─────────────────────────────────────────────────────────────┐
│ Frontend │
│ (Next.js + React Query) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Backend │
│ (FastAPI + SQLAlchemy) │
└──────────┬──────────────┬──────────────────┬────────────────┘
│ │ │
┌──────▼──────┐ ┌─────▼─────┐ ┌──────▼──────┐
│ PostgreSQL │ │ Redis │ │ AI Service │
│ (Database) │ │ (Job Queue)│ │ (OpenAI/etc)│
└─────────────┘ └─────┬─────┘ └─────────────┘
│
┌──────────▼──────────┐
│ Background Worker │
│ (arq - AI Jobs) │
└─────────────────────┘
| Layer | Technology |
|---|---|
| Frontend | Next.js 14, TypeScript, TanStack Query, Tailwind CSS, shadcn/ui |
| Backend | FastAPI, SQLAlchemy (async), Pydantic, Python 3.11+ |
| Database | PostgreSQL 15 |
| Cache/Queue | Redis 7 |
| Background Jobs | arq |
| Authentication | NextAuth.js (supports OIDC, dev credentials) |
| AI | Any OpenAI-compatible API |
See docker-compose.prod.yml for production configuration. Like the default stack, it pulls pre-built images from GHCR rather than building on the host.
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
docker compose exec backend alembic upgrade headImages are tagged backend-latest / frontend-latest, and each release also
publishes backend-<version> / frontend-<version> (e.g. backend-1.3.0). To
pin a deployment to a specific release, replace the -latest tags in the
compose file with the version, e.g. ghcr.io/anyesh/wardrowbe:backend-1.3.0.
See the k8s/ directory for Kubernetes manifests including:
- PostgreSQL and Redis with persistent storage
- Backend API and worker deployments
- Next.js frontend
- Ingress with TLS
- Network policies
| Variable | Description | Required |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | Yes |
SECRET_KEY |
Backend secret for JWT | Yes |
PUID |
Uid the app process runs as (default: 1000 backend/worker, 1001 frontend) | No |
PGID |
Gid the app process runs as (default: 1000 backend/worker, 1001 frontend) | No |
NEXTAUTH_SECRET |
NextAuth session encryption | Yes |
AI_BASE_URL |
AI service URL | Yes |
AI_API_KEY |
AI API key (if required) | Depends |
OIDC_ISSUER_URL |
OIDC provider URL (enables SSO login) | No |
OIDC_CLIENT_ID |
OIDC client ID | If OIDC |
OIDC_CLIENT_SECRET |
OIDC client secret | If OIDC |
OIDC_SKIP_SSL_VERIFY |
Skip TLS verification for OIDC provider (self-signed certs) | No |
LOCAL_DNS |
Custom DNS server for container name resolution (e.g. local OIDC host) | No |
SMTP_HOST |
SMTP server for email notifications | No |
SMTP_PORT |
SMTP port (default: 587) | No |
SMTP_USER |
SMTP username | No |
SMTP_PASSWORD |
SMTP password | No |
BG_REMOVAL_PROVIDER |
Background removal backend: rembg or http (default: rembg) |
No |
BG_REMOVAL_MODEL |
rembg model name (default: u2net) |
No |
BG_REMOVAL_URL |
URL for HTTP bg removal provider | If http |
BG_REMOVAL_API_KEY |
API key for HTTP bg removal provider | No |
NEXT_PUBLIC_ENABLE_IP_LOCATION_FALLBACK |
Enable IP-based approximate location when browser geolocation is denied/unavailable. Off by default (sends the user's IP to a third party). Set to true to enable |
No |
NEXT_PUBLIC_NETWORK_LOCATION_URL |
Override the IP geolocation provider (default: https://ipapi.co/json/). Only used when the fallback above is enabled |
No |
See .env.example for all options.
The Settings page can fill in your coordinates from the browser's Geolocation API. If that is denied or unavailable, an optional fallback can approximate your location from your IP address via a third-party service (ipapi.co by default). This fallback is disabled by default because it sends the user's IP to an external provider; enable it with NEXT_PUBLIC_ENABLE_IP_LOCATION_FALLBACK=true and optionally point NEXT_PUBLIC_NETWORK_LOCATION_URL at a provider you trust. These are build-time frontend variables, so set them before building the frontend image. Geocoding a location name you type yourself still uses OpenStreetMap Nominatim regardless of this setting.
Remove image backgrounds from wardrobe items. Two backends supported:
rembg (local, default):
pip install rembg[cpu] # add to your image, or install manuallyNo config needed — works out of the box. Change model with BG_REMOVAL_MODEL (default: u2net, options: isnet-general-use, silueta, u2netp).
HTTP provider (e.g. withoutbg):
BG_REMOVAL_PROVIDER=http BG_REMOVAL_URL=http://withoutbg:5000 BG_REMOVAL_API_KEY= # optional
If neither is configured, the remove-background button returns a 501 with setup instructions.
- Development Mode (default): Simple email/name login, no setup required
- OIDC Mode: Any OIDC provider (PocketID, Authentik, Keycloak, Auth0, etc.)
To enable OIDC, set OIDC_ISSUER_URL, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET in your .env. If your OIDC provider uses a self-signed certificate, set OIDC_SKIP_SSL_VERIFY=true. If your OIDC provider runs on a hostname that Docker containers can't resolve (e.g. a local DNS name), set LOCAL_DNS to your DNS server IP, or set OIDC_HOST and OIDC_HOST_IP to inject the hostname directly into the container's /etc/hosts.
When registering the app in your OIDC provider, use this as the callback/redirect URI:
{NEXTAUTH_URL}/api/auth/callback/oidc
For example, if NEXTAUTH_URL=http://localhost:8080, the callback URL is:
http://localhost:8080/api/auth/callback/oidc
- ntfy.sh: Free push notifications
- Email: SMTP-based (set
SMTP_HOST,SMTP_USER,SMTP_PASSWORDin.env)
Uses Open-Meteo - free, no API key needed.
# Run tests (requires running containers) docker compose exec backend python -m pytest tests/ -v --tb=short # Run a specific test file docker compose exec backend python -m pytest tests/test_notification_workers.py -v # Lint pip install ruff ruff check --fix backend/app/ && ruff format backend/app/
cd frontend npm install # Run dev server npm run dev # Run tests npm test # Build npm run build
Available when running:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
# Check for type errors cd frontend npm install npx tsc --noEmit # If you see errors, please report them as a bug
# 1. Check all services are healthy docker compose ps # 2. Check backend is responding curl http://localhost:8000/api/v1/health # 3. Verify migrations ran successfully docker compose exec backend alembic current # 4. Check logs for errors docker compose logs backend frontend --tail=50 # 5. If migrations failed, run them manually docker compose exec backend alembic upgrade head
# For Ollama users: # 1. Verify Ollama is running and accessible curl http://localhost:11434/api/tags # Should show your installed models # 2. Check you have the vision model ollama list | grep gemma # 3. Verify .env has correct configuration cat .env | grep AI_ # 4. Check worker logs for AI errors docker compose logs worker --tail=50 # For OpenAI users: # 1. Verify API key is valid curl https://api.openai.com/v1/models \ -H "Authorization: Bearer $AI_API_KEY" # 2. Check you have credits remaining in your account
# 1. Ensure you're using the dev compose file docker compose -f docker-compose.yml -f docker-compose.dev.yml down docker compose -f docker-compose.yml -f docker-compose.dev.yml build frontend docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d # 2. Check frontend logs docker compose logs frontend -f # Alternative: Run frontend locally for development cd frontend npm install npm run dev # Then access at http://localhost:3000
# Check what's using the ports sudo lsof -i :3000 # Frontend sudo lsof -i :8000 # Backend sudo lsof -i :5432 # PostgreSQL sudo lsof -i :6379 # Redis # Stop conflicting services or change ports in .env
# Check current migration version docker compose exec backend alembic current # View migration history docker compose exec backend alembic history # If migrations are corrupted, reset (WARNING: Deletes all data!) docker compose down -v docker compose up -d sleep 10 docker compose exec backend alembic upgrade head
# Check container logs docker compose logs <service-name> --tail=100 # Common issues: # - Database not ready: Wait 30 seconds and retry # - Out of memory: Increase Docker memory limit # - Permission errors: Check file permissions on volumes
# Check resource usage docker stats # If backend is slow: # 1. Check PostgreSQL performance docker compose exec postgres psql -U wardrobe -c "SELECT * FROM pg_stat_activity;" # 2. Check Redis connection docker compose exec redis redis-cli ping # If AI analysis is slow: # - For Ollama: Use smaller quantized models # - For OpenAI: Check your rate limits
If you're still stuck:
- Check existing GitHub Issues
- Search Discussions
- Create a new issue with:
- Output of
docker compose ps - Relevant logs from
docker compose logs - Your .env configuration (redact secrets!)
- Steps to reproduce the problem
- Output of
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
If you find wardrowbe useful, consider supporting its development:
Thanks to our supporters:
This project is licensed under the MIT License - see the LICENSE file for details.
- Docker & Docker Compose
- ~4GB RAM (with local Ollama models)
- Storage for clothing photos
Works great on a Raspberry Pi 5!