code-runner

Introduction

What code-runner is, who it's for, and how the pieces fit together.

code-runner is an open-source (MIT), self-hostable remote code execution service. You hand it code, it runs that code in a hardened, resource-bounded sandbox with a live interactive stdin session, and it streams the output back in real time.

Think Piston, but with first-class interactive stdin, a horizontally scalable Go worker pool, and an "add a language by adding a folder" extensibility model.

It is an internal service

code-runner is never exposed to the internet directly. In front of it sits your own backend (any stack), which authenticates with a bearer token and consumes the API. Browsers only ever receive output — over soketi — and never send trusted input directly to code-runner. See Architecture.

What it gives you

  • Run untrusted code safely. network=none, read-only rootfs, dropped Linux capabilities, a deny-by-default seccomp profile, non-root user, and cgroup memory/CPU/PID limits — applied to every sandbox unconditionally.
  • Interactive sessions. Write to a running process's stdin mid-execution and watch stdout/stderr stream back over WebSockets, chunk by chunk.
  • Multi-file input (text + binary). Submit many files and subdirectories in one job — UTF-8 text or base64 binary, materialized under /workspace. See Multi-file input.
  • Content-addressed blobs. Upload large or reused files once by sha256 and reference them by hash across runs — skipping re-upload and the request-size cap. See Large & shared files.
  • Optional zygote density tier. An opt-in warm-pool copy-on-write backend packs ~2.7× more heavy Python sandboxes per node. See the Zygote tier.
  • Bounded resource usage. Three independent clocks — wall, idle, and CPU — guarantee no sandbox, container, or session slot is ever leaked.
  • Real-time output via soketi (a Pusher-compatible WebSocket server). The worker triggers events; soketi fans them out to clients.
  • Trivially extensible. A language is a folder with a manifest.json and a Dockerfile. No Go or API changes needed.
  • Horizontally scalable & stateless. Scale the worker fleet by Redis queue depth. Scale-to-zero friendly.

The shape of the system

code-runner is a polyglot monorepo — each component uses the right tool:

ComponentTechRole
apps/apiHono / TypeScriptThe single trusted entry point. Validates requests, enqueues jobs, relays stdin & control signals.
apps/workerGoClaims jobs from Redis, launches hardened sandboxes via the host Docker daemon, keeps sessions alive, streams output to soketi.
packages/contractJSON Schema → TS + Zod + GoThe shared wire contract. One schema generates types for every language; a CI drift check guards the seam.
languages/manifest + DockerfileOne folder per language. Auto-discovered at boot.
RedisJob queue + stdin/control pub-sub + job metadata.
soketiOutput-only WebSocket fan-out to clients.

Where to go next

On this page