DEV Community

Cover image for I Built a 'Perfect' Niche App with Zero Backend. Learned More About Product Prioritization Than Any PM Book
Yash
Yash Subscriber

Posted on

I Built a 'Perfect' Niche App with Zero Backend. Learned More About Product Prioritization Than Any PM Book


I watched students spend six hours on topics worth 0.5% of their final score, and founders spend six weeks on features used by 0.5% of users. Same problem, different domain. So I built Tracker for GATE Rankers (ECE) — a weighted progress tracker that turns study time into intentional effort.

Core Idea

Bundle the syllabus in a single syllabus.json, persist progress in localStorage, and calculate a client-side weighted score. Completing a high-weight topic instantly feels more meaningful.

Why It Works

  • Zero signup friction & offline-first
  • Privacy-first (data stays local)
  • Instant performance (no backend)
  • Weighted progress = smarter motivation

Single Code Block

const saveProgress = (topicId, completed) => {
  const key = 'gateProgress';
  const progress = JSON.parse(localStorage.getItem(key) || '{}');
  progress[topicId] = { completed: !!completed, timestamp: Date.now() };
  localStorage.setItem(key, JSON.stringify(progress));
};

const calculateWeightedScore = (subjects, userProgress) => {
  let total = 0, achieved = 0;
  subjects.forEach(s => s.chapters.forEach(c => c.topics.forEach(t => {
    total += t.weightage;
    if (userProgress[t.id]?.completed) achieved += t.weightage;
  })));
  return total ? (achieved / total) * 100 : 0;
};
Enter fullscreen mode Exit fullscreen mode

Key Lessons

  1. Show weighted value for every task.
  2. Visual progress > raw counts.
  3. Remove signup friction.
  4. Privacy builds trust.
  5. Beautiful UX is a retention moat.

Tech Stack

React + TypeScript | Tailwind CSS | localStorage | Static JSON | Deployed on Vercel

Building this taught me more about prioritization than any PM book. Weighted effort beats equal effort.

webdev #javascript #react #product #buildinpublic #showdev

Top comments (0)