I Didn’t Want to Give Full GitHub Access — So I Built My Own LeetCode-to-GitHub Sync Chrome Extension
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:
- Detects the accepted state
- Extracts the solution code and language from the DOM
- Creates a properly named file (organized by language)
- 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.
Links
- GitHub repository:
- Chrome Web Store: