GitHub - therepanic/openleetcode: we have democratized the LeetCode tests

3 min read Original article ↗

openleetcode is a local LeetCode runner built around open test suites, made in Haskell.

It takes a normal solution file, finds the matching problem manifest, builds a tiny language-specific harness, sends it to a pluggable execution backend, and judges the result locally. The tests live in the repo. The runtime templates live in the repo. The CLI is just the glue.

$ openleetcode submit ./solution.py --id 1
$ openleetcode submit ./solution.rs --title two-sum

Demo

openleetcode demo

Install

You need Docker for the execution backend. On Linux and macOS the installer will try to start the default Piston backend for you through Docker Compose.

Linux and macOS:

curl -fsSL https://raw.githubusercontent.com/therepanic/openleetcode/main/install.sh | sh

Windows PowerShell:

irm https://raw.githubusercontent.com/therepanic/openleetcode/main/install.ps1 | iex

On Windows, the installer only installs the CLI. Bring Docker yourself and start the backend manually.

Backend

openleetcode currently uses Piston as its execution backend. The default config points to:

From a checkout, start the bundled backend with:

docker compose -f backends/piston/docker-compose.yml up -d

Then check the CLI config:

$ openleetcode config list
$ openleetcode config set backend.url http://localhost:2000

Usage

Download the latest public data assets:

$ openleetcode download all

Run a solution by problem id:

$ openleetcode submit ./two_sum.py --id 1

Run a solution by title:

$ openleetcode submit ./solution.cpp --title "two-sum"

Override language detection when the file extension is ambiguous:

$ openleetcode submit ./main.abc --id 1 --lang python3

Update openleetcode:

Languages

The runner has templates for:

cpp, rust, python3, python2, ruby, java, csharp, kotlin, go, dart, swift, typescript

Each runtime provides the small compatibility layer LeetCode problems tend to need: JSON output, arrays, matrices, linked lists, binary trees, etc. Imports and common libraries are kept close to the official LeetCode environments, so a solution should look like a normal LeetCode submission, not a custom openleetcode program.

Contributing

For code changes, you need a Haskell toolchain with Cabal.

Build the CLI:

$ cabal build exe:openleetcode

Run the test suites:

$ cabal test core-tests
$ cabal test cli-tests

Run the built executable directly:

Contributing Without Code

Start with TEST_FORMAT.md. Seriously. It is the contract between the YAML, the runtime templates, and the judge.

Every problem is a directory with a manifest.yaml:

tests/1-500/1. two-sum/manifest.yaml
tests/1-500/1. two-sum/sol.py
tests/1-500/1. two-sum/sol.cpp

There are helper scripts too, because we are all human and writing the 39th edge case by hand is how people start bargaining with spreadsheets.

$ python generate_prompt.py two-sum
$ python spartan.py --skip 0 --limit 10 --no-generate --concurrency 5
$ python molotov.py --skip 0 --limit 10 --concurrency 5

generate_prompt.py builds a prompt for one LeetCode problem from its statement, code snippets, and a reference Python solution. spartan.py does the same in batches and can ask an LLM through OpenRouter to draft manifests into generated_problems/ when OPENROUTER_API_KEY is set. molotov.py fills in sol.{lang} files from those generated folders, reusing prompt.txt and sol.py. Treat the output like a junior contributor with infinite patience: useful, fast, and still very much in need of review.

Status

openleetcode is young and some manifests will be better than others. That is fine. The whole point is that the judge and tests are not sealed away somewhere.