A collaborative time-lapse app where people record 5-second clips of their day, stitched into a single "one day on earth" montage.
Every day is a compilation. Users submit 5-second video clips capturing a moment from their day. Clips get stitched together into a seamless daily montage — "One Day on Earth, April 18 2026". Browse past days, contribute to today's, feel the world's rhythm.
- Next.js 15 + TypeScript + Tailwind CSS
- Framer Motion for animations
- better-sqlite3 for clip metadata
- FFmpeg for video processing (thumbnails, normalization, concatenation)
- File-based storage for clips and montages
npm install
npm run devOpen http://localhost:3000.
- Home — Today's compilation with auto-playing montage, big "Add Your Moment" button
- Upload — Simple drag-and-drop upload flow with preview, caption, and location tag
- Daily Montage — Grid of all clips for a day, play the full stitched video
- Browse — Calendar/archive to explore past days
- Clip Cards — Beautiful cards with thumbnail, location, time, caption
| Endpoint | Method | Description |
|---|---|---|
/api/upload |
POST | Upload a video clip (form data: video, caption, location, nickname) |
/api/clips/[date] |
GET | Get all clips for a date |
/api/montage/[date] |
GET | Get/generate montage for a date |
/api/montage/[date] |
POST | Regenerate montage for a date |
/api/days |
GET | List all dates with clips |
/api/stats |
GET | Global stats |
/api/serve/clip/[id] |
GET | Serve raw clip video |
/api/serve/montage/[date] |
GET | Serve montage video |
/api/serve/thumb/[id] |
GET | Serve clip thumbnail |
Apple minimalistic + fun. Dark cozy theme (#0a0a0b), coral/peach accent (#FF6B6B → #FF8A65), generous spacing, rounded corners, glass effects, smooth spring animations.
- Clips:
./clips/{date}/— uploaded video files + thumbnails - Montages:
./montages/{date}.mp4— FFmpeg-concatenated daily videos - Database:
./onday.db— SQLite with clips and montages tables
docker compose up -dThe Dockerfile installs ffmpeg, Python + numpy/scipy/soundfile for beat generation, and DejaVu fonts for text overlays. Data persists in named volumes.
npm ci
npm run build
npm start # or: pm2 start npm --name onday -- startRequirements:
- Node.js 20+
- FFmpeg 8+
- Python 3.10+ with numpy, scipy, soundfile (for beat generation)
- DejaVu fonts (for text overlays)
Set PYTHON_PATH if Python isn't at default location.
A Caddyfile is included for automatic HTTPS with Caddy:
caddy run --config Caddyfile| Variable | Default | Description |
|---|---|---|
PYTHON_PATH |
auto-detect | Python binary for beat generation |
DB_PATH |
./onday.db |
SQLite database path |
PORT |
3000 | Server port |
GET /api/health — returns status of ffmpeg, beat generation, and canvas dependencies.
- Beat-synced — clips snapped to 110 BPM beat grid, brightness pulses on each beat
- Transitions — xfade effects between clips (slide, circle, dissolve, fade-to-black)
- Branded intro/outro — "One Day on Earth" intro card, "oneday.earth" outro
- Caption overlays — location + nickname with fade in/out
- Dual format — 16:9 montage + 9:16 story version
- Short-form optimized — montages capped at 60 seconds
- Background music — generated beat track (I-V-vi-IV pop progression) or user-provided
music/file