Tools
The OJS ecosystem includes tools for operations, development, validation, testing, and code generation.
Repository: ojs-cli/
Language: Go
The OJS CLI (ojs) is a command-line tool for managing jobs, queues, workers, cron schedules, and workflows against any OJS-compliant backend.
Installation
Section titled “Installation”go install github.com/openjobspec/ojs-cli@latestCommands
Section titled “Commands”| Command | Description |
|---|---|
ojs enqueue | Enqueue a job |
ojs status <id> | Get job status |
ojs cancel <id> | Cancel a job |
ojs queues | List queues and stats |
ojs queues pause <name> | Pause a queue |
ojs queues resume <name> | Resume a queue |
ojs workers | List active workers |
ojs workers quiet <id> | Quiet a worker |
ojs cron list | List cron schedules |
ojs cron register | Register a cron job |
ojs workflows | List workflows |
ojs dead-letter | List dead letter jobs |
ojs dead-letter retry <id> | Retry a dead letter job |
ojs monitor | Live monitoring dashboard |
# Enqueue a jobojs enqueue --type email.send --args '["user@example.com","Welcome!"]'
# Check statusojs status 01961234-5678-7abc-def0-123456789abc
# Monitor liveojs monitor --url http://localhost:8080
# Output as JSONojs queues --format jsonConfiguration
Section titled “Configuration”| Environment variable | Default | Description |
|---|---|---|
OJS_URL | http://localhost:8080 | OJS server URL |
OJS_FORMAT | table | Output format (table or json) |
Admin UI
Section titled “Admin UI”Repository: ojs-admin-ui/
Language: TypeScript (React 19 + Vite)
A universal web dashboard for managing any OJS backend. The Admin UI auto-discovers backend capabilities via the OJS manifest and adapts its interface accordingly.
Features
Section titled “Features”- Dashboard — Real-time job statistics, throughput charts, queue depth gauges
- Queues — View, pause, resume, purge queues with live stats
- Jobs — Search, filter, inspect, cancel, retry individual jobs
- Workers — Monitor active workers, send quiet/terminate signals
- Dead Letter — Browse, retry, delete dead letter jobs
- Dark Mode — System-aware theme with manual toggle
- Auto-refresh — Configurable polling interval for live updates
Deployment
Section titled “Deployment”The Admin UI can be served as static files by any OJS backend at /ojs/admin, or run standalone:
cd ojs-admin-uinpm installnpm run dev # Development servernpm run build # Production build to dist/Backends can embed the UI:
import "github.com/openjobspec/ojs-admin-ui"
mountOJSAdmin(element, { baseUrl: "", basename: "/ojs/admin" })Playground
Section titled “Playground”Repository: ojs-playground/
URL: play.openjobspec.org
An interactive development environment for exploring OJS without any local setup.
Browser mode
Section titled “Browser mode”The playground runs entirely in the browser and includes:
- Schema editor — Monaco-based editor with OJS JSON Schema validation
- State machine visualization — Interactive job lifecycle diagram (React Flow)
- Retry timeline — Visual retry backoff calculator (Recharts)
- Code generation — Generate SDK code from job definitions (Go, TypeScript, Python, Java, Rust, Ruby)
- Templates — Pre-built examples for common patterns
Local mode
Section titled “Local mode”For testing against real backends:
cd ojs-playgrounddocker compose upLocal mode starts a Go backend and executes jobs with real state transitions, streamed to the browser via SSE.
Kubernetes Operator
Section titled “Kubernetes Operator”Repository: ojs-k8s-operator/
Language: Go
The OJS Kubernetes Operator manages OJS clusters declaratively using a custom OJSCluster resource. It supports all backend types, auto-scaling, and integrated monitoring.
Features
Section titled “Features”- Declarative management — Define your OJS cluster as a Kubernetes custom resource
- Multi-backend support — Redis, PostgreSQL, and NATS backends with optional embedded instances
- Auto-scaling — HPA-based scaling driven by queue depth and worker utilization
- Monitoring — Built-in Prometheus metrics and optional Grafana dashboard provisioning
Example CRD
Section titled “Example CRD”apiVersion: ojs.openjobspec.org/v1alpha1kind: OJSClustermetadata: name: my-ojsspec: backend: redis replicas: 3 resources: requests: cpu: "500m" memory: "512Mi" autoScaling: enabled: true minReplicas: 2 maxReplicas: 10 targetQueueDepth: 1000 monitoring: enabled: trueInstallation
Section titled “Installation”# Install the CRD and operatorkubectl apply -f https://github.com/openjobspec/ojs-k8s-operator/releases/latest/download/install.yaml
# Create a clusterkubectl apply -f my-ojs-cluster.yaml
# Check statuskubectl get ojsclustersCloudEvents Bridge
Section titled “CloudEvents Bridge”Repository: ojs-cloudevents-bridge/
Language: Go
The CloudEvents Bridge provides bidirectional mapping between CloudEvents v1.0 and OJS events. It enables integration with event-driven platforms like Knative, Azure Event Grid, AWS EventBridge, and Dapr.
Packages
Section titled “Packages”| Package | Description |
|---|---|
bridge | Core mapping functions: OJSToCloudEvent(), CloudEventToOJS() |
middleware | HTTP middleware that intercepts incoming CloudEvents and converts them to OJS enqueue requests |
OJS → CloudEvents mapping
Section titled “OJS → CloudEvents mapping”| OJS field | CloudEvents field |
|---|---|
event.type | type (prefixed with org.openjobspec.) |
event.source | source |
event.subject | subject |
event.data | data |
event.id | id |
import ( "github.com/openjobspec/ojs-cloudevents-bridge/bridge" "github.com/openjobspec/ojs-cloudevents-bridge/middleware")
// Convert OJS event to CloudEventce := bridge.OJSToCloudEvent(ojsEvent)
// Convert CloudEvent to OJS jobjob := bridge.CloudEventToOJS(cloudEvent)
// HTTP middleware: auto-convert incoming CloudEvents to OJS enqueue requestsrouter.Use(middleware.CloudEventInterceptor(ojsClient))See the CloudEvents Interop spec for the full mapping specification.
Conformance test suite
Section titled “Conformance test suite”Repository: ojs-conformance/
Language: Go (test runner), JSON (test definitions)
The conformance test suite validates that an OJS backend correctly implements the specification. Tests are organized into five levels, each a superset of the previous.
Conformance levels
Section titled “Conformance levels”| Level | Name | What it tests |
|---|---|---|
| 0 | Core | Enqueue, fetch, ack, nack, health, queue listing, schemas |
| 1 | Lifecycle | Job info, cancel, dead letter, heartbeat, state transitions |
| 2 | Scheduling | Delayed jobs (scheduled_at), cron job registration, timezone handling |
| 3 | Workflows | Chain, group, and batch workflow primitives |
| 4 | Full | Batch enqueue, unique jobs, priority ordering, queue pause/resume, queue stats |
Running conformance tests
Section titled “Running conformance tests”The test runner makes HTTP requests against a running OJS server. Set OJS_URL to point to your server.
Against the Redis backend:
cd ojs-backend-redismake docker-up # Start the servermake conformance # Run all levelsmake conformance-level-0 # Run just Level 0make conformance-level-1 # Run just Level 1Against any OJS server:
cd ojs-conformanceOJS_URL=http://localhost:8080 go test ./runner/http/ -vTest structure
Section titled “Test structure”Test definitions are JSON files in ojs-conformance/. Each test specifies:
- An HTTP request (method, path, body)
- Expected response (status code, body fields, timing constraints)
- Pre-conditions and post-conditions
Tests are language-agnostic. The Go test runner executes them, but the test definitions could be used by a runner in any language.
Using conformance to build a backend
Section titled “Using conformance to build a backend”If you are building a new OJS backend, start with Level 0 and work up. The conformance tests are the definitive guide to expected behavior. See Implement a Backend for a walkthrough.
JSON Schema package
Section titled “JSON Schema package”Repository: ojs-json-schema/
Language: Node.js
JSON Schema (draft 2020-12) definitions for all OJS data structures.
Schemas included
Section titled “Schemas included”| Schema | File | Description |
|---|---|---|
| Job Envelope | job.schema.json | Complete job envelope validation |
| Retry Policy | retry-policy.schema.json | Retry configuration |
| Unique Policy | unique-policy.schema.json | Deduplication configuration |
| Error | error.schema.json | API error response format |
| Event | event.schema.json | Lifecycle event format |
| Batch Request | batch-request.schema.json | Batch enqueue request |
pnpm add @openjobspec/json-schemaimport jobSchema from '@openjobspec/json-schema/job.schema.json';import Ajv from 'ajv';
const ajv = new Ajv();const validate = ajv.compile(jobSchema);const valid = validate(myJobEnvelope);See JSON Schemas Reference for the full schema definitions.
Protobuf definitions
Section titled “Protobuf definitions”Repository: ojs-proto/
Language: Protobuf (with Go and TypeScript codegen)
gRPC service definitions for the OJS gRPC protocol binding. Uses Buf for linting and code generation.
Contents
Section titled “Contents”ojs/v1/job.proto- Job envelope message typesojs/v1/service.proto- gRPC service definitionsojs/v1/error.proto- Error response typesojs/v1/workflow.proto- Workflow message types
Commands
Section titled “Commands”buf lint # Lint proto filesbuf generate # Generate Go + TypeScript codeGenerated code
Section titled “Generated code”Buf generates:
- Go: Full gRPC client and server stubs with protobuf marshaling
- TypeScript: Type definitions and client stubs for use with gRPC-web or Connect
Examples & demos
Section titled “Examples & demos”Repository: examples/
Runnable examples for every SDK, plus full-stack and observability demos. Each example includes a Docker Compose file to start a backend, so you can run it with zero infrastructure setup.
Language quickstarts
Section titled “Language quickstarts”| Example | Language | What it demonstrates |
|---|---|---|
go-quickstart | Go | Enqueue + worker with retry policy |
js-quickstart | TypeScript | Enqueue + worker with middleware |
python-quickstart | Python | Async enqueue + worker |
java-quickstart | Java | Enqueue + worker with records |
rust-quickstart | Rust | Async enqueue + worker with tokio |
ruby-quickstart | Ruby | Enqueue + worker |
Full-stack demo
Section titled “Full-stack demo”The full-stack-demo provides a complete end-to-end example: a Go web API enqueues jobs, a Go worker processes them, and an OJS Redis backend manages the lifecycle. Includes retry support and status polling.
cd examples/full-stack-demodocker compose upOpenTelemetry demo
Section titled “OpenTelemetry demo”The otel-demo demonstrates distributed tracing across the full job lifecycle using OpenTelemetry and Jaeger. Shows end-to-end traces with span attributes (job ID, queue, attempts) and error tracking.
cd examples/otel-demodocker compose up# Open Jaeger UI at http://localhost:16686Development workflow
Section titled “Development workflow”Setting up a local development environment
Section titled “Setting up a local development environment”-
Start a backend:
Terminal window cd ojs-backend-redismake docker-up -
Verify health:
Terminal window curl http://localhost:8080/ojs/v1/health -
Check conformance:
Terminal window make conformance -
Run SDK tests:
Terminal window # JavaScriptcd ojs-js-sdk && pnpm test# Gocd ojs-go-sdk && go test ./...# Pythoncd ojs-python-sdk && pytest
Testing against different backends
Section titled “Testing against different backends”The beauty of OJS is that you can swap backends without changing your application code. To test against PostgreSQL instead of Redis:
cd ojs-backend-postgresmake docker-up# Same SDK code, same tests, different backendUseful curl commands
Section titled “Useful curl commands”# Health checkcurl http://localhost:8080/ojs/v1/health
# Conformance manifestcurl http://localhost:8080/ojs/manifest
# Enqueue a jobcurl -X POST http://localhost:8080/ojs/v1/jobs \ -H "Content-Type: application/openjobspec+json" \ -d '{"type":"test.hello","args":["world"]}'
# List queuescurl http://localhost:8080/ojs/v1/queues
# Get a jobcurl http://localhost:8080/ojs/v1/jobs/<job-id>
# List dead letter jobscurl http://localhost:8080/ojs/v1/dead-letter