A personal attention and life-balance companion.
The Shelf helps you plan attention, log what actually happened, and review balance over time. It's a place to start and end the day—taking things off the shelf when ready, and putting them back when it's time to stop.
The goal is visibility, pattern recognition, and intentional adjustment—not productivity, streaks, or self-optimization.
Live demo: demo-the-shelf.vercel.app (public instance with sample data) Personal app: the-shelf-amk.vercel.app
To run a demo locally with sample data:
# Start the stack
docker compose -f docker-compose.dev.yml up -d
# Seed demo data
cd backend/api && npm run demo-seedVisit http://localhost:5173 to explore.
Web App:
- 6 views: Shelf, Today, Progress, Review, Attention, Settings
- Full habit/practice/behavior management with drag-drop
- Entry logging with warm-up/cool-down flows
- Balance and Patterns analysis with iOS Screen Time–style charts
- Rich text reflections with triggers
- Import/export with preview and duplicate detection
- Dark mode (auto 6PM-6AM or manual)
Mobile App (React Native):
- All 6 views optimized for mobile
- Offline queue - mutations sync automatically when connectivity restored
- Network monitoring - visual status banner shows offline/syncing state
- Error handling - user-friendly messages with toast notifications
- Haptic feedback on interactions
- Swipeable entry cards for quick actions
- E2E testing with Playwright
- Practice-level drill down in Progress view
- Calendar heatmap visualization
- Mobile app conflict resolution for concurrent offline edits
See BACKLOG.md for details.
| Layer | Technology |
|---|---|
| Backend | Node.js + Express.js |
| Database | PostgreSQL (Neon) |
| Web Frontend | React 19 + Vite |
| Mobile Frontend | React Native + Expo |
| UI Components (Web) | shadcn/ui + Tailwind CSS |
| UI Components (Mobile) | Custom + Lucide React Native |
| State Management (Mobile) | Zustand |
| Offline Queue (Mobile) | AsyncStorage + NetInfo |
| Charts | Recharts (web), Victory Native (mobile) |
| Rich Text | Tiptap |
| Drag & Drop | @hello-pangea/dnd (web), react-native-draggable-flatlist (mobile) |
| Containerization | Docker Compose |
| Hosting | Google Cloud Run + Vercel |
Run the full stack locally:
docker compose -f docker-compose.dev.yml up -dRebuild after dependency/config changes:
docker compose -f docker-compose.dev.yml up -d --buildStop:
docker compose -f docker-compose.dev.yml downReset database (destructive):
docker compose -f docker-compose.dev.yml down -vEndpoints:
- Web UI:
http://localhost:5173 - API:
http://localhost:3001 - PostgreSQL:
localhost:5432
Web (frontend/web/.env.example):
VITE_API_BASE_URL=http://localhost:3001
API:
DATABASE_URL=postgresql://user:pass@host:5432/dbname
Mobile:
The mobile app auto-detects the API URL based on platform:
- Android emulator:
http://10.0.2.2:3001 - iOS simulator/real devices:
http://localhost:3001
To use a deployed API, update the default URL in frontend/shared/api/index.ts or call setApiBaseUrl() at runtime.
Prerequisites:
- Node.js 18+
- iOS: Xcode (Mac only)
- Android: Android Studio
Install and run:
cd frontend/mobile
npm install
npm startThen:
- Press
ifor iOS simulator - Press
afor Android emulator - Scan QR code with Expo Go app for physical device
Features:
- Offline queue automatically syncs mutations when connectivity restored
- Network status banner shows offline/syncing state
- All CRUD operations work offline with optimistic updates
Seed the database with sample habits, entries, and targets:
cd backend/api && npm run demo-seedThis loads:
- 7 habits with 49 practices and 91 actions
- 12 days of sample entries (24 entries total)
- 6 sample targets in various states
- Preparations, closures, and reflections
Raw demo data is available in data/logs/demo/ for manual import via Settings > Import/Export.
| Document | Purpose |
|---|---|
| TECH_SPEC.md | Technical specification, data model, import format |
| BACKLOG.md | All work items with priorities |
| PROGRESS.md | Session changelog |
| OPS.md | Operational procedures |
This is a personal project. If you're interested in contributing or have feedback, please open an issue.
Personal project. License to be determined if shared.