rulocode
Work

To-Pra: The Productivity App I Built Because Nothing Else Worked

To-Pra: The Productivity App I Built Because Nothing Else Worked
February 8, 2025
I'm a productivity app hoarder. Todoist, Notion, TickTick, Things 3—I've tried them all. But none of them solved my actual problem: I'd make beautiful task lists, then ignore them. The issue wasn't the apps. It was me. I needed:
  • Something that made completing tasks feel rewarding
  • A built-in focus mode so I'd actually do the work
  • Real data showing where my time went
Nothing combined all three. So I built it. To-Pra is a productivity app that treats getting things done like a game—because our brains respond to rewards, not guilt. 🎮 Gamified Task Completion Every completed task earns points. Streaks multiply rewards. You unlock achievements (Novice → Expert → Master). It sounds silly until you realize you've completed 47 tasks this week just to keep your streak alive. ⏱️ Built-in Focus Mode No more switching between a task app and a timer app. To-Pra has Pomodoro built in—25, 50, or 90-minute sessions. When the timer's running, you're accountable. 📊 Honest Analytics Most apps show you tasks completed. To-Pra shows you time invested. The difference matters. Completing 20 tiny tasks feels productive until you realize you spent 4 hours on busywork. I needed real-time sync across devices and fast iteration. Supabase gave me auth, database, and real-time subscriptions in one package. Next.js App Router let me ship features quickly while keeping the bundle small. The reward system needed to feel fair but challenging:
// Streak multiplier calculation
const getStreakMultiplier = (streak: number): number => {
  if (streak >= 30) return 3.0;  // Monthly warrior
  if (streak >= 7) return 2.0;   // Weekly consistent
  if (streak >= 3) return 1.5;   // Getting momentum
  return 1.0;                     // Starting fresh
};

// Points scale with task priority
const calculatePoints = (task: Task, streak: number): number => {
  const basePoints = task.priority * 10;
  const multiplier = getStreakMultiplier(streak);
  const focusBonus = task.completedInFocusMode ? 1.5 : 1;
  
  return Math.round(basePoints * multiplier * focusBonus);
};
Tasks completed during focus sessions earn 50% bonus points. This nudges users toward deep work without forcing it. The hardest part was handling offline-first with eventual consistency. Users expect tasks to save immediately, even on spotty connections. Solution: Optimistic updates with a sync queue. Changes apply instantly to the UI, then reconcile with Supabase when connection returns. Conflicts resolve by "last write wins" with timestamp comparison.
MetricResult
Active users500+ monthly
Tasks completed12,000+ tracked
Avg. focus sessions/user4.2 per day
User retention (30-day)42%
User satisfaction4.7★ average
But the number I care about most: I actually use it. Every day. That's the real validation. The best products come from solving your own problems. You understand the pain deeply, and you're the first user to notice when something's off. Points and streaks work—until they become stressful. We added "streak freeze" after users reported anxiety about breaking chains. Features should motivate, not guilt. Early versions had way more features (habit tracking, journaling, team boards). We cut 60% of them. The focused product retained users better than the bloated one.
  • Competitive weekly rankings (opt-in) for those who thrive on competition
  • Team workspaces for small groups
  • AI task suggestions based on productivity patterns

Built with: Next.js 14, TypeScript, Tailwind CSS, Supabase, Vercel
Want to try it? to-pra.vercel.app — it's free. Need something similar built for your team? Let's talk →

Tell me what's stealing hours from your team

A free 30-minute call, no sales pitch: we review your operation and I tell you whether I can help — and how.
Book a call