LeetSense

I added IntelliSense to LeetCode 😏

Chrome ExtensionLanguage ServersWebAssembly

LeetSense exists because LeetCode's free editor did not have the IntelliSense I use in Zed and VS Code: completions, hover documentation, parameter hints, and diagnostics.

I wanted those features mainly to catch basic mistakes while solving a problem. A misspelled variable should be an editor diagnostic, not a failed run.

C++ diagnostics and completions running directly inside LeetCode.

Research before building

LeetCode already offers smart code autocomplete as a Premium feature. I also found a few Chrome extensions that added autocomplete to the free editor, so I tested those before building anything.

The most promising extension was no longer usable. Its reviews said it had worked earlier, but it had not been updated for about a year. LeetCode had changed in the meantime, and the extension no longer integrated with the editor correctly.

I set three constraints for LeetSense:

  • Reuse LeetCode's current editor instead of replacing it.
  • Use real semantic analysis instead of a hard-coded autocomplete list.
  • Keep the user's source code in the browser.

What LeetCode already provides

LeetCode uses Monaco, the editor used by VS Code. Monaco already has UI for completion menus, hover cards, parameter hints, and diagnostics.

On the free editor, some of those features were disabled. Re-enabling the UI was easy, but Monaco still needed a language service that understood the code.

LeetCode's Premium editor sends code to language servers running on its infrastructure. JavaScript and TypeScript were different because the page already included Monaco's TypeScript language service in the browser.

So the extension could reuse Monaco's UI and the existing TypeScript service. C++ and Python still needed real language servers.

Choosing the language servers

For Python, I used Pyright. It has a browser build, speaks the Language Server Protocol, and provides completions, hover information, signatures, and diagnostics.

For C++, I found a WebAssembly build of clangd. It was a real C++ language server running in the browser, but it came with two complications:

  • The binary was roughly 90 MB.
  • Its multithreaded runtime required cross-origin isolation.

LeetCode's page was not cross-origin isolated, and a content script could not change that. I moved the language servers into an extension-owned offscreen document with the required security headers. A small bridge passes document updates and language-server responses between Monaco and that document.

This kept the editor integration inside LeetCode while running clangd and Pyright in an environment controlled by the extension.

Verifying clangd with semantic tests

Starting clangd was not enough to prove that C++ support worked. My first acceptance test created a std::vector and requested its members. clangd returned no completions.

A small custom struct worked, which confirmed that the editor, bridge, and language server were communicating correctly. The failure was specific to the C++ standard library.

The WebAssembly package had most of the standard library, but it did not include the matching Clang resource headers. I added the exact LLVM headers expected by that clangd build and tested it outside the extension. C++ support was connected to Monaco only after the test returned results such as push_back and size.

A Windows-style dialog says β€œTask failed successfully.”

The worker was running, but semantic C++ completion was not. Meme source.

After this, every language engine got an end-to-end acceptance test. A running worker was not considered ready until it returned a correct semantic result.

Adding the code LeetCode hides

LeetCode solutions are not complete source files. The judge adds imports, headers, and types such as ListNode and TreeNode outside the visible editor.

A language server only sees the code in the editor, so it reports missing types and imports that LeetCode provides during execution.

LeetSense generates the missing context before sending the document to the language server. This wrapper stays hidden from the editor. Diagnostics are then mapped back to the original line numbers before Monaco displays them.

Without this step, valid LeetCode code would be marked as incorrect.

Browser lifecycle and performance

The C++ runtime is too large to start on every problem page. LeetSense loads clangd only when a C++ editor becomes active. Pyright follows the same pattern. If no editor is using a language server, the offscreen document is closed so the browser can reclaim the memory.

LeetCode also replaces Monaco models during navigation, and browser extension connections can disappear. A language-server response may arrive after the user has already changed the language or opened another problem.

I added request timeouts, restart cooldowns, version checks, and document replay after reconnecting. The status is marked as ready only after diagnostics for the current document version reach Monaco.

I profiled the message path before changing it. The useful improvements were linear parsing for clangd messages, streaming WebAssembly compilation, lazy Pyright startup, and reducing editor requests to one bridge round trip.

I also tested trimming the C++ headers, but it did not produce a useful improvement, so I kept the complete context.

Scope

LeetSense has no backend, account, telemetry pipeline, or AI completion layer. Source code stays in the browser.

The first version supports C++, Python, JavaScript, and TypeScript. Java was left out because I could not find a credible browser-based language server. A hard-coded autocomplete dictionary would have looked similar in a demo but would not understand the program.

LeetCode also uses CodeMirror in some editor modes. Monaco exposed the APIs LeetSense needed; CodeMirror did not, so it is not supported.

Result

LeetSense connects LeetCode's Monaco editor to clangd for C++ and Pyright for Python. For JavaScript and TypeScript, it uses the language service already included on the page.

It provides completions, hover documentation, parameter hints, and diagnostics without sending source code to a backend.

The main work was not the completion menu. It was running real language servers inside a browser extension, supplying the code LeetCode hides, recovering from extension lifecycle changes, and verifying that each engine returned correct semantic results.

If you want to use it, LeetSense is available on the Chrome Web Store.