When you generate thousands of AI images sweeping LoRAs, samplers, schedulers and denoise strengths, "which settings are best" stops being answerable by eyeballing folders. DART turns it into a tournament: upload batches, run pairwise battles, and let an ELO rating surface the parameter combinations that consistently win. Self-hosted, your images never leave your infrastructure.
- ⚔️ Battle Arena: pairwise image comparisons, one click per duel
- 📈 ELO Ranking: ratings converge on the truly best outputs (configurable K-factor)
- 🧪 Parameter Insights: attach generation metadata (LoRA, sampler, scheduler, denoise) and see which settings climb the ladder
- 🖼️ Bulk Upload: drag in image batches with or without JSON metadata
- 🗳️ Smart Annotation: coordinate-based tagging on any image
- 📤 Export Winners: dump top-ranked image filenames to txt for training pipelines
- 🏠 Self-hosted: Node + Next.js + MongoDB, images on your own S3-compatible storage
- 🧱 DDD Architecture: clean domain/application/infrastructure/presentation layering, full TypeScript
DART uses mise for one-command setup.
mise trust # trust the mise configuration
mise run install # install all dependencies
mise run dev # start everythingThat's it:
- Frontend: http://localhost:3000
- Backend API: http://localhost:3001
- Health check: http://localhost:3001/health
Other commands: mise run clean (remove node_modules/builds) and mise run reset (clean + reinstall).
dart/
├── backend/ # Node.js + Express, DDD layout
│ └── src/
│ ├── domain/ # Entities, value objects, repositories
│ ├── application/ # Use cases, services
│ ├── infrastructure/ # MongoDB, storage, external APIs
│ └── presentation/ # Controllers, routes
├── frontend/ # Next.js (App Router) + Tailwind
│ └── src/
│ ├── app/ # Pages
│ ├── components/ # Reusable components
│ └── lib/ # Utilities
└── mise.toml # Unified dev environment + env vars
All variables are managed through mise.toml, which generates backend/.env and frontend/.env.local:
| Variable | Purpose |
|---|---|
MONGODB_URI |
MongoDB connection string |
JWT_SECRET |
JWT signing secret |
FRONTEND_URL |
Frontend URL for CORS |
NEXT_PUBLIC_API_URL |
API URL for the frontend |
GET /api/v1/dreamshots # list images
POST /api/v1/dreamshots # create
GET /api/v1/dreamshots/:id # detail
PUT /api/v1/dreamshots/:id # update
DELETE /api/v1/dreamshots/:id # delete
POST /api/v1/dreamshots/:id/annotations # annotate
PUT /api/v1/dreamshots/:id/ranking # update ELO
GET /api/health # health check
Each image document carries its annotations (with x/y coordinates), its ranking (score, votes, average) and free-form tags. See the domain models in backend/src/domain/.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes
- Open a Pull Request
MIT - see LICENSE.
Made with ❤️ by javierjrueda at Dreamshot.io