Never forget what you learn.
Track everything you study — coding problems, math exercises, design tutorials, language lessons, and more. FSRS — the modern spaced-repetition algorithm behind Anki — tells you exactly when to revise, so knowledge sticks for good.
You learn something. You forget it in a week. This fixes that.
Revise is a browser extension + web dashboard that:
- Auto-detects the platform you're using (LeetCode, Codeforces, HackerRank, Khan Academy, etc.)
- Lets you add custom platforms — track any website you learn from
- Times your study with a built-in timer — no manual entry
- Schedules revisions using FSRS, the modern spaced repetition algorithm behind Anki
- Shows a dashboard with stats, charts, activity feed, and a filterable table of everything you've tracked
No passwords. Sign in with a magic link. Your data is yours.
10+ platforms supported out of the box, plus add your own.
Full analytics: items tracked, difficulty breakdown, platform distribution, revision schedule, and daily activity — all in one view.
No passwords to remember. Enter your email, click the link, you're in.
The extension auto-detects the URL and title. Navigate to any supported platform and it picks it up instantly.
Start a timer when you begin studying. When you're done, rate your recall (1-5 stars), say how you solved it (yourself, with a hint, or from the solution), add notes, and save. FSRS handles the rest.
Browser Extension (Chrome / Safari)
|
| REST API
v
FastAPI Server --> Supabase (Postgres + Auth)
|
v
Web Dashboard (revise.mrinal.dev/dashboard)
- Study something on any supported platform (or add your own)
- Click the extension — it auto-detects the URL and title
- Start the timer, study, stop when done
- Rate your recall (1-5 stars) and save
- FSRS schedules your next review — things you found hard come back sooner, easy ones later. Peeking at the solution brings an item back quickly, no matter the rating
- Check the dashboard for what's due today, your stats, and your full history
| Platform | Auto-detected |
|---|---|
| LeetCode | Yes |
| Codeforces | Yes |
| HackerRank | Yes |
| CodeChef | Yes |
| GeeksForGeeks | Yes |
| InterviewBit | Yes |
| AtCoder | Yes |
| NeetCode | Yes |
| AlgoMonster | Yes |
| DesignGurus.io | Yes |
| Custom Platforms | User-defined |
Any other URL works too — it's tagged as "other". You can add custom platforms from the dashboard settings to auto-detect any website.
- FSRS Spaced Repetition — the same algorithm behind modern Anki. Rate your recall 1-5 stars, and it models your memory to schedule the next review at the optimal time, tunable via a per-user target retention (70–99%).
- Honest Check-ins — record how you solved each item: by yourself, with a hint, or from the solution. Assisted recalls earn shorter intervals so the schedule reflects what you actually know.
- Built-in Timer — start when you begin studying, pause/resume, stop when done. Time is recorded automatically.
- Custom Platforms — add any website from the dashboard settings. Define a name and URL pattern, and it auto-detects just like the built-in platforms.
- Analytics Dashboard — items tracked, difficulty breakdown, platform distribution, revision schedule, daily activity feed.
- Magic Link Auth — no passwords. Enter your email, click the link in your inbox, done. Powered by Supabase Auth.
- 10+ Platforms — auto-detects LeetCode, Codeforces, HackerRank, CodeChef, GeeksForGeeks, InterviewBit, AtCoder, NeetCode, AlgoMonster, DesignGurus.
- Browser Extension — Chrome and Safari. Captures the current URL with one click.
- Due for Revision — the extension and dashboard both show which items are due today, so you always know what to revise.
- CSV Export — download your entire history as a CSV.
- Per-user Data Isolation — Row Level Security on Supabase. Each user only sees their own data.
- Go to revise.mrinal.dev
- Click Get Started Free
- Enter your email and click Send Magic Link
- Check your inbox, click the link — you're logged in
- Install the browser extension (see below)
- Start learning!
- Download
extension.zipfrom the latest release - Unzip the downloaded file
- Open
chrome://extensionsin Chrome - Enable Developer mode (top right toggle)
- Click Load unpacked and select the unzipped folder
- Pin the extension from the puzzle icon in the toolbar
Safari: Available on request. It requires a macOS/iOS native app wrapper built with Xcode. Reach out at dmrinal626@gmail.com and I'll send you the build.
Create a Supabase project and run this in the SQL Editor:
create table public.questions (
id bigint generated always as identity primary key,
user_id uuid not null references auth.users(id) on delete cascade,
url text not null,
title text,
platform text,
difficulty text,
self_rating integer check (self_rating between 1 and 5),
time_taken integer,
notes text,
solved_at timestamptz default now(),
easiness_factor double precision default 2.5, -- legacy SM-2 (kept for rollback)
interval integer default 1,
repetitions integer default 0, -- legacy SM-2 (kept for rollback)
next_review date,
last_reviewed timestamptz,
attempts integer default 1,
-- study metadata
pattern text,
question_type text default 'dsa',
approach text,
mistakes text,
time_complexity text,
space_complexity text,
-- FSRS memory state + solution source (migration 009)
stability double precision,
fsrs_difficulty double precision,
fsrs_state smallint,
solution_source text check (solution_source in ('self', 'hint', 'solution'))
);
alter table public.questions enable row level security;
create policy "Users see own questions" on public.questions for select using (auth.uid() = user_id);
create policy "Users insert own questions" on public.questions for insert with check (auth.uid() = user_id);
create policy "Users update own questions" on public.questions for update using (auth.uid() = user_id);
create policy "Users delete own questions" on public.questions for delete using (auth.uid() = user_id);
create index idx_questions_user_url on public.questions(user_id, url);
create index idx_questions_next_review on public.questions(user_id, next_review);
-- Custom platforms (for user-defined URL patterns)
create table public.user_platforms (
id bigint generated always as identity primary key,
user_id uuid not null references auth.users(id) on delete cascade,
name text not null,
url_pattern text not null,
created_at timestamptz default now()
);
alter table public.user_platforms enable row level security;
create policy "Users see own platforms" on public.user_platforms for select using (auth.uid() = user_id);
create policy "Users insert own platforms" on public.user_platforms for insert with check (auth.uid() = user_id);
create policy "Users update own platforms" on public.user_platforms for update using (auth.uid() = user_id);
create policy "Users delete own platforms" on public.user_platforms for delete using (auth.uid() = user_id);
create unique index idx_user_platforms_unique on public.user_platforms(user_id, name);
-- Per-question audit/event log (history of every solve / review / re-attempt).
-- Also available as server/migrations/001_question_events.sql
create table public.question_events (
id bigint generated always as identity primary key,
user_id uuid not null references auth.users(id) on delete cascade,
question_id bigint not null references public.questions(id) on delete cascade,
event_type text not null, -- 'created' | 'reviewed' | 'attempted'
self_rating integer,
time_taken integer,
interval integer, -- schedule snapshot AFTER this event
repetitions integer, -- legacy SM-2 (frozen post-FSRS)
easiness_factor double precision, -- legacy SM-2 (frozen post-FSRS)
next_review date,
reconstructed boolean default false, -- true for backfilled rows (approximate)
created_at timestamptz default now(),
-- FSRS snapshot + solution source (migration 009)
solution_source text check (solution_source in ('self', 'hint', 'solution')),
stability double precision,
fsrs_difficulty double precision,
fsrs_state smallint
);
alter table public.question_events enable row level security;
create policy "Users see own events" on public.question_events for select using (auth.uid() = user_id);
create policy "Users insert own events" on public.question_events for insert with check (auth.uid() = user_id);
create policy "Users update own events" on public.question_events for update using (auth.uid() = user_id);
create policy "Users delete own events" on public.question_events for delete using (auth.uid() = user_id);
create index idx_qevents_question on public.question_events(user_id, question_id, created_at);
-- Per-user settings (e.g. how many revisions to surface as "due" at once)
create table public.user_settings (
user_id uuid primary key references auth.users(id) on delete cascade,
revision_queue_size integer not null default 20, -- 0 = unlimited
updated_at timestamptz default now(),
-- FSRS (migration 009)
desired_retention double precision not null default 0.9
check (desired_retention between 0.70 and 0.99),
fsrs_params jsonb -- per-user optimized parameters (null = defaults)
);
alter table public.user_settings enable row level security;
create policy "Users see own settings" on public.user_settings for select using (auth.uid() = user_id);
create policy "Users insert own settings" on public.user_settings for insert with check (auth.uid() = user_id);
create policy "Users update own settings" on public.user_settings for update using (auth.uid() = user_id);
create policy "Users delete own settings" on public.user_settings for delete using (auth.uid() = user_id);Existing deployments: apply the incremental migrations in
server/migrations/(run each.sqlin the Supabase SQL Editor).
Configure Auth redirect URLs in Supabase Dashboard:
- Site URL:
https://your-domain.com/dashboard - Redirect URL:
https://your-domain.com/api/auth/callback
Create a .env file:
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
SUPABASE_JWT_SECRET=your-jwt-secret
SERVER_URL=https://your-domain.comdocker compose up -dThe server starts at http://localhost:8765. The landing page is at / and the dashboard at /dashboard.
Update the SERVER_URL in the extension's config to point to your self-hosted instance.
The hosted instance is deployed from the Deploy workflow in the Actions tab (Run workflow → main). It pulls the latest code on the server, rebuilds the container, and verifies the site is up. Database migrations in server/migrations/ are applied manually against Supabase.
All endpoints except auth require an Authorization: Bearer <token> header.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/magic-link |
Send magic link email |
GET |
/api/auth/callback |
Handle auth callback (PKCE + implicit flow) |
POST |
/api/auth/refresh |
Refresh access token |
POST |
/api/questions |
Save a new item |
GET |
/api/questions |
List all items |
PUT |
/api/questions/{id} |
Edit an item |
DELETE |
/api/questions/{id} |
Delete an item |
POST |
/api/questions/{id}/review |
Submit a review rating + solution source (triggers FSRS) |
GET |
/api/revisions/today |
Get items due for revision today |
GET |
/api/activity/today |
Today's new + revised items |
GET |
/api/stats |
Summary statistics |
GET |
/api/platforms |
List built-in + custom platforms |
POST |
/api/platforms |
Add a custom platform |
DELETE |
/api/platforms/{id} |
Delete a custom platform |
The revision schedule uses FSRS (Free Spaced Repetition Scheduler, the algorithm modern Anki adopted), via py-fsrs. It models each item's memory stability and difficulty from your review history and schedules the next review just before you'd forget.
Your 1-5 star rating combines with how you solved it:
| Rating | Solved myself | Used a hint | Saw the solution |
|---|---|---|---|
| 1-2 | Back soon (lapse) | Back soon (lapse) | Back soon (lapse) |
| 3 | Short interval | Short interval | Back soon (lapse) |
| 4 | Normal interval | Capped — short | Back soon (lapse) |
| 5 | Longest interval | Capped — short | Back soon (lapse) |
Reading the answer always brings the item back quickly — solving it yourself is the only way to earn long intervals. A per-user target retention setting (default 90%) controls the trade-off between review frequency and forgetting.
Migrating an existing deployment from SM-2: apply server/migrations/009_fsrs.sql, deploy, then run python migrate_to_fsrs.py once (idempotent) to replay each question's review history through FSRS. Legacy rows also seed themselves lazily on their first post-migration review, so the backfill is a nicety, not a requirement.
The repo includes 15 in-depth study guides covering the classic DSA patterns — arrays/matrices, two pointers, sliding window, stacks, linked lists, trees, graphs, backtracking, dynamic programming, greedy, binary search, heaps, and more — each with worked problem analyses and step-by-step SVG diagrams. They're also served on the hosted instance at revise.mrinal.dev/research.
- Backend: Python, FastAPI
- Database: Supabase (Postgres + Row Level Security)
- Auth: Supabase Auth (magic link / passwordless)
- Frontend: Vanilla HTML/CSS/JS (no frameworks)
- Extension: Manifest V3 (Chrome & Safari)
- Deployment: Docker Compose
Contributions welcome! See CONTRIBUTING.md for dev setup, testing, and PR guidelines. Good entry points: platform support requests and issues labeled good first issue.
MIT







