Case study · Chrome extension · Sep 2026 – Oct 2026

Flozable Focus

A Manifest V3 extension with 70 users on the Chrome Web Store. It gathers deadlines from Canvas, Blackboard, and Gradescope into one dashboard and blocks distracting sites during a Flozable focus session.

The Flozable Focus settings page, with a choice between blocking distractions and allowing only study sites, a list of blocked sites, and a study timer.
Users
70 on the Chrome Web Store (Nov 2026)
Tests
216 passing
Version
3.4.6, Manifest V3
Site access
Requested per site at runtime

Overview

Students’ deadlines are scattered across school systems. Flozable Focus is a Manifest V3 Chrome extension that gathers assignments from Canvas, Blackboard, and Gradescope into one dashboard, sends deadline reminders, and can block distracting sites while a Flozable study timer runs. It works without a Flozable account, and syncing is optional.

My role

I built it alone: about 6,600 lines of first-party JavaScript, TypeScript, HTML, and CSS, with the matching connection code on the Flozable website.

How it works

From a school site to a reminder
  1. School siteCanvas, Blackboard, or Gradescope, using the student’s own session
  2. Session readerInjected only with permission; checks account and origin
  3. Local storeCached tasks and an account-scoped reminder ledger
  4. DashboardReact sidebar, reminders at 48 h, 24 h, 1 h, and 15 min
  5. Optional syncMetadata only, after a preview

Engineering decisions

Staying correct when Chrome kills the service worker

Problem
Manifest V3 service workers can stop at any time and lose everything in memory, but a focus session and its blocked tabs have to keep working.
Approach
State lives in extension storage, and chrome.alarms drives periodic work instead of in-memory timers. Tests recreate the worker to check that focus sessions survive, that signed-out polling stays paused, and that an explicit opt-out still holds.
Trade-off
Every handler has to reload its state first, which adds code and storage reads. A browser restart deliberately begins from a safe state rather than resuming protection.

Importing coursework without touching anyone else’s data

Problem
The extension reads school systems through a logged-in session, so a shared computer or a switched account must never mix students’ data.
Approach
It needs no API tokens. Readers run only on sites the student has allowed. Canvas pagination links are rejected if they change origin or endpoint, or repeat. If the account changes mid-import, or between preview and import, the write is refused.
Trade-off
Failing closed means an import sometimes stops and asks the student to retry. Imports are also bounded, so unusually large course lists can be cut short.

Blocking sites without breaking pages

Problem
Redirecting a blocked tab loses the student’s place, and a dropped connection shouldn’t leave tabs blocked forever.
Approach
Blocking uses an overlay that keeps the exact URL. Overlays hold short leases, and they release when the timer stops, the connection fails past a brief grace period, or the student revokes permission.
Trade-off
An overlay is easier to bypass than a network-level block. This is a focus aid rather than parental control, so I chose the approach that can’t lose someone’s work.

Avoiding needless background requests

Problem
A timer check in every tab could multiply requests to the website and waste battery.
Approach
The extension prefers one responsive Flozable tab per origin, polls every 30 seconds while a session runs and every 60 seconds when idle, and pauses polling until the student signs in again after a signed-out response. Transient failures back off.
Trade-off
Status can lag by up to a polling interval. Counter-based tests check request counts, but I don’t have production CPU measurements.

Testing

All 216 tests pass: 193 controller, parser, and bridge tests on node:test, and 23 React interaction tests. Fixtures cover multiple-account cases, foreign pagination links, and worker restarts. The tests run in jsdom and against fixtures, so real school sites still need manual checks.

What I’d do next

  • Track activation and retention, since the store’s user count doesn’t show how many students stay.
  • Run the suite in CI on every push.