Skip to content

JetBrains-Research/Runway

Repository files navigation

Runway

JetBrains Research

Runway is an open-source service for executing code through a queue-backed service and worker architecture. It is designed for multilingual execution through language-specific workers; the current implementation includes a Python worker.

The repository contains the HTTP service, the Python worker, and the Helm chart used to deploy them together.

Repository layout

service/          Spring Boot WebFlux gateway for the execution API
python-worker/    Python worker that consumes execution jobs from NATS JetStream
charts/runway/    Helm chart for deploying Runway
docs/             Project documentation
examples/         Example requests, deployments, and integrations

API

The main execution endpoint is:

POST /api/v1/execute

Example request:

{
  "snippet": "print('Hello, World!')",
  "timeoutMs": 5000,
  "stdin": null,
  "executionType": "safe"
}

Example response:

{
  "exitCode": 0,
  "stdout": "Hello, World!\n",
  "stderr": "",
  "executionTimeMs": null
}

Batch execution is available at:

POST /api/v1/execute/batch

See service/README.md for the complete HTTP API, service configuration, metrics, and dead letter queue behavior.

Architecture

Runway separates the public API from code execution. Clients talk to the service over HTTP. The service publishes execution jobs to NATS JetStream — a lightweight, high-performance messaging system with persistent streams — waits for a worker response on a per-request reply subject, and returns the result to the client. NATS JetStream is used as the execution queue: it decouples the HTTP service from workers, provides at-least-once delivery, and allows workers to be scaled independently.

Client
  -> Runway service
      -> NATS JetStream stream
          -> Python worker
      <- worker reply
  <- HTTP response

The service owns request routing, timeouts, API responses, metrics, and the dead letter queue. Workers own language-specific execution. This keeps the service independent from any one runtime and allows additional worker implementations to be added without changing the HTTP API shape.

The current API executes Python snippets through the Python worker. Requests can be sent one at a time or as batches. The worker supports safe and unsafe execution modes; see python-worker/README.md for the exact behavior and tradeoffs.

Prerequisites

For local development from source:

  • Docker, for running NATS locally
  • JDK 21+, for the service
  • Python 3.12+
  • uv, for Python dependency management

For Kubernetes deployment:

  • A Kubernetes cluster
  • kubectl
  • Helm 3
  • Container images for the service and Python worker, either the defaults from the chart values or your own image repositories and tags

Runway uses NATS JetStream as its execution queue (see Architecture for details). The service creates the required stream by default when it starts.

The commands below use Bash-style syntax. On Windows, use Git Bash or WSL, or adapt shell-specific details such as ./gradlew and JSON quoting for PowerShell.

Run locally from source

Start NATS with JetStream enabled:

docker run --rm -p 4222:4222 nats:latest -js

In a second terminal, start the service:

cd service
./gradlew bootRun

In Windows PowerShell, run .\gradlew.bat bootRun instead.

The service listens on http://localhost:8080 and creates the default execution_requests stream.

In a third terminal, start the Python worker:

cd python-worker
uv sync
uv run uvicorn executor.app:app --host 0.0.0.0 --port 8000

Send a test request:

curl -s -X POST http://localhost:8080/api/v1/execute \
  -H 'Content-Type: application/json' \
  -d '{"snippet": "print(\"hello from Runway\")", "timeoutMs": 5000, "executionType": "safe"}'

Example response:

{
  "exitCode": 0,
  "stdout": "hello from Runway\n",
  "stderr": "",
  "executionTimeMs": null
}

If the service starts but no worker is running, requests time out and are written to the service dead letter queue.

Run locally with Docker

Create a Docker network and start NATS:

docker network create runway
docker run -d --rm --name runway-nats --network runway -p 4222:4222 nats:latest -js

Build and run the service:

docker build -t runway-service:local service
docker run -d --rm --name runway-service --network runway -p 8080:8080 \
  -e NATS_URL=nats://runway-nats:4222 \
  runway-service:local

Build and run the Python worker:

docker build -t runway-python-worker:local python-worker
docker run -d --rm --name runway-python-worker --network runway -p 8000:8000 \
  -e NATS_URL=nats://runway-nats:4222 \
  runway-python-worker:local

Then send the same request to http://localhost:8080/api/v1/execute.

Stop the local Docker setup when you are done:

docker stop runway-python-worker runway-service runway-nats
docker network rm runway

Deploy to Kubernetes

The Helm chart in charts/runway deploys the service, the Python worker, and, by default, a bundled NATS instance with JetStream enabled.

Install with the default values:

helm upgrade --install runway oci://ghcr.io/jetbrains-research/runway \
  --namespace runway \
  --create-namespace

For a local minikube deployment, build the images locally, load them into minikube, and override the chart image values:

docker build -t runway-service:local service
docker build -t runway-python-worker:local python-worker

minikube image load runway-service:local
minikube image load runway-python-worker:local

helm upgrade --install runway charts/runway \
  --namespace runway \
  --create-namespace \
  --set service.image.repository=runway-service \
  --set service.image.tag=local \
  --set workers.python.image.repository=runway-python-worker \
  --set workers.python.image.tag=local

Wait for the service and Python worker deployments:

kubectl -n runway rollout status statefulset/runway-nats
kubectl -n runway rollout status deployment/runway-service
kubectl -n runway rollout status deployment/runway-python-worker

Forward the service locally and send a test request:

kubectl -n runway port-forward svc/runway-service 8080:8080
curl -s -X POST http://localhost:8080/api/v1/execute \
  -H 'Content-Type: application/json' \
  -d '{"snippet": "print(\"hello from Kubernetes\")", "timeoutMs": 5000, "executionType": "safe"}'

Remove the test deployment when you are done:

helm uninstall runway --namespace runway
kubectl delete namespace runway

See charts/runway/README.md and charts/runway/values.yaml for chart configuration, image overrides, ingress, scaling, external NATS, and worker sandboxing options.

Security note

Runway executes user-provided code. Treat workers as untrusted-workload infrastructure and run them with appropriate isolation for your environment. The Helm chart supports setting a worker runtimeClassName, for example to use a sandboxing runtime such as gVisor when it is available in the cluster.

More documentation

License

Runway is licensed under the MIT License.

About

Runway is an open-source service for executing code through a queue-backed service and worker architecture.

Topics

Resources

License

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors