Case Study  ·  Solo Project

A reading tracker
built for fanfic readers

FicTracker is a fully local-first web app that lets AO3 readers track their reading, discover new fics, and visualise their reading life — no account, no server, no cost.

Type
Solo project
Frontend
React 19 + Vite
Backend
None (local-first)
Extension
Chrome + Firefox (MV3)
Deployed on
Vercel
Server cost
$0 / month

AO3 bookmarks are a graveyard

AO3 (Archive of Our Own) is one of the largest fanfiction platforms in the world, with millions of active readers. Its bookmarking system is essentially a flat list — no reading status, no chapter progress, no notes, no analytics, no way to surface what you actually want to read next.

Readers were tracking progress in spreadsheets, Notion databases, and handwritten notes. Smart community members built browser extensions with limited scope. There was no cohesive, purpose-built tool.

I built FicTracker to solve that — a full reading tracker tailored to how fanfic readers actually read: long multi-chapter works, frequent WIPs, a deep culture around curation and community.


A full reading workflow in the browser

Everything lives in localStorage — no login, no server roundtrips, instant interactions. The app is usable in under 10 seconds with zero friction.

📚

Library

Import AO3 bookmarks in one click, or add any fic by URL. Track status, chapter progress, star ratings, and personal notes. Shuffled on every visit so nothing stays buried.

🔖

Continue Reading

Deep links to the exact last-read chapter on AO3. Never hunt for your place again.

📐

Bookshelves

Manual shelves for curation, smart shelves that restore a saved filter set with one click. Unlimited for all users.

🔔

WIP tracking

Checks incomplete fics for new chapters and shows per-work update banners in the library. No emails, no noise.

📊

Stats & Analytics

Top fandoms, word count, reading pace over time, interactive Recharts area timelines and bar charts. Shareable Reading Wrapped cards.

🎯

Fic Finder & Queue

Taste-based queue scores your to-read list by overlap with highly-rated fandoms and ships. Fic Finder generates targeted AO3 search URLs from filter presets.

📥

Import options

AO3 bookmark sync, EPUB drop, Quick Add bookmarklet for mobile Safari, JSON backup restore.

🧩

Browser Extension

MV3 extension for Chrome and Firefox. Floating panel on every AO3 work page — auto-detects chapter, +/– controls, silent sync. Also ships for Firefox for Android.


Deliberately lean

The stack was chosen to eliminate operational overhead entirely. No database to provision, no auth to maintain, no API costs, no billing infrastructure. Just a static build deployed to Vercel's CDN.

React 19
Vite
React Router
Recharts
localStorage
corsproxy.io
Chrome MV3
Firefox MV3
Vercel
No backend
No auth
No database

Local-first, zero infrastructure

All state lives in localStorage, managed through custom hooks that provide a typed API to the rest of the app. The browser itself is the database — reads are synchronous and instant, writes are atomic, and there's nothing to go down.

AO3 scraping runs through a public CORS proxy at import time only. The extension communicates with the web app via a shared localStorage key — no messaging API, no background server.

Data layer
  • useLocalLibrary hook (core engine)
  • useLocalShelves hook
  • storage/local.js — I/O abstraction
  • JSON export / import
Import pipeline
  • AO3 bookmark page scraper
  • EPUB metadata parser
  • Quick Add bookmarklet (mobile)
  • JSON backup restore
Extension
  • MV3 service worker
  • Content script on AO3 work pages
  • Floating panel UI (full / mini / hidden)
  • Shared localStorage bridge
Deployment
  • Vercel — auto-deploy from GitHub
  • Custom domain: fictracker.app
  • Chrome Web Store
  • Firefox Add-ons (AMO)

Problems worth solving

Challenge

AO3 doesn't provide a public API. Importing a reader's bookmark library requires scraping paginated HTML across potentially dozens of pages.

Solution

Built a CORS-proxied scraper that parses AO3 bookmark HTML client-side, extracting work ID, title, author, fandom, tags, and chapter count. Runs entirely in the browser with progress tracking.

Challenge

Readers want to resume exactly where they left off — AO3 chapter URLs follow a specific pattern but chapter numbers aren't always sequential or predictable.

Solution

Designed a chapter tracking model that stores the AO3 chapter ID (not just the number), enabling deep links that navigate to the exact chapter even after story restructuring.

Challenge

The app started as a Supabase + Stripe SaaS. After Reddit community feedback made clear that paywalling features is culturally incompatible with the fanfic ecosystem, the entire backend had to be rearchitected away.

Solution

Migrated to a fully local-first model. Replaced all Supabase calls with localStorage hooks behind a clean abstraction layer — meaning the switch was a data-layer swap, not a UI rewrite.

Challenge

The browser extension needs to sync chapter progress with the web app in real time, without a shared server or persistent connection.

Solution

Both the extension and web app read and write the same localStorage keys. The extension content script writes directly; the web app picks up changes on next render. Simple, reliable, offline-capable.

Challenge

Mobile Safari doesn't support browser extensions — a significant fraction of the target audience reads on iPad.

Solution

Built a Quick Add bookmarklet that works on mobile Safari — grabs the current AO3 work URL and fires a deep link into the web app to add it to the library without any extension required.


Built iteratively, shaped by users

Phase 1
Supabase + Stripe SaaS

Launched with full backend: Supabase Postgres, Row Level Security, Stripe subscription tiers, server-side scraping via Edge Functions, multi-user auth. Fully functional but operationally complex.

Phase 2
Community feedback changes the model

Posted to r/FanFiction and r/AO3. Strong signal: fanfic readers are culturally opposed to paywalled tools in a community built on free, gift-economy content. Decision made to go fully free and remove the backend.

Phase 3
Local-first rearchitecture

Replaced all Supabase calls with localStorage hooks behind a clean abstraction. Removed auth, Stripe, and server-side scraping. Moved AO3 scraping client-side. Dropped backend cost to zero.

Phase 4
Feature depth

Added Reading Wrapped, Analytics, Fic Finder, taste-based queue, EPUB import, series dashboard, WIP tracking, and the full browser extension with chapter auto-detection and deep linking.


Scale and scope

0
Server cost per month
2
Browser extension platforms (Chrome + Firefox)
5
Import methods (AO3 sync, EPUB, bookmarklet, URL, JSON)
14+
React components across 8 distinct views
Fics, shelves, and data — no limits, no tiers