A place for Perry code to rest and run.
Coop turns a directory of Perry-compatible TypeScript into a native application library and serves it over HTTP, while the Perry runtime and standard library are supplied once per machine.
Experimental infrastructure for code you own
Perry compiles it. Coop keeps it running.
The distinction is where the language runtime lives. Coop keeps the application image small and supplies the compatible Perry runtime and standard library at the host level.
A regular Perry executable
The application, runtime, garbage collector, and selected standard-library features are linked into one target-specific executable.
A Coop deployment
The application is compiled as an app-only shared library. Compatible runtime providers are built once per machine, and their identity is verified before the app is mapped.
Split by failure boundary
The box, each deployment, and each request have separate responsibilities. Application code never runs in the box daemon.
Daemon · one per machine
Terminates TLS, routes by host and path, owns deployments, artifacts, the admin API, and metrics.
Worker · one per deployment
Loads the application library, owns Perry runtime state, and runs cron and durable queue work.
Invocation · one per request
Runs as a task inside the deployment worker, sharing its address space without spawning a process per request.
What works today
Coop is tested infrastructure, but it is not yet a finished hosting product. The current implementation includes:
- ✓TypeScript compilation, HTTP routing, and static mounts
- ✓Shared provider identity checks
- ✓Content-addressed deployments and rollback
- ✓Cron and a durable queue
- ✓Dedicated-worker KV and object storage
- ✓CLI, Prometheus metrics, alerts, and a Grafana dashboard
A small deployment surface
A deployment is a directory with a coop.toml file and one or more handlers. Coop compiles it, caches the result, and starts a local worker.
name = "hello"
version = "0.1.0"
[hosts]
domains = ["hello.test"]
[[handlers]]
file = "handlers/hello.ts"
path = "/hello"
method = "GET"import { CoopRequest, respond } from "@coop/runtime";
export function handle(reqJson: string): string {
const req = new CoopRequest(reqJson);
return respond(200, {}, `hello from ${req.path}`);
}$ coop-cli dev ./helloDeliberately narrow
A good fit today
- ✓Services and small applications whose code you own
- ✓One operator running a portfolio on one machine
- ✓Workloads that compile within Perry's TypeScript subset
- ✓Teams that value density, explicit artifacts, and fast rollback
Not a promise Coop makes yet
- ·Arbitrary npm or Node.js compatibility
- ·A sandbox for untrusted third-party code
- ·A Kubernetes replacement or multi-region platform
- ·Universal performance wins over Node.js
Density is the thesis. Benchmarks are still the work.
Current measurements point in different directions on different workloads. Coop has shown promising density on small Linux applications, while a full Next.js route has cost more CPU than Node.js in another test. Read the methodology before quoting either result.
Build with Perry. Give it a Coop.
Explore the source, run the example deployment, and help turn the shared-runtime model into dependable infrastructure.