Free, offline-friendly coding interview practice that runs entirely on your machine.
About 4,100 problems · 2,830 judged against 273k hidden tests · company frequency lists for 423 companies · Python, Java, C++ and Kotlin
Interview prep sites lock the most useful features behind a subscription: company-tagged question lists, frequency data and full solutions. None of that needs a server. localcode puts it all on your own computer:
- No account, no subscription, no tracking. Your code and progress never leave your machine.
- The same environment for everyone. Code is judged by pinned compilers and runtimes inside Docker, so a solution that passes for you passes for anyone else.
- Open data. Problems, tests, solutions and company lists come from open-source projects, downloaded when you first start the app.
localcode is an independent project. It is not affiliated with, or endorsed by, LeetCode.
You need Docker with Compose v2, with at least 4 GB of memory available to it.
git clone https://github.com/RyPope/localcode.git
cd localcode
docker compose up -d --buildOpen http://localhost:4173. The first launch downloads and indexes the open datasets (about 200 MB, a few minutes), and you can watch it happen:
Then pick a company or a problem and start solving.
| Task | Command |
|---|---|
| Stop (your data is kept) | docker compose down |
| Start again | docker compose up -d |
| Update problem data | Progress → Refresh content, or make update |
| Update localcode itself | git pull && docker compose up -d --build |
| Use a different port | LOCALCODE_PORT=8080 docker compose up -d |
| Reach it by another host name | LOCALCODE_ALLOWED_HOSTS=localhost,mybox.lan docker compose up -d (and change the port binding in docker-compose.yml) |
flowchart LR
B["Browser<br/>localhost:4173"] --> A
subgraph Docker["Docker Compose"]
A["app<br/>FastAPI + React UI"]
R["runner<br/>Python 3.14 · JDK 25 · Clang 23 · Kotlin 2.4<br/>no network"]
D[("localcode-data volume<br/>content.db · user.db")]
A -- "code + test inputs<br/>(Unix socket)" --> R
R -- "raw outputs" --> A
A --- D
end
S["Open datasets<br/>(first run and updates)"] -.-> A
- The app serves the UI, imports content, and judges results.
- The runner compiles and executes submissions. It has no network at all (the app reaches it through a Unix socket), and runs each submission as an unprivileged user with time, memory and process limits. It cleans up after every run. See SECURITY.md for the full model.
- Tests are language-neutral. Every case is stored as JSON arguments and an expected value. Small per-language harnesses turn those into real typed calls: Python through type hints, Java and Kotlin by reflection, C++ through a generated
main. Outputs are compared in the app, never in your code. - Your progress lives in
user.db, separate from the problem data, so updating content never touches your drafts or submissions.
More detail: docs/architecture.md.
localcode ships no problem content. On first run, your installation downloads it directly from these projects and joins them by problem slug:
| Data | Source | License |
|---|---|---|
| Test cases (about 100 per problem), Python starter code | newfacade/LeetCodeDataset | Apache-2.0 |
| Problem statements, reference solutions, explanations | doocs/leetcode | CC BY-SA 4.0 |
| Company frequency lists | liquidslr/leetcode-company-wise-problems | none stated |
flowchart LR
T[LeetCodeDataset] --> I[importer]
S[doocs/leetcode] --> I
C[company lists] --> I
I --> F["filter invalid test cases"] --> DB[(content.db)]
The upstream test cases were generated by running Python solutions on synthetic inputs, and a few of them break the problems' own constraints (for example 64-bit values where a problem promises 32-bit ones). The importer removes cases the typed languages can't represent. It also applies an exclusion list of about 2,100 cases in 308 problems, produced by make validate-cases: it runs the Java and C++ reference solutions over every unfiltered suite with the same answer checking users get, and excludes cases the references reject, plus cases whose recorded answer fails the problem's own answer checker.
See NOTICE.md for attribution.
The content/ folder holds problems, test cases and solutions that are part of localcode itself. They are plain Markdown and JSON files, contributed by pull request. They're merged over the downloaded data on every import, and they can add new problems or improve existing ones. A refresh adds and updates content but never removes anything an earlier import had. See content/README.md for the format.
Each source can fall back to mirrors you control. If every source is unreachable, an update keeps your existing copy. Set any of these (comma-separated URLs, tried after the default) before starting:
| Variable | Default source |
|---|---|
LOCALCODE_DATASET_MIRRORS |
Hugging Face dataset files |
LOCALCODE_DOOCS_MIRRORS |
github.com/doocs/leetcode |
LOCALCODE_COMPANIES_MIRRORS |
github.com/liquidslr/leetcode-company-wise-problems |
Everything is stored in the localcode-data Docker volume. To keep a copy of your progress, use Progress → Export progress, or back up the database file:
docker compose cp app:/data/user.db ./localcode-user-backup.dbdocker compose down -v deletes the volume, including your progress.
- Kotlin reference solutions are sparse upstream, so the Solutions tab shows Java for most Kotlin problems. Kotlin submissions are judged normally.
- Problems with several valid answers are judged by checking the answer, not by matching one expected output: 75 problems ("return any valid arrangement", course orders, Gray codes, CIDR covers, …) have a checker that validates the answer against the input, and "in any order" answers are compared ignoring order (at every level where the problem allows it). A multi-answer problem without a checker yet is still compared against one expected answer; please report it.
- Design, SQL, shell and concurrency problems can be read but not run.
- C++ is compiled with Clang 23 and
-std=c++23 -O2but without AddressSanitizer, so some out-of-bounds bugs may go unnoticed instead of failing with a runtime error. - Cold-start compile times are about 1 to 2 s for Java and C++ and about 4 s for Kotlin.
The setup screen says the import failed
Check your internet connection and press Retry. If a source is down, configure a mirror (see above). docker compose logs app shows the details.
"Code runner unavailable"
The runner container isn't running or is restarting. docker compose ps should show it as running; docker compose up -d starts it again.
Port 4173 is already in use
Start on another port: LOCALCODE_PORT=8080 docker compose up -d.
My correct solution was rejected
A few upstream test cases may still be invalid. Please open a wrong verdict report with your code and the failing case, and we'll fix the answer checking or exclude the case.
Contributions are welcome, from wrong-verdict reports to new languages. Start with CONTRIBUTING.md; for a quick start:
make setup # Python venv + web dependencies
make up # build and run the stack
make dev-web # hot-reloading UI on :5173
make test # backend, runner and web tests
make lint # ruff, ESLint, PrettierPlease read the Code of Conduct. Security issues go through SECURITY.md, not public issues.
localcode exists because of the people behind LeetCodeDataset, doocs/leetcode and leetcode-company-wise-problems. It is built with FastAPI, React, TanStack Query, Monaco Editor, KaTeX and Geist.
MIT © 2026 Ryan Pope. Problem content downloaded at runtime is subject to its sources' licenses (see NOTICE.md).






