Skip to content

Supported Languages

Runtimes in the judge image and how to add more.

Defined in src/judge/languages.toml, registered in Postgres via /v1/languages. On startup the judge maps DB IDs to local configs by name. Typo in either place = compile failures for everyone. Fun afternoon.

LanguageVersionExtNotes
C++13.2.0.cppg++ -O2
C13.2.0.cgcc -O2
Python3.12.pyinterpreted
PyPy3.9.18.pysame ext as Python, different ID
Java21.0.3.java512 MB heap, renames file if class ≠ filename
JavaScript21.6.2.jsNode
TypeScript5.4.5.tstsc → Node
Go1.24.11.gomodule cache mounts, 2 cores at compile
Rust1.78.0.rsrustc
Ruby3.2.3.rb
Lua5.4.6.lua
Kotlin1.9.24.ktJVM, InputKt.class entry
Haskell9.4.7.hsGHC

Time/memory limits come from the problem, not this table. Defaults are usually 5 to 10s CPU and 256 to 512 MB unless you override on create.

Everything through nsjail. Judge service for the gory details.

Each block needs name, version, extension, and script. The script runs at compile time and must produce /executable/main. {IN_FILE} is the source path placeholder.

  1. Install toolchain in Dockerfile.newbase
  2. Write build script, test it in isolation if you can
  3. Rebuild judge image
  4. POST /v1/languages
  5. Submit a known AC solution. If step 5 fails, fix step 2 before blaming the algorithm.

Java: public class name must match filename, or the judge renames the file for you.

Go: first submission after cold start is slow (module download). Warm the cache or warn contestants.

TypeScript / Kotlin: compile errors show as COMPILE_TIME_ERROR, not runtime. Read stderr.

Python vs PyPy: same .py extension, different language IDs. Pick deliberately.

Output comparison: line-by-line, trimmed. "42\n" vs "42" can matter if you’re not printing newlines. Classic.