Run Rocket routes on Cloudflare Workers.
📖 Full documentation: comet.physikos.app
Rocket's published releases pull in Hyper/Tokio networking that doesn't
compile to wasm32-unknown-unknown. comet pairs a patched Rocket (vendored
in this repo, see vendor/rocket/COMET_NOTES.md)
with an adapter that dispatches worker::Requests straight through Rocket's
routing, guards, and responders — no socket, no Hyper — and converts the
result back into a worker::Response.
use worker::{event, Context, Env, Request, Response, Result};
#[macro_use]
extern crate rocket;
#[get("/")]
fn index() -> &'static str {
"hello from Rocket on Cloudflare Workers"
}
fn rocket(env: Env, _ctx: Context) -> rocket::Rocket<rocket::Build> {
rocket::build().manage(env).mount("/", routes![index])
}
#[event(fetch)]
pub async fn main(req: Request, env: Env, ctx: Context) -> Result<Response> {
comet::cloudflare::fetch(req, env, ctx, rocket).await
}See examples/cloudflare-worker for a complete
app: a D1-backed task API with async D1/Queue calls, custom struct
(de)serialization, R2 object streaming, a Worker WebSocket echo endpoint, an
async queue consumer, and both unit and end-to-end tests.
This is an early-stage adapter, not a finished framework integration. What works today:
- Request and response bodies are streamed through Rocket, not buffered —
neither side is read fully into memory before the other can start working
with it.
examples/cloudflare-worker'stests/integration.shproves this isn't just "it compiles": a/streamroute response's time-to-first-byte is checked against its total time, and a 1MiB request body is checked for an exact round-trip. See "Streaming adapter" in the roadmap for how. - JSON data guards and responders.
- Cloudflare bindings (
Env, D1, Queues, KV, R2, service bindings, and Hyperdrive) via Rocket managed state —comet::cloudflare::D1,QueueBinding,Kv,R2Bucket,ServiceBinding, andHyperdriveprovide typed request guards for named bindings. Worker builds use local-boxed Rocket route futures, so routes can await D1/Queue calls directly.comet::cloudflare::local()remains available for manual compatibility cases, andlocal_stream()bridges Rocket'sSend-bound streaming responders with!SendWorker streams. - R2-backed object responses via
comet::cloudflare::R2Object, which streams an object body through Rocket, preserves R2 HTTP metadata, and avoids pretending that local filesystem responders work in Workers. - Worker WebSocket routes via
WebSocketUpgradeandWebSocketResponsewhen thecloudflare-websocketfeature is enabled. WebSockets still become CloudflareWebSocketPairresponses under the hood, but applications can mount them with normal Rocket route syntax.
What's not there yet: full storage-backed replacements for filesystem APIs
such as FileServer, NamedFile, and disk-backed TempFile. See
docs/rocket-worker-roadmap.md for the full
plan.
comet isn't published to crates.io yet. Verified with cargo package:
error: failed to verify manifest at `.../Cargo.toml`
Caused by:
all dependencies must have a version requirement specified when packaging.
dependency `rocket` does not specify a version
Note: The packaged dependency will use the version from crates.io,
the `path` specification will be removed from the dependency declaration.
Adding a version to the rocket path dependency would silence that error,
but it wouldn't fix anything: crates.io replaces path dependencies with the
matching registry version at publish time, so consumers would get the
unpatched, non-worker-featured Rocket instead of the fork vendored here.
Publishing comet to crates.io needs the patched Rocket fork to have its own
public, versioned home first (either published under a different crate name,
or rocket-worker-feature.patch upstreamed) — see
docs/rocket-worker-roadmap.md.
Until then, depend on it via git once this repository has a public remote:
[dependencies]
comet = { git = "https://github.com/viniciusamelio/comet", default-features = false, features = ["cloudflare"] }A git dependency clones the whole repo, so the vendored rocket path
dependency resolves the same way it does locally — no extra setup needed on
the consumer's side.
native-client(default): aRocketWorkerthat dispatchesWorkerRequest/WorkerResponsethrough Rocket's local async client. Useful for testing the request/response shapes without aworkerruntime.cloudflare: thecomet::cloudflaremodule —fetch(),FetchApp,serve(), theApplicationimpl forRocket<Build>,local(), andlocal_stream(). Requiresworker.cloudflare-d1,cloudflare-queue,cloudflare-kv,cloudflare-r2,cloudflare-service,cloudflare-hyperdrive: typed request guards for the corresponding Cloudflare bindings.cloudflare-r2also enables theR2Objectresponder.cloudflare-websocket:WebSocketUpgrade,WebSocketResponse, and low-level Worker WebSocket helpers. Keep it off for HTTP-only Workers.nebula: the experimental D1-first ORM core —#[derive(Entity)], entity metadata, typed columns, foreign-key metadata, SQL values, deterministic SQL builders, explicit relationship helpers, query/schema lints, and migration SQL generation. It is fully feature-gated and is not compiled unless enabled.nebula-d1: D1 execution helpers for Nebula statements. This enablesnebula,cloudflare-d1, andserde.nebula-schema: an owned, serializable mirror of Nebula's schema metadata (comet::nebula::schema), for tooling that needs to persist a schema snapshot to disk and diff it later — this is whatcomet-cli'scomet migratecommands use. Enablesnebulaandserde; does not requirecloudflare/worker.
A CLI (binary name comet) that scaffolds Comet + Nebula projects, generates
entities and CRUD routes, drives migration generation, and runs a project's
test gate. See comet-cli/README.md for install and
usage, and docs/comet-cli-roadmap.md for the
full command reference.
See docs/testing.md for how to choose between native
route tests, Comet adapter dispatch tests, and wrangler dev integration
tests.
cargo test --features native-client # adapter tests, run natively
cargo test --no-default-features --features cloudflare # also runs natively
cargo bench --bench native_adapter # adapter-only performance baseline
cargo bench --bench nebula_sql --features nebula # Nebula SQL generation baseline
cd examples/cloudflare-worker && npm install && npm run test && npm run test:integrationLicensed under either of Apache License, Version 2.0 or
MIT license at your option. The vendored Rocket fork under
vendor/rocket retains its own original MIT/Apache-2.0 licensing from the
Rocket project.