- Mobile bottom nav: icons, 56px targets, safe-area padding, and a "More" menu so Genetics/Shows/Settings are reachable on phones - Sticky sidebar, max-width content column, min-w-0 so wide children (pedigree tree, tables) scroll in place instead of widening the page - PageHeader owns no gutter and stacks actions on small screens; pages share one flex/gap structure and a consistent loading header - 16px inputs on mobile to stop iOS focus zoom; disabled button styling - Remove placeholder "0 litters / 0 kits" on rabbit cards, duplicate name on Rabbit Detail; proper Genetics placeholder and 404 pages Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| client | ||
| server | ||
| README.md | ||
| docker-compose.yml | ||
README.md
MyKindlebox
A self-hosted rabbitry (rabbit breeding herd) management web app — track your rabbits, their pedigrees, litters, and genetics. Self-hosted, with simple user accounts sharing one herd, and designed to replace a legacy PHP herd-management site.
The core differentiator: adding a rabbit starts from a pedigree tree, not a blank form. The 3-generation ancestor tree (sire/dam and their sires/dams) is the primary data-entry surface, with inline autocomplete against your existing herd and graceful fallback to freeform text for bought-in or unknown ancestors.
Features
- Pedigree-first rabbit entry — build the ancestor tree first, then fill in details; unknown ancestors can be stored as plain text so entry is never blocked by missing records.
- Herd management — name, sex, DOB, weight, and status
(
active/for_sale/on_hold/sold/deceased/other). - Litters — record kindle dates and kit counts; the kit list is derived live from Rabbit records (no separate Kit table).
- Genetics — per-rabbit loci (
A/B/C/D/E/En/V) and a session-only pairing calculator for predicting offspring. - Dashboard — herd counts derived live from rabbit status.
- Pedigree printing, CSV import/export, and a configurable weight display (decimal lbs or lb + oz).
- PWA-ready with a mobile bottom nav, installable on phones/tablets.
Tech stack
| Layer | Choice |
|---|---|
| Frontend | React 19 + Vite (PWA-ready) |
| Routing | React Router v7 |
| State | React Query (server sync) |
| Styling | Tailwind CSS |
| Backend | Node.js + Express 5 (REST API) |
| Database | SQLite via Drizzle ORM (single-file DB) |
| Auth | User accounts, shared herd (scrypt + DB sessions) |
| Hosting | Docker Compose (Nginx + Node + SQLite volume) |
Project layout
mykindlebox/
├── client/ React + Vite frontend
├── server/ Express + SQLite/Drizzle API
└── docker-compose.yml Production stack (nginx + node + volume)
Development
Run the backend and frontend in two terminals.
Backend (server/):
cd server
npm install
npm run dev # API on http://localhost:3001 (tsx watch, hot reload)
Other scripts: npm run build (typecheck + compile to dist/),
npm start (run compiled server), npm test.
Frontend (client/):
cd client
npm install
npm run dev # Vite dev server on http://localhost:5173
The dev server proxies /api and /uploads to localhost:3001. Other
scripts: npm run build, npm run lint, npm test.
The client talks to the API over relative URLs (
/api,/uploads) so the app works over LAN and as an installed PWA — never hardcode a host.
Deployment (Docker Compose)
From the mykindlebox/ directory:
docker compose up --build
The app is served on http://localhost:8080 — nginx serves the built client
and reverse-proxies /api + /uploads to the Node server. The SQLite database
and uploaded photos live in the server-data Docker volume.
To serve on a different host port, set MYKINDLEBOX_PORT (e.g. in a .env file
next to docker-compose.yml, alongside MYKINDLEBOX_PASSWORD):
MYKINDLEBOX_PORT=3000
Then re-run docker compose up -d — the app is served on that port instead of
8080. (Only the host side changes; inside the compose network nginx still
listens on 80.)
Authentication
The app uses user accounts — everyone shares the same herd; accounts are separate logins with their own theme and weight-display preference. On first launch the app shows a one-time create your account screen; add more people later under Settings → Users. Passwords are hashed (scrypt) and sessions last 30 days, surviving server restarts.
Upgrading from the password-only version? The old
MYKINDLEBOX_PASSWORDenv var is no longer used — remove it from your.env. On your next visit you'll see the one-time account-creation screen; your herd data is untouched.
Data & backups
The herd database (server/data/), uploaded photos, and .env files are
gitignored — they are never committed. In production they persist in the
server-data volume; back that volume up to preserve your data.