Skip to content
| Marketplace
Sign in
Visual Studio Code>Education>LeetCode Practice: Spaced RepetitionNew to Visual Studio Code? Get it now.
LeetCode Practice: Spaced Repetition

LeetCode Practice: Spaced Repetition

sam56714

|
1 install
| (0) | Free
Solve LeetCode problems in VS Code, with a workflow built around spaced repetition.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

LeetCode Practice

English · 繁體中文

A VS Code extension for practising LeetCode, built around spaced repetition: problem folders lead with the problem number, so they pair with an archive and review workflow that decides what to redo and when.

Written from scratch — not a fork of any existing extension. Inspired by Ayanrocks/better-leetcode, but sharing none of its code.

What works today

Signing in

Click the status bar or the sidebar and LeetCode opens in your browser; once you authorise there, VS Code picks the session up on its own. Nothing to copy.

Credentials live in VS Code's secret storage, scoped to this extension, so they never reach a settings file. They are checked against LeetCode before being stored, so a bad or expired session fails immediately rather than at the first submission.

Because the handoff returns the session in a URL, a callback is accepted only while an authorisation started here is still open (five minutes), only when addressed to this extension, and only once. Otherwise any link could hand the extension somebody else's session.

Signing in with a cookie instead

Run LeetCode Practice: Sign In with Cookie from the command palette. It is the way in for anywhere the browser handoff cannot reach: a vscode:// scheme the OS has not registered, Remote SSH or a dev container where the callback has to cross a machine boundary, VS Code on the web, or LeetCode changing its authorisation page.

  1. Sign in to https://leetcode.com in your browser
  2. Open DevTools (F12) and go to the Network tab
  3. Reload the page, click any request to leetcode.com, and find Request Headers → Cookie
  4. Copy that whole line and paste it in

The line is long and holds far more than is needed; only these two are read, and they can be pasted on their own in either order:

LEETCODE_SESSION=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...; csrftoken=8kZQ2nR7...

Sessions expire after a few weeks, at which point Test and Submit start failing with "the session may have expired" and you sign in again.

The sidebar

  • Daily Challenge — today's problem, one row
  • Study Lists — your own lists, then LeetCode's official plans (Top Interview 150, LeetCode 75 and the rest) as plan, section, problem, with how many of each you have solved. Your lists have a listing query; the plans do not, so which ones to show is a setting.
  • Contests — upcoming ones with a countdown, then the last dozen that ran. A finished contest expands into its problems, each opening like any other, which is the practisable part; an upcoming one has no problems yet, so its row opens the website where the timer and scoreboard are.
  • Problems — the whole set, over 4,000 problems, searchable. The list is cached on disk and only refetched in the background once it is a week old. Unfiltered it renders the first 500 rows, because nobody scrolls four thousand and search is the way in. A numeric query matches the number by prefix, so typing 17 surfaces 17, 170 and 171 rather than being buried by the 1700s.

Icons: colour is difficulty, shape is progress

One glyph answers both "how hard" and "have I done this":

State Icon Colour
Untouched hollow circle green Easy / yellow Medium / red Hard
Attempted, not solved filled circle as above
Solved tick in a circle as above
Premium padlock as above

Colours come from VS Code's charts.green / yellow / red, so they follow the reader's theme instead of hardcoding hex values.

Opening a problem

A folder appears under storagePath, named <number>-<titleSlug>:

3028-ant-on-the-boundary/
├─ main.py           # LeetCode's template
├─ testcases.txt     # every example case
└─ .metadata.json    # both ids, language, lines per test case

The code opens in the editor and the statement opens beside it without taking focus, so the cursor lands where the typing happens.

  • Reopening a problem never overwrites work. An existing main.* or testcases.txt is left exactly as it was.
  • Python templates get the typing imports they actually reference. LeetCode serves def twoSum(self, nums: List[int]) with no import, and since Python evaluates annotations at definition time, that file raises NameError when run locally. Only mentioned names are imported: two-sum gets List, add-two-numbers gets Optional, reverse-integer gets nothing.
  • The statement panel loads no scripts, behind a content security policy that allows inline styles and remote images only.

Switching language

The button in the editor title bar lists the languages that problem offers, 19 of them for most. Picking one writes that language's template beside the existing file rather than replacing it, so a problem can hold main.py and main.rs at once — redoing a solved problem in another language is a practice technique, not an accident. Test and Submit use whichever file is open.

Testing and submitting

With a solution file open, Ctrl+; runs it against the cases in testcases.txt and Ctrl+Enter submits it; both also sit as buttons in the editor title bar. Results appear in the LeetCode Results panel at the bottom, alongside Terminal and Output: verdict, timing, each case next to its expected output, and compile or runtime errors when there are any. They sit there rather than in an editor tab because a result is something to glance at while the code stays on screen. A submission asks for confirmation first, since it is recorded against the account.

The language comes from the file's own extension, not the folder's metadata: a problem can hold main.py and main.rs at once, and the one being submitted is the one in front of you.

Cloudflare. The judge endpoints are behind bot mitigation that fingerprints the TLS handshake before reading a single header — measured on interpret_solution, submit and check, all three answer 403 with cf-mitigated: challenge from Node's own HTTP stack, browser headers or not. This extension therefore sends those three requests through impit, which performs the handshake as Chrome would; the same endpoints then answer from LeetCode itself. impit is a native module, so a VSIX is platform specific.

Settings

Setting What it does
leetcodePractice.storagePath Where problem folders are created. Empty means solutions/ under the first workspace folder.
leetcodePractice.defaultLanguage Which language template a problem opens with (python3, cpp, rust, …).
leetcodePractice.studyPlans Which study plans the sidebar shows, by the slug in their URL.

Three commands have no button, and live in the palette: Change Default Language, Sign In with Cookie, and Clear Cache, which throws away the cached problem list and any solutions read without touching your own files.

Reading other people's solutions

The discussion button in the editor title bar lists the most upvoted community solutions for the problem, with votes, views and comments, and opens the one you pick as a Markdown preview beside your code. They are Markdown already, so VS Code's own preview renders them — no Markdown renderer or HTML sanitiser to ship, and the code blocks come out highlighted and copyable. Articles are cached under global storage rather than in the problem folder, since they are somebody else's work and the archive workflow sweeps up whatever sits next to a solution.

Developing

bun install
bun run compile

F5 starts the Extension Development Host. It passes --disable-extensions by default so a session exercises this extension alone, without noise or crashes from unrelated ones.

bun run typecheck
bun run lint
bun test

The tests cover the parts where being wrong is silent: reading judge payloads, undoing the escaping on community posts, deciding which language a file submits as, and normalising the vocabularies LeetCode uses in different places. They run against payloads recorded from real runs, so they need no credentials and no network. The scripts under scripts/ do talk to the API and are run by hand.

Conventions and the LeetCode API behaviour found by probing are in CLAUDE.md.

Licence

MIT — see LICENSE.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft