npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fusekit-cloud/fusekit_darwin_amd64

v0.2.2

Published

Fusekit CLI — deploy apps and manage Fusekit installations.

Downloads

571

Readme

Fusekit

Fusekit is an internal application platform that operates in two modes: a self-hosted single-tenant data plane inside a customer VPC, or a hosted multi-tenant cloud platform (fusekit.cloud). It deploys static web apps and provides those apps with authenticated user, Postgres document, object-file, and optional AI APIs.

# Log in (add --cloud flag for Fusekit Cloud)
fusekit login [--cloud]
fusekit deploy ./dist --app expenses

The resulting app is available at:

# Self-hosted mode:
https://expenses.apps.customer-company.internal

# Hosted cloud mode:
https://expenses.your-tenant.apps.fusekit.cloud

In self-hosted mode, Fusekit has no vendor-hosted control plane. Customer identity, metadata, application data, assets, and uploaded files remain inside customer infrastructure.

Documentation, SDK & AI tooling

Everything a developer needs to build on Fusekit is served under fusekit.cloud:

  • Docshttps://docs.fusekit.cloud (Mintlify site, source in web/docs/).
  • CLIcurl -fsSL https://fusekit.cloud/install | sh, or npx @fusekit-cloud/fusekit if you have Node (prebuilt binary from npm).
  • SDKnpm install @fusekit-cloud/sdk (or https://esm.sh/@fusekit-cloud/sdk).
  • MCP servernpx @fusekit-cloud/mcp lets AI agents (Claude Code, Cursor, Claude Desktop) scaffold, inspect, and deploy Fusekit apps. Source in mcp/.
  • AI skills — importable agent skills in skills/, downloadable at https://fusekit.cloud/skills/fusekit-app-builder.zip.

Architecture

Self-Hosted Mode

Browser
  -> customer wildcard DNS
  -> Caddy (strips headers, verifies session, adds X-Fusekit-Proxy-Secret)
  -> OAuth2 Proxy
  -> Fusekit Server
       -> PostgreSQL (pgx/Postgres)
       -> Go CDK blob bucket (s3:// / gs:// / azblob:// — one binary, any cloud)
       -> optional LiteLLM

Fusekit CLI
  -> bearer-token deploy API
  -> Fusekit Server

In self-hosted mode, Caddy removes user-supplied identity headers, verifies browser sessions through OAuth2 Proxy, copies verified identity headers, and adds X-Fusekit-Proxy-Secret. The CLI routes bypass browser SSO and use Authorization: Bearer <FUSEKIT_DEPLOY_TOKEN>.

The root of a self-hosted install is the employee launcher — a searchable home where every signed-in person sees the company's internal apps (name, description, owner, last updated) and opens them in one click. Inside the company everyone is trusted, so every member sees every deployed app; there are no per-app permissions. Admins manage apps from the console at /dashboard.

Hosted Cloud Mode (fusekit.cloud)

Browser
  -> wildcard DNS (*.apps.fusekit.cloud + fusekit.cloud)
  -> Caddy / Cloudflare load balancer
  -> Stateless Fusekit Server pool (verifies GoTrue JWTs, maps tenant)
       -> Supabase (Database, Auth, and Storage/S3-compatible API)
       -> optional LiteLLM

Fusekit CLI (fusekit login --cloud)
  -> token-based deploy API (X-Fusekit-Org + Bearer token)
  -> Fusekit Server pool

In cloud mode, Fusekit bypasses the external OAuth2 Proxy and validates browser sessions and API calls using Supabase Auth (GoTrue JWTs) (via the Authorization: Bearer header or first-party fusekit_session cookie). Request paths resolve tenant scoping dynamically from host headers, which are mapped to orgs in Postgres.

Repository

cmd/fusekit-server/      Go HTTP server (supports both self-hosted and cloud modes)
cmd/fusekit/             Go CLI
internal/                auth, deploy, DB, storage, audit, AI, limits, tenant, and realtime packages
migrations/              embedded SQL migrations (001_initial … 006_custom_domains)
sdk/                     @fusekit-cloud/sdk
web/admin/               React/Vite admin console (includes cloud control panel features)
examples/hello-react/    example Fusekit application
examples/api-conformance/ deployable smoke test exercising every feature API
deploy/                  Compose, Caddy, OAuth2 Proxy, MinIO, LiteLLM config, Docker Cloud config, Helm chart

Roles and Placements

One binary serves every placement, selected by FUSEKIT_ROLE (see docs/ARCHITECTURE.md):

  • FUSEKIT_ROLE=all — control plane + shared multi-tenant runtime in one stateless pool (Fusekit Cloud).
  • FUSEKIT_ROLE=runtime — the portable single-tenant runtime, in two sub-modes:
    • disconnected (classic self-hosted): license key, static deploy token, no control-plane dependency;
    • connected BYOC: set FUSEKIT_CONTROL_PLANE_URL=https://fusekit.cloud and FUSEKIT_RUNTIME_TOKEN=frt_... (created in the cloud console under Runtimes). The runtime registers on boot, heartbeats aggregate health/usage outbound-only, and accepts short-lived signed deploy tokens minted by the control plane. App data never leaves the runtime, and it keeps serving if fusekit.cloud is unreachable.

FUSEKIT_MODE remains a backward-compatible alias (cloudall, self-hostedruntime).

Deploy routing

fusekit deploy asks the control plane where the workspace's runtime lives (POST /api/deploy/target), receives {deployment_mode, runtime_url, base_domain, deploy_token} with a 10-minute Ed25519-signed deploy token, and uploads the bundle directly to that runtime. Servers without the endpoint (disconnected self-hosted) are deployed to directly with the configured static token. Multi-instance cloud pools must share FUSEKIT_DEPLOY_TOKEN_SIGNING_KEY (base64url 32-byte Ed25519 seed); verification keys are published at GET /api/cp/jwks.

Local Development

Fusekit can be run in one of two modes, selected via the FUSEKIT_MODE environment variable:

  • self-hosted (default): Runs the single-tenant server using OAuth2 Proxy headers and local database configuration.
  • cloud: Runs the multi-tenant hosted SaaS server using Supabase for database, authentication, and object storage.

Requirements:

  • Docker Desktop with Compose
  • Node.js 20 or newer
  • Go 1.25 or newer when building the CLI outside Docker

Start the development stack:

  • To run in self-hosted mode:

    make dev-self-hosted
  • To run in cloud (multi-tenant SaaS) mode:

    1. Configure your Supabase project credentials in deploy/.env.cloud (which is copied from deploy/.env.cloud.example automatically on first run).
    2. Start the stack:
    make dev-cloud

Open http://localhost:8080. The development Caddy configuration uses a fixed identity:

[email protected]
groups: admin

Do not use development identity mode in production. It is available only when FUSEKIT_DEV_MODE=true, validates the internal proxy secret, and is intended solely to make the local stack runnable without an external IdP.

For the lowest-friction path, use the CLI wizard instead of editing Compose files. This is the same arc as a real install, with a local developer identity standing in for SSO:

fusekit setup --dev --dir ./fusekit-install   # generate (no DNS/IdP needed in dev)
fusekit install --install-dir ./fusekit-install
fusekit doctor --install-dir ./fusekit-install
fusekit init myapp                             # scaffold a starter app
fusekit deploy ./myapp --app myapp             # open http://myapp.localhost:8080

Build the CLI and example:

mkdir -p bin
go build -o bin/fusekit ./cmd/fusekit
npm install
npm run build

Configure and deploy (Self-Hosted):

bin/fusekit login \
  --server http://localhost:8080 \
  --token dev-deploy-token-change-me

bin/fusekit deploy examples/hello-react/dist --app hello

Open http://hello.localhost:8080. If the local resolver does not map subdomains of localhost automatically, add hello.localhost to /etc/hosts or use a local DNS resolver.

Configure and deploy (Hosted Cloud):

# Log in to local cloud dev server (or omit --server to log in to production fusekit.cloud)
bin/fusekit login --server http://localhost:8080 --token <your-deploy-token>
# Or log in to production
bin/fusekit login --cloud

bin/fusekit deploy examples/hello-react/dist --app hello

The MinIO console is available at http://localhost:9001 in development. Credentials come from AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

Conformance test (every feature API, any target)

examples/api-conformance is a one-page app that exercises every Fusekit feature API — auth, document DB, DB realtime, file storage, AI, and realtime rooms — and reports pass / warn / fail per feature. scripts/conformance.sh (wrapped by make) builds the CLI, builds the app, brings up (or points at) the right stack, deploys the app, and prints the URL to open and hit Run all checks:

# Local, self-hosted single-tenant runtime (non-managed). Fully automatic:
# brings the stack up, deploys, signs you in as the dev identity.
make test-local-self-hosted          # add FLAGS=--open to auto-open the browser

# Local, managed multi-tenant mode (needs Supabase creds in deploy/.env.cloud).
make test-local-managed

# Managed production fusekit.cloud (device-flow login).
make test-cloud TENANT=<your-tenant>

make test-down                       # tear the local stack down

Run scripts/conformance.sh --help for flags (--open, --no-build) and env overrides (APP, TENANT, SERVER, TOKEN). Each check writes only to throwaway collections / files and cleans up after itself.

Self-Host Quickstart (≈15 minutes)

From nothing to a shared internal app, in one arc. Each command prints the next one, so you can follow the CLI alone.

0. Install the CLI

curl -fsSL https://fusekit.cloud/install | sh

The install script is served by fusekit-server (GET /install): it detects your OS and CPU architecture, downloads the matching GitHub release, verifies its SHA-256 checksum, and installs only the fusekit binary.

1. Generate the installationfusekit setup

fusekit setup --dir /opt/fusekit

The wizard asks for your domain, identity provider (Microsoft Entra ID, Okta, Google Workspace, or generic OIDC), and object storage, then generates every secret, writes a private .env and Compose bundle, calculates the exact OIDC callback URL, saves your CLI deploy credentials, and prints the exact DNS records to create. It spells out both the apex (apps.company.internal) and wildcard (*.apps.company.internal) A/AAAA records pointing at this host, and calls out that one TLS certificate must cover both names (a single wildcard cert) — a cert for only the apex loads the launcher but breaks every app. Finish SSO using the generated sso-setup-instructions.md.

If you already hold a wildcard certificate (common with an internal CA), pass it to setup and it wires it straight into Caddy — no Caddyfile editing:

fusekit setup --dir /opt/fusekit --tls-cert wildcard.crt --tls-key wildcard.key

Setup verifies the cert actually covers *.apps.company.internal (rejecting an apex-only cert up front), copies it to tls/ in the install, mounts it read-only, and adds the tls directive. Omit the flags to keep Caddy's automatic HTTPS — but note public ACME cannot issue for private .internal names, so internal deployments should supply a cert or configure a DNS-01 challenge.

2. Start itfusekit install

fusekit install --install-dir /opt/fusekit

Runs a preflight, brings up the stack, waits for readiness, and prints Fusekit is live at https://….

3. Confirm it's healthyfusekit doctor

fusekit doctor --install-dir /opt/fusekit

doctor checks Docker and Compose, configuration and placeholder secrets, the SSO client and Compose profile, the referenced Caddyfile, health/readiness, and — because every app is served from its own subdomain — DNS and TLS specifically for subdomain routing: that the apex resolves, that *.{base} resolves to the same host (not just anything), and that the certificate actually covers app hosts (*.{base}), not only the apex. The last check catches the silent failure where the launcher loads but every app fails its TLS handshake. When a wildcard cert was supplied to setup (FUSEKIT_TLS_CERT_FILE is set), the apex TLS check verifies the certificate's names and expiry rather than its chain — an internal CA the doctor host doesn't trust is fine, since client devices trust it. Each failure prints an exact fix on its line; re-run until it's all green.

4. Ship your first appfusekit init + fusekit deploy

fusekit init myapp                    # scaffolds a zero-build starter app
fusekit deploy ./myapp --app myapp    # uploads it

init writes a single self-contained index.html (no npm, no build step) that already uses SSO identity and the shared database. deploy prints Your app is live at https://myapp.apps.company.internal.

Prefer the browser? Open the console and use Fusekit Drop — drag any folder of HTML/files (no build needed) and it deploys through the same pipeline. A folder with an index.html at its root is served as the site directly.

5. Open it via SSO and share it

Open the printed URL — your IdP signs you in — and send the link to a teammate. They sign in with the same SSO and see the same live list. That's the whole loop.

For automation, every setup prompt has a flag:

fusekit setup \
  --non-interactive \
  --dir /opt/fusekit \
  --domain apps.company.internal \
  --provider entra \
  --issuer-url https://login.microsoftonline.com/TENANT_ID/v2.0 \
  --client-id CLIENT_ID \
  --client-secret CLIENT_SECRET \
  --admin-groups platform-admins \
  --storage bucket \
  --bucket-url gs://company-fusekit

The bucket preset takes any Go CDK bucket URL (s3:// for AWS/MinIO/R2, gs://, or azblob://), so this command targets any cloud by changing only the URL.

Installation reference

DNS. Create two records; no per-app changes are ever required:

apps.customer-company.internal   -> Caddy or customer load balancer
*.apps.customer-company.internal -> Caddy or customer load balancer

TLS. For private internal domains, provide a wildcard certificate from the customer internal CA — pass it to fusekit setup --tls-cert/--tls-key and it is validated (must cover *.{domain}), copied into tls/, and mounted into Caddy automatically. For public domains, use ACME with a DNS challenge — public HTTP ACME cannot be assumed to work for private .internal names. Local TLS testing can use mkcert. Either way fusekit doctor confirms the served certificate actually covers app hosts before you ship.

Production OIDC (setup writes these; fill in any [configure-later-…] placeholders, which doctor flags):

FUSEKIT_DEV_MODE=false
FUSEKIT_CADDYFILE=./Caddyfile
OAUTH2_PROXY_PROVIDER=oidc
OAUTH2_PROXY_OIDC_ISSUER_URL=https://idp.customer.example
OAUTH2_PROXY_CLIENT_ID=...
OAUTH2_PROXY_CLIENT_SECRET=...
OAUTH2_PROXY_COOKIE_SECRET=...

Use deploy/Caddyfile, not deploy/Caddyfile.dev, in production. Configure OAuth2 Proxy group claims for the selected provider and set the admin groups:

FUSEKIT_ADMIN_GROUPS=platform-admins,security-admins

Only users in one of those exact groups can call /admin/api/* or perform destructive browser admin actions. All authenticated employees can access deployed applications and their own app's runtime APIs.

doctor also serves CI and cloud installs: --json emits machine-readable results; in cloud mode it probes nested wildcard DNS ({app}.{tenant}.{base}), and --app-host {app}.{tenant}.{base} verifies a real deployed host resolves and serves a valid certificate (on-demand TLS issuance succeeded).

Hosted Multi-Tenant SaaS Mode (Fusekit Cloud)

Hosted mode (FUSEKIT_MODE=cloud) turns Fusekit into a multi-tenant application platform powered by Supabase.

Core Tenancy Architecture

  • Tenant Isolation: Achieved using org_id columns in the database. Requests are scoped automatically via the Go query-layer. Row-level security (RLS) is deferred in the database layer.
  • Default Organization: A well-known default organization (00000000-0000-0000-0000-000000000001) is automatically seeded. Self-hosted deployments backfill into this organization, allowing seamless upgrade paths.
  • Hostname Scheme: Apps are served at {app_slug}.{tenant_slug}.apps.fusekit.cloud (the app is a child label of the tenant). These two-label-deep hosts fall outside the single-label *.apps.fusekit.cloud wildcard cert, so they receive per-host certificates via Caddy on-demand TLS, gated by /internal/tls-allowed. Verified custom domains serve the same apps at {app_slug}.{custom_domain}.
  • Cloud Limits: Cloud mode skips license verification; organizations are bound to plans (e.g., free, unlimited) configured in the plans table which restrict max_apps, max_members, max_storage_bytes, and max_upload_bytes.

Cloud Configuration

To run the server in cloud mode, set the following environment variables:

FUSEKIT_MODE=cloud
FUSEKIT_CLOUD_ROOT_DOMAIN=fusekit.cloud
FUSEKIT_PUBLIC_BASE_DOMAIN=apps.fusekit.cloud
FUSEKIT_DATABASE_URL=postgresql://postgres:[email protected]:6543/postgres?pgbouncer=true
FUSEKIT_LISTEN_DATABASE_URL=postgresql://postgres:[email protected]:5432/postgres
FUSEKIT_BLOB_BUCKET_URL=s3://fusekit?endpoint=https://xxx.storage.supabase.co/storage/v1/s3&use_path_style=true
FUSEKIT_SUPABASE_URL=https://xxx.supabase.co
FUSEKIT_SUPABASE_PUBLISHABLE_KEY=eyJhbGci...
# Secret Key or JWKS URL to verify incoming GoTrue JWTs (JWKS is auto-inferred if not specified)
FUSEKIT_SUPABASE_SECRET_KEY=your-secret-key

[!NOTE] FUSEKIT_LISTEN_DATABASE_URL is required because PgBouncer in transaction mode does not support Postgres LISTEN. It should connect directly to the database rather than the pooler port.

Cloud Control-Plane API

When FUSEKIT_MODE=cloud is active, the following API endpoints are registered for tenant onboarding and management:

  • GET /api/cloud/config: Public configuration endpoint (used by the admin console to detect cloud mode).
  • GET /api/orgs / POST /api/orgs: List user's organizations and create new ones.
  • GET/POST/DELETE /api/orgs/{org_slug}/deploy-tokens: List, create, and revoke deploy tokens.
  • GET/POST/PATCH/DELETE /api/orgs/{org_slug}/members: List and manage members (owner, admin, member).
  • POST /api/deploy/target: Resolve the workspace's runtime and mint a short-lived signed deploy token (CLI).
  • GET /api/cp/jwks: Deploy-token verification keys for runtimes.
  • POST /api/cp/runtimes/register / POST /api/cp/runtimes/heartbeat: Connected-runtime registration and health (authenticated by frt_ runtime tokens).
  • GET/POST/DELETE /api/orgs/{org_slug}/runtimes: Manage BYOC runtime registrations.
  • GET/POST/DELETE /api/orgs/{org_slug}/domains and POST .../domains/{id}/verify: Customer wildcard domains with _fusekit-verify TXT verification.
  • GET /internal/tls-allowed?domain=: Caddy on-demand TLS gate; approves only verified custom-domain hosts.

Custom Domains

Verified orgs can serve apps from their own wildcard domain. Add apps.acme.com in the console, create the _fusekit-verify.apps.acme.com TXT record, point *.apps.acme.com at the Fusekit edge with a CNAME, and apps resolve at https://expenses.apps.acme.com. Certificates are issued per host via Caddy on-demand TLS (deploy/Caddyfile.cloud).

Authentication on custom domains is transparent: the first HTML navigation bounces through https://fusekit.cloud/auth/gateway (one redirect; shows the login page if there is no fusekit.cloud session), returns to /__fusekit/callback on the app host with a 60-second single-hop signed code, and sets a first-party fusekit_app_session cookie (12h, Ed25519-signed, scoped to the customer base domain so one login covers all apps on it). Membership is re-checked on every request, so removing a member takes effect within seconds, not at session expiry. When the session expires, the next navigation silently re-runs the redirect. GET /__fusekit/logout clears the cookie. No SDK or app-code changes are required; Authorization: Bearer continues to work for non-browser clients.

CLI Cloud Support

Log in to Fusekit Cloud by passing the --cloud flag:

fusekit login --cloud
fusekit deploy ./dist --app expenses --workspace acme

This will automatically configure the CLI to target https://fusekit.cloud and prompt for a developer token. --workspace is validated against the token's organization; deploys are routed to the workspace's runtime (shared cloud pool or a connected BYOC runtime) via POST /api/deploy/target.

Use the whoami command to inspect your organization role and plan limits:

fusekit whoami
# Output: deploy-token in organization Acme Inc. (acme) on https://fusekit.cloud

Object Storage

Fusekit opens storage through Go CDK:

blob.OpenBucket(ctx, bucketURL)

The binary includes the S3, GCS, and Azure drivers. MinIO and other S3-compatible services work with:

FUSEKIT_BLOB_BUCKET_URL=s3://fusekit-assets?endpoint=http://minio:9000&disableSSL=true&s3ForcePathStyle=true

Fusekit normalizes the legacy disableSSL option to Go CDK's current disable_https parameter. Production examples:

# AWS S3
FUSEKIT_BLOB_BUCKET_URL=s3://customer-fusekit-bucket

# MinIO or another S3-compatible service
FUSEKIT_BLOB_BUCKET_URL=s3://fusekit-assets?endpoint=https://minio.customer.internal&s3ForcePathStyle=true

# Google Cloud Storage
FUSEKIT_BLOB_BUCKET_URL=gs://customer-fusekit-bucket

# Azure Blob
FUSEKIT_BLOB_BUCKET_URL=azblob://customer-fusekit-container

GCS and Azure use the same ObjectStore interface and are compiled into the binary, so switching clouds is a FUSEKIT_BLOB_BUCKET_URL change, not a rebuild.

All deployed assets and runtime files are stored under portable logical keys.

In self-hosted mode:

apps/{app_slug}/versions/{version_id}/...
files/{app_slug}/{file_id}/{filename}

In cloud mode:

tenants/{org_id}/apps/{app_slug}/versions/{version_id}/...
tenants/{org_id}/files/{app_slug}/{file_id}/{filename}

Fusekit never stores deployed bundles or uploaded files on local disk.

Browser SDK

Install from npm (or load from a CDN with import { fusekit } from "https://esm.sh/@fusekit-cloud/sdk"):

npm install @fusekit-cloud/sdk
import { fusekit } from "@fusekit-cloud/sdk";

const user = await fusekit.user();

const task = await fusekit.db.collection("tasks").create({
  title: "Review invoices",
  done: false,
});

await fusekit.db.collection("tasks").update(task.id, { done: true });

const uploaded = await fusekit.files.upload(file);

const response = await fusekit.ai.chat({
  model: "gpt-4o-mini",
  messages: [{ role: "user", content: "Summarize this" }],
});

The SDK infers the app slug and tenant slug from the current hostname (handling both app.domain and app.tenant.domain automatically) and sends credentialed same-origin requests. Tests and non-browser clients can configure it explicitly:

fusekit.configure({
  app: "expenses",
  tenant: "acme", // Optional tenant override
  baseUrl: "https://expenses.acme.apps.fusekit.cloud",
});

Realtime

Fusekit supports server-mediated realtime record subscriptions in both self-hosted and cloud modes using PostgreSQL LISTEN/NOTIFY and Server-Sent Events (SSE).

How it works

  1. An AFTER INSERT OR UPDATE OR DELETE trigger on the records table calls pg_notify('fusekit_records', payload).
  2. The payload contains only the record ID, collection, organization, and action type (to respect the 8KB payload limit).
  3. The Fusekit Server runs a background listener hub (PostgresHub) on FUSEKIT_LISTEN_DATABASE_URL.
  4. When a browser client subscribes, it opens an EventSource connection at GET /runtime/{app}/db/{collection}/subscribe.
  5. The server fans out notifications to subscribers, and the SDK automatically refetches updated records before invoking user handlers.

SDK Usage

To subscribe to realtime collection events:

const unsubscribe = fusekit.db.collection("tasks").subscribe((change) => {
  if (change.op === "insert") {
    console.log("New task created:", change.record);
  } else if (change.op === "update") {
    console.log("Task updated:", change.record);
  } else if (change.op === "delete") {
    console.log("Task deleted, ID:", change.recordId);
  }
}, {
  events: ["insert", "update", "delete"] // Optional: filter events
});

// To stop listening:
unsubscribe();

Broadcast and presence

App-scoped rooms ride the same Postgres NOTIFY bus (POST /runtime/{app}/realtime/broadcast + SSE at GET /runtime/{app}/realtime/subscribe?room=), so they work identically in every placement. Payloads are capped at 4KB. Channels are structured server-side (app + kind + room); cross-app channels cannot be expressed.

const room = fusekit.realtime.room("document-123");
const stop = room.subscribe((message) => console.log(message.event, message.payload, message.sender));
await room.broadcast("cursor.move", { x: 10, y: 20 });

const presence = fusekit.realtime.presence("document-123", (members) => {
  console.log("online:", members.map((member) => member.sender));
});
presence.leave();

AI

AI is disabled by default:

FUSEKIT_AI_ENABLED=false

Enable the optional Compose profile and OpenAI-compatible LiteLLM proxy:

docker compose -f deploy/docker-compose.yml --profile ai up --build

Set FUSEKIT_AI_API_KEY if LiteLLM requires a master key. Provider credentials remain server-side. Fusekit records returned token usage in Postgres.

Security Notes

The full security brief — trust model, HTTP posture, fail-closed defaults, and vulnerability reporting — is in SECURITY.md. Highlights:

  • Every response carries baseline hardening headers (X-Content-Type-Options: nosniff, X-Frame-Options, Referrer-Policy, Cross-Origin-Opener-Policy, a per-surface CSP, and HSTS when the public scheme is HTTPS) with zero tuning — see internal/httpapi/security.go.
  • CORS is closed by default: the SDK is same-origin, so no Access-Control-Allow-Origin header is ever emitted and browsers block cross-origin reads.
  • In production self-hosted mode the server fails closed on weak shared secrets: FUSEKIT_INTERNAL_PROXY_SECRET and FUSEKIT_DEPLOY_TOKEN must be at least 16 characters.
  • Shared secrets are compared in constant time; tokens, keys, and connection strings are never logged or returned.
  • Do not expose fusekit-server directly. Only Caddy should receive public or employee traffic.
  • Browser identity headers are trusted only when the internal proxy secret is valid.
  • Caddy removes incoming identity and proxy-secret headers before authentication.
  • Runtime API app slugs must match the request subdomain, preventing cross-app data access.
  • Browser admin APIs require configured SSO group membership.
  • CLI deploy/admin APIs use a static bearer token for the MVP. Replace this with OIDC device authorization later.
  • Deployment archives reject absolute paths, traversal, symlinks, hardlinks, special files, excessive file counts, and excessive expanded size.
  • App assets and uploaded files live only in the configured Go CDK bucket.
  • Keep database, MinIO, OAuth2 Proxy, and Fusekit Server on private networks.
  • Rotate FUSEKIT_INTERNAL_PROXY_SECRET, FUSEKIT_DEPLOY_TOKEN, database credentials, MinIO credentials, and OAuth cookie secrets before production use.

Validation

go test ./...
go vet ./...
npm test
npm run build
docker compose -f deploy/docker-compose.yml config
docker compose -f deploy/docker-compose.yml up --build

Operations

Generated installations include backup and restore scripts, exposed through the CLI:

fusekit backup --install-dir /opt/fusekit
fusekit restore --install-dir /opt/fusekit /secure/backups/20260611T120000Z

Backups contain a PostgreSQL custom-format dump, the complete object bucket, and installation configuration.

Upgrades always take a backup first:

fusekit upgrade --install-dir /opt/fusekit --version v0.2.0

The command updates the image tag, creates a timestamped pre-upgrade backup, pulls images, runs the embedded database migrations during startup, and recreates services.

The Go tests cover authentication, wildcard-domain parsing, cross-app runtime rejection, cache policy, tar traversal and link rejection, and the Go CDK object lifecycle. Compose provides the Postgres and MinIO dependencies for end-to-end deployment and runtime checks.

API conformance smoke test

examples/api-conformance/ is a single deployable app that exercises every feature API the SDK exposes — identity (fusekit.user()), document CRUD, database realtime subscriptions, file storage, AI chat, and realtime broadcast/presence — and reports per-API pass/warn/fail with the assertions and latency for each step. Deploy it to any tenant to confirm a release behaves on that tenant:

npm run build --workspace @fusekit-cloud/api-conformance
fusekit deploy examples/api-conformance/dist --app conformance --workspace <tenant>

Open the app and click Run all checks. Green means the feature works on that tenant; warnings flag optional features that are disabled (e.g. AI). Each check writes only to throwaway __conformance* collections / files and cleans up after itself. For local testing against a remote tenant without deploying, pass ?app=&tenant=&baseUrl= query params to point the SDK at a host.

MVP Boundaries

Not included:

  • BYOC Provisioning: Connected BYOC runtimes register and heartbeat against the control plane, but Fusekit does not provision infrastructure into customer cloud accounts (Terraform/CloudFormation); customers run the existing Compose bundle.
  • Postgres Row-Level Security (RLS): Scoping is currently handled at the query layer via org_id parameters. RLS will be added in a future phase to unlock direct browser-to-Supabase Realtime connectivity.
  • Billing & Payments: The database contains a plans table to enforce limits, but integration with a billing provider (e.g., Stripe) is out of scope.
  • Other: Kubernetes operator, KOTS or air-gap packaging, direct-to-bucket uploads, STS credential vending, or complex RBAC.