I Didn’t Want to Give Full GitHub Access — So I Built My Own LeetCode-to-GitHub Sync Chrome Extension

Published: (February 25, 2026 at 07:17 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Motivation

I was practicing problems on LeetCode and wondered if my GitHub could automatically reflect my progress. I wanted the contribution graph and repository history to show accepted submissions without manually uploading each solution.

Why I Built My Own Extension

Existing Chrome extensions required:

  • Full read/write access to all my GitHub repositories
  • Logging into my LeetCode account through the extension

Granting such broad permissions felt unsafe, especially when the extension only needed to write to a single repository. I decided to create a tool that:

  • Detects accepted LeetCode submissions
  • Reads the solution directly from the page DOM (no login handling)
  • Pushes the code to a specific GitHub repository using a fine‑grained personal access token

How It Works

The extension is built with Chrome Extension Manifest V3 and uses the GitHub REST API.

When a submission is accepted on LeetCode, the extension:

  1. Detects the accepted state
  2. Extracts the solution code and language from the DOM
  3. Creates a properly named file (organized by language)
  4. Pushes the file to the configured GitHub repository

Technical Challenges

Dynamic Editor Content

LeetCode renders the solution in a browser‑based editor, so the extension must:

  • Verify the submission is accepted
  • Wait for the editor content to be fully rendered
  • Extract the correct code and language

Timing and Idempotency

The sync should occur only after acceptance and only once per submission. The extension therefore:

  • Listens for the accepted state before extracting data
  • Tracks already‑synced submissions to avoid duplicate uploads

Extracting Additional Metadata

Problem difficulty and other details are also rendered dynamically, requiring careful DOM inspection to retrieve them reliably.

Manifest V3 Architecture

Transitioning from persistent background scripts to service workers introduced an event‑driven model. Understanding the interaction between content scripts, service workers, and extension storage was essential.

Publishing the Extension

After personal use, I published the extension on the Chrome Web Store. The MVP uses fine‑grained personal access tokens, which:

  • Limit access to a single repository
  • Avoid broad permissions
  • Keep the architecture simple without a backend

A more robust solution would involve GitHub Apps, offering better authentication flows and structured permissions—something I plan to explore later.

Future Improvements

  • Support syncing historical LeetCode submissions
  • Refine the authentication flow (e.g., migrate to GitHub Apps)
  • Enhance the setup process for user friendliness

Takeaways

Building this extension taught me:

  • How browser extensions interact with web applications
  • Secure integration with external APIs
  • Designing tools with minimal permissions
  • End‑to‑end development and publishing

It reinforced the idea that solving a personal annoyance can lead to a useful, shareable project.

  • GitHub repository:
  • Chrome Web Store:
0 views
Back to Blog

Related posts

Read more »