Skip to content

Repository files navigation

@mieweb/cloud

A thin, stable portability layer over the platform primitives an app uses — database, object storage, key/value, queues, stateful objects, vector index, and AI. It is inspired by Cloudflare's clean serverless APIs and aims for feature parity across runtimes — without promising a 1:1 match everywhere. The organizing principle:

Cloudflare is the reference implementation and stays first-class and zero-overhead. The layer never gets in the way of targeting Cloudflare: on that target your code runs against the native bindings, unchanged. The same application code can then target other runtimes — local Node today; os.mieweb.org, AWS, GCP later — through adapters that implement the same Cloudflare-shaped contract as faithfully as each environment allows.

Design bias: compatibility over purity, parity over perfection. Adapters chase Cloudflare's behavior closely, but where a runtime genuinely can't match a primitive the difference is surfaced honestly (an explicit UnsupportedBindingError or a documented gap) rather than faked. The first version makes an existing Cloudflare codebase portable with the fewest possible source changes.

Packages

Three packages, split by what a consumer must install, not by module:

Package Role
@mieweb/cloud Zero dependencies. The portable contracts (CloudDatabase, CloudBucket, CloudKV, CloudQueue, CloudStatefulNamespace, CloudVectorIndex, CloudAI, CloudContainerNamespace, UnsupportedBindingError) and, at @mieweb/cloud/workers, the DurableObject base behind the mieweb:workers import — re-exports cloudflare:workers on Cloudflare (workerd export condition), pure-JS base everywhere else. This is the only package a Cloudflare app touches.
@mieweb/cloud-adapters Off-Cloudflare adapters + the Node host harness and migration runner. ./local: D1→SQLite, R2→filesystem, KV→in-memory, Queues→in-process, Durable Objects→in-process, Vectorize→sqlite-vec. ./os (os.mieweb.org / self-hosted): D1→libSQL, Vectorize→libSQL vectors, R2→S3/MinIO, KV+Queues→Valkey; ships a docker-compose.yml. Backend SDKs are optional peers — install only what your target needs.
@mieweb/cli The mieweb CLI. On the cloudflare target it delegates verbatim to wrangler; on the local/mieweb targets it runs the matching adapter via the Node host harness.
@mieweb/test-app (private) A tiny worker that exercises every contract surface over plain HTTP, plus a cross-target runner. The same worker + the same assertions prove the layer on cloudflare, local, and mieweb. See Try it.

How a consuming app wires it in

  • import { DurableObject } from 'mieweb:workers' resolves via three coordinated aliases — tsconfig.json paths (typecheck), wrangler.jsonc alias (Cloudflare build), and the @mieweb/cloud/workers exports conditions (runtime). mieweb init writes the first two; they're an implementation detail you never edit.
  • wrangler.jsonc stays the source of truth for bindings/migrations/queues/DO tags. A small mieweb.jsonc sidecar adds only a target + non-Cloudflare adapter hints.
  • The mieweb CLI reads both and either shells out to wrangler (Cloudflare) or runs the local adapters.

Using the mieweb CLI

What the CLI is depends on where you point it. If you're targeting Cloudflare (or already know wrangler), think of it as a thin pass-through: every command is forwarded verbatim to wrangler, so there's nothing new to learn and zero overhead. On the other targets it is not a wrapper — there is no wrangler underneath; the CLI runs your unchanged worker on a Node host harness backed by the adapters, reusing your wrangler.jsonc purely as configuration. The active target comes from --target <t>, MIEWEB_TARGET, or the target field in mieweb.jsonc (default cloudflare).

# cloudflare (default): every command is forwarded verbatim to wrangler
mieweb dev
mieweb deploy
mieweb d1 migrations apply <db>

# local: run the unchanged worker on the Node host harness (SQLite/fs/memory/in-proc)
mieweb --target local d1 migrations apply <db>
mieweb --target local dev

# mieweb (os.mieweb.org): run it on libSQL + S3/MinIO + Valkey
mieweb --target mieweb dev

On cloudflare, behavior is identical to wrangler (zero overhead). On the local/mieweb targets the CLI imports the worker your wrangler.jsonc main points at, builds an Env from the mieweb.jsonc driver hints, and serves fetch/queue/scheduled over HTTP — the same handler Cloudflare runs.

Try it: the test app

packages/test-app is a worker whose routes each touch exactly one binding — D1, R2, KV, Queues, Durable Objects, Vectorize, AI — so a single set of HTTP assertions reads like a contract checklist. The cross-target runner boots that worker on each target and runs the same checks:

pnpm install

# one target at a time
pnpm --filter @mieweb/test-app check:local    # in-process Node adapters
pnpm --filter @mieweb/test-app check:docker   # mieweb/os: spins up libSQL+MinIO+Valkey
pnpm --filter @mieweb/test-app check:cf        # Cloudflare via `wrangler dev` (Miniflare)

# everything available (docker auto-skips without Docker, cf without wrangler)
pnpm --filter @mieweb/test-app check:all

Surfaces a target can't provide answer 501 { skipped: true } instead of failing (e.g. Workers AI needs a model backend; Cloudflare local dev can't reach Vectorize/AI without credentials), so one suite stays green everywhere. The local target also runs as a plain node --test under pnpm -r test.

Containers

Cloudflare Containers (DO-controlled Linux containers) are a reserved surface of the contract: CloudContainerNamespace / CloudContainerStub in @mieweb/cloud. App code uses the stock Cloudflare shape — a class MyContainer extends Container (from @cloudflare/containers) paired with a containers entry + DO binding in wrangler.jsonc — and stays target-agnostic.

Target Support
cloudflare ✅ native (wrangler dev / wrangler deploy, wrangler containers ssh for a shell)
local ⏳ planned — Docker-backed adapter; today a container binding throws UnsupportedBindingError on use
mieweb ⏳ planned — image distribution via skopeo → Harbor, cluster runtime TBD

See container-plan.md for the milestones, the skopeo/Harbor image pipeline, and the myapp walkthrough.

Status

0.x — published to npm as @mieweb/*; the API may change between minor versions. Cloudflare is fully supported; the local Node target and the mieweb (os.mieweb.org) target both cover D1, R2, KV, Queues, Durable Objects, and Vectorize, with Workers AI available when a model backend is configured. Every target is exercised by the test app and in CI.

License

MIT

About

Cloudflare-first portability layer (@mieweb/cloud): database, object storage, key/value, queues, durable objects, vector, AI. Other runtimes implement the same contract.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages