Show HN: Openleetcode – local LeetCode runner where tests live in the repo
Summary
Openleetcode is a local LeetCode runner built in Haskell, allowing developers to run LeetCode problems locally with tests stored in the repository and using Docker for backend execution.
View Cached Full Text
Cached at: 08/18/26, 07:02 PM
therepanic/openleetcode
Source: https://github.com/therepanic/openleetcode
"There are no magic machines and no magic operators." - DHH
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
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. On Windows, the installer only installs the CLI. Bring Docker yourself and start the backend manually.
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
Docker:
curl -fsSL https://raw.githubusercontent.com/therepanic/openleetcode/main/openleetcode.yml -o openleetcode.yml
curl -fsSL https://raw.githubusercontent.com/therepanic/openleetcode/main/backends/piston/docker-compose.yml -o piston.yml
docker compose -f piston.yml up -d
docker compose -f openleetcode.yml -f piston.yml run --rm openleetcode --version
The backend may take a while to install runtimes on the first start.
Backend
openleetcode currently uses Piston as its execution backend. The default config points to:
http://localhost:2000
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:
$ openleetcode update
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:
$ cabal run openleetcode
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.
Similar Articles
Lambda on Lambda: Serverless Haskell on AWS
Jack Kelly provides an end-to-end example and talk slides for deploying Haskell functions as AWS Lambda using OCI containers and OpenTofu.
Show HN: Local text, image, video, music and 3D from one CLI, no Python
mere.run is a local-first inference runtime for Apple Silicon and headless Linux that provides a single CLI for text, image, video, music, 3D, and more without requiring Python.
opencodex (GitHub Repo)
opencodex is a lightweight local proxy that lets you use any LLM (Claude, Gemini, Grok, DeepSeek, etc.) with OpenAI Codex and Claude Code, supporting streaming, tool calls, and reasoning tokens.
Show HN: Codiff, a local diff review tool
Codiff is a minimal, local diff viewer for reviewing staged and unstaged Git changes, with LLM-powered walkthroughs and inline review comments.
RepoLens – An interactive local codebase packer and token optimizer (TUI/CLI) written in Go
RepoLens is a zero-dependency Go tool that packs local codebases into a single file for LLM context, featuring an interactive TUI file explorer, live token counting, comment stripping, and secret scanning.