ApprenticeLog: Our Build Story
🌟 What Inspired Us
Like many hobbyists, we dutifully log practice time—yet traditional spreadsheets never felt motivating. Reading about Anders Ericsson’s “10 000-hour mastery” rule triggered an idea:
What if the act of logging practice felt as rewarding as the practice itself?
We imagined a tiny, privacy-first timer that throws confetti when you hit milestones, works anywhere (even on a long flight), and never nags you to create an account. That spark became ApprenticeLog.
🛠️ How We Built It
Offline-first mindset We started with a blank HTML file and a service-worker shell, treating network access as an enhancement, not a requirement. IndexedDB (wrapped in a tiny helper) stores every skill and session locally.
Component-driven UI We sketched wireframes in Figma, then translated them into lightweight web-components. A floating action button (FAB) controls the stopwatch modal; a radial gauge and mini-donuts visualize progress in real time.
Micro-interactions for delight Pressing any button triggers a 100 ms scale-down; milestone crossings fire an SVG-based Lottie confetti burst that respects the user’s
prefers-reduced-motionsetting.Slim by design With a strict 250 kB gzip budget, every dependency had to earn its place. We wrote plain CSS variables for theming, used system fonts, and tree-shook everything else.
📚 What We Learned
- Motivation is UI-driven. A live radial gauge outperformed raw numbers in user tests; people feel progress.
- Privacy is a feature, not a toggle. “No sign-up required” became one of the most-cited reasons testers kept using the app.
- Animations amplify—if they’re fast. Even 50 ms of jank breaks immersion. We throttled every effect to guarantee 60 fps on mid-range phones.
⚔️ Challenges We Faced
| Hurdle | How we tackled it |
|---|---|
| Large data sets (5 000 + sessions) | Implemented virtualized lists and debounced chart updates, keeping dashboard render ≤ 300 ms. |
| Encrypting and indexing quickly | Ran AES-256 in a Web Worker so the UI stays fluid; derived keys once per session, then cached. |
| Confetti on low-power devices | Fell back to a static celebration emoji when prefers-reduced-motion or low-end hardware was detected. |
| Keeping bundle size tiny | Wrote our own 1.2 kB radial-gauge component instead of importing a charting library. |
🚀 Looking Ahead
- Cloud-optional sync—but only if we can preserve zero-sign-up privacy.
- Native wrappers for deeper OS integrations (focus mode, widgets).
- Community templates for popular skills (e.g., “Jazz Piano Practice Plan”).
ApprenticeLog began as a simple stopwatch idea; it’s grown into a joyful companion for anyone chasing mastery—one confetti blast at a time. Thanks for following our journey!
Built With
- canvas-confetti
- date-fns
- lucide-react
- react
- tailwind-css
- typescript
- vite

Log in or sign up for Devpost to join the conversation.