Skip to content

CodeSprint is a typing practice environment for software engineers that uses real LeetCode-style code snippets instead of lorem ipsum, tracking WPM, accuracy, and errors in real time inside a minimal, keyboard‑first Next.js/React UI.

License

Notifications You must be signed in to change notification settings

cwklurks/codesprint

Repository files navigation

CodeSprint

Next.js 15 React 19 Monaco

codesprint demo

A "muscle memory engine" for LeetCode patterns.
It syncs real problem snippets via a custom GraphQL scraper and scores your typing accuracy against the actual syntax trees.

Engineering · Data Pipeline · Running Locally

Why?

Most typing tests are just String.split(' '). I felt like they measure your ability to type English, but that doesn't translate as much when you're typing code.

I built CodeSprint because I realized people sometimes fail technical interviews not on logic, but on syntax fluency. I needed a way to drill "Depth First Search in Python" or "Ring Buffer in C++" until my fingers knew the shape of the code.

Engineering

I wanted to create more than just a text area wrapper. Here is how I went about making it:

1. The Renderer (Monaco + Delta Decorations)

Instead of building a custom canvas renderer (yet), CodeSprint runs a heavily customized instance of the Monaco Editor (the core of VS Code).

  • Diffing: It uses deltaDecorations to paint correct/incorrect keystrokes directly onto the editor model without breaking the underlying syntax highlighting.
  • Layout: It calculates getScrolledVisiblePosition to overlay a really nice custom caret that behaves smoother than the native DOM caret.

2. The Sync Script (Bun)

I didn't really want to hardcode snippets. So, I wrote a custom scraper in Bun (scripts/sync-leetcode.ts) that:

  • Reverse-engineers the LeetCode GraphQL schema.
  • Fetches problems by difficulty and acceptance rate.
  • Sanitizes the code (strips docstrings and excessive comments).
  • Normalizes indentation to standard 4-space tabs.

3. The Latency Fight

React's render cycle is often too slow for a 100 WPM feedback loop. The typing engine (hooks/useTypingEngine.ts) isolates the keystroke logic from the React render tree where possible, only triggering re-renders for specific UI updates (like the WPM gauge) to avoid garbage collection pauses during typing bursts.

The Data Pipeline

To keep the snippets fresh, you can run the sync script locally:

# Requires Bun (https://bun.sh)
npm run sync:leetcode -- --limit 50 --difficulties medium,hard

This will:

  • Query the LeetCode questionData endpoint.
  • Parse codeSnippets for C++, Java, Python, and JS.
  • Output a minified JSON catalog to data/leetcode-snippets.json.
  • Autosort them into short, medium, and long problems.

Running Locally

# Install dependencies
npm install

# Start the Next.js 15 Turbopack server
npm run dev

Open http://localhost:3000.

Roadmap

  • Custom Renderer: Migrating from Monaco to a custom WebGL/Canvas text renderer to support large files with zero DOM overhead (Gap Buffer implementation in progress).
  • Parser Integration: Using Tree-sitter to allow "semantic typing" (skipping whitespace/formatting irrelevant to the code logic).

License

MIT.

About

CodeSprint is a typing practice environment for software engineers that uses real LeetCode-style code snippets instead of lorem ipsum, tracking WPM, accuracy, and errors in real time inside a minimal, keyboard‑first Next.js/React UI.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published