lc is a small Rust CLI for LeetCode workflows. It keeps read-only discovery on a public convenience endpoint, shows profile activity, and uses authenticated LeetCode endpoints for judge runs and real submissions.
I made this because I wanted to learn Neovim, and LeetCode felt like a good source of small finger exercises. I tried a few other CLIs, but authentication was rough enough that building a small one around browser-cookie auth felt simpler.
cargo install --path . --forceThis installs lc to Cargo's binary directory, usually ~/.cargo/bin.
Authenticated commands need LEETCODE_SESSION and LEETCODE_CSRF_TOKEN. The CLI can read them from the environment or probe your browser cookies with the helper script:
lc loginThe command prints shell exports. Source or paste those exports if browser probing is not available automatically in your shell.
Treat the printed values like credentials: avoid pasting them into shared terminals, shell history, or logs.
Read-only discovery commands use https://leetcode-api-pied.vercel.app by default. Override it with LC_PUBLIC_API_BASE_URL if you run a compatible mirror:
export LC_PUBLIC_API_BASE_URL='https://example.com'lc daily
lc list
lc list --limit 100
lc list --topic string
lc problem two-sum
lc profile
lc profile ynbh
lc edit two-sum
lc edit two-sum --lang rust
lc edit two-sum --editor nvim
lc test two-sum solutions/two-sum.py
lc test solutions/two-sum.py
lc test two-sum solutions/two-sum.cpp
lc check two-sum solutions/two-sum.py
lc check solutions/two-sum.py
lc check two-sum solutions/two-sum.rs
lc run two-sum solutions/two-sum.py
lc run solutions/two-sum.py
lc run two-sum solutions/two-sum.py --input-file input.txt
lc submit two-sum solutions/two-sum.py
lc submit solutions/two-sum.py
lc submit two-sum solutions/two-sum.rs
lc status <submission-or-run-id>Files created by lc edit include a small metadata header, so test, run, check, and submit can infer the problem when called with only the solution path. Explicit <problem> <file> calls still work and are required for files without metadata.
lc test uses LeetCode's provided example testcases through the authenticated custom-run endpoint. It does not submit.
lc check runs LeetCode's provided example testcases first. If they pass, it submits; if they fail, it prints the judge result and skips the real submission.
lc run also uses the custom-run endpoint. Without --input-file, it uses the problem's example testcases; with --input-file, it sends your custom input.
lc submit sends a real LeetCode submission.
lc edit creates solutions/<problem-slug>.<extension> from LeetCode's starter template when it does not already exist, then opens it in --editor, $VISUAL, $EDITOR, or nvim.
lc profile includes profile stats and a compact contribution-style activity chart when LeetCode returns calendar data.
The CLI auto-detects the LeetCode language from the solution file extension. Currently supported:
| Extension | LeetCode language |
|---|---|
.py |
python3 |
.cpp |
cpp |
.java |
java |
.js |
javascript |
.ts |
typescript |
.rs |
rust |
.go |
golang |
.c |
c |
.cs |
csharp |
.kt |
kotlin |
.swift |
swift |
.php |
php |
.rb |
ruby |
.scala |
scala |
.dart |
dart |
.rkt |
racket |
.erl |
erlang |
.ex |
elixir |
You can override detection with --lang when the extension is ambiguous or you want to force the LeetCode slug:
lc test two-sum ./scratch.txt --lang python3
lc run two-sum ./solution.cc --lang cpp
lc submit two-sum ./main.go --lang golangThe project is test-first. See docs/development.md for the architecture contract and docs/endpoints.md for the LeetCode endpoint notes.
cargo fmt -- --check
cargo test