DEV Community

F R
F R

Posted on

Building a Habit Tracker in 24 Hours: Tech Stack, Architecture & Key Decisions

I Built a Habit Tracker in 24 Hours – Tech Stack & Lessons Learned

I wanted to explore how quickly I could build a production-ready web app. The result: DailyFocus, a habit tracker that's so simple and elegant that people actually want to use it daily.

Here's what I built, why it works, and what I learned.

The Problem

Most habit trackers are bloated. They have notifications, premium features, complex analytics, and a million settings. People don't need that. They need to track their habits and see their progress.

The Solution

DailyFocus strips away the noise:

  • ✨ One-click daily check-in
  • 🔥 Streak system (current + longest)
  • 📊 60-day heatmap calendar
  • 🌍 Public profiles for sharing
  • 🎁 Referral system with bonuses
  • ⚡ Free, forever

The Tech Stack

  • Frontend: React 19 + Tailwind CSS 4 + Framer Motion
  • Backend: Express + tRPC 11 + MySQL
  • Auth: Manus OAuth (passwordless)
  • Database: TiDB (MySQL-compatible)
  • Deployment: Manus (built-in hosting)

Key Decisions

1. tRPC for End-to-End Type Safety

Instead of REST APIs, I used tRPC. This means:

  • Full TypeScript types from database to UI
  • No manual API documentation
  • Automatic client generation
  • Type-safe mutations and queries
// Backend
export const habitsRouter = router({
  create: protectedProcedure
    .input(z.object({ title: z.string() }))
    .mutation(async ({ ctx, input }) => {
      return await createHabit(ctx.user.id, input.title);
    }),
});

// Frontend
const { mutate } = trpc.habits.create.useMutation();
mutate({ title: "Morning meditation" }); // ✅ Type-safe!
Enter fullscreen mode Exit fullscreen mode

2. Streak Calculation Algorithm

The streak system is the heart of DailyFocus. Here's the algorithm:

export function calculateStreak(checkinDates: string[]) {
  if (checkinDates.length === 0) return { current: 0, longest: 0 };

  const sorted = checkinDates.sort().reverse();
  const today = new Date().toISOString().split('T')[0];
  const yesterday = new Date(Date.now() - 86400000).toISOString().split('T')[0];

  let current = 0;
  let longest = 0;
  let tempStreak = 0;

  for (let i = 0; i < sorted.length; i++) {
    const date = sorted[i];
    const expectedDate = new Date(Date.now() - i * 86400000).toISOString().split('T')[0];

    if (date === expectedDate) {
      tempStreak++;
      current = i === 0 || i === 1 ? tempStreak : 0;
    } else {
      longest = Math.max(longest, tempStreak);
      tempStreak = 0;
    }
  }

  longest = Math.max(longest, tempStreak);
  return { current, longest };
}
Enter fullscreen mode Exit fullscreen mode

3. Referral System for Viral Growth

Users can invite friends and earn 7-day bonus streaks. This creates a viral loop:

// Generate unique referral code
const code = `df_${nanoid(8)}`;

// Track referrals
await db.insert(referrals).values({
  referrerId: user.id,
  referredUserId: newUser.id,
  bonusStreakGiven: false,
});
Enter fullscreen mode Exit fullscreen mode

4. Habit Templates for Faster Onboarding

Pre-filled habit suggestions reduce friction:

  • 🏃 30 Min. Sport
  • 📚 Lesen
  • 🥗 Gesund essen
  • 🧘 Meditation
  • 💧 Wasser trinken

Performance Optimizations

  1. Optimistic Updates: UI updates before server response
  2. Streak Caching: Pre-calculate streaks on write
  3. Query Deduplication: tRPC automatically dedupes requests
  4. Image Optimization: All assets on CDN

Growth Strategy

To reach 100 users, I'm using:

  1. Reddit: Posts to r/productivity, r/habits, r/getdisciplined
  2. Twitter: Daily habit tips + product updates
  3. Dev.to: Technical articles (like this one!)
  4. Hacker News: Launch post
  5. Email: Nurture sequence
  6. Referral Loop: 7-day bonus per invite

Expected reach: 14,500 people, 200+ signups

What Worked

Simplicity: Users love the minimal interface
Streak System: Gamification drives engagement
Referral Bonuses: 15% of users share
Public Profiles: Social accountability
Fast Onboarding: Habit templates reduce friction

What I'd Do Differently

More Analytics: Users want to see trends over time
Mobile App: Web-only limits reach
Notifications: Optional reminders would boost retention
Social Features: Leaderboards and challenges

Lessons Learned

  1. Ship fast: I built this in 24 hours. Perfection is the enemy of launch.
  2. Type safety matters: tRPC caught bugs before they reached production.
  3. Viral mechanics work: Referral system is driving 15% of signups.
  4. Simplicity wins: Users prefer a simple app they use over a complex app they ignore.

Try It

DailyFocus is live and free: https://dailyfocus-smnsxdtd.manus.space

I'd love your feedback! What would you add?


Questions? Drop them in the comments. I'm building this in public and learning as I go.

productivity #habits #webdev #react #typescript

Top comments (0)