Skip to main content
Cargo hosts two kinds of custom code alongside your resources: workers (serverless edge HTTP handlers) and apps (Vite single-page apps served on *.cargo.app). defineWorker and defineApp deploy a source bundle directory that Cargo Hosting builds on deploy.

Define a worker

workers/webhook.ts
import { defineWorker } from "@cargo-ai/cdk";

// bundle root needs: manifest.json + package.json + package-lock.json,
// plus a TS entry `src/index.ts` (or a pre-built `index.js`)
export const webhook = defineWorker("webhook", {
  path: new URL("./webhook", import.meta.url).pathname,
});

Define an app

apps/dashboard.ts
import { defineApp } from "@cargo-ai/cdk";

// bundle root needs: index.html + package.json + package-lock.json (a Vite app)
export const dashboard = defineApp("dashboard", {
  path: new URL("./dashboard", import.meta.url).pathname,
});
The CDK validates the required bundle files exist at define time, so a missing file fails in plan.
defineWorker/defineApp are the deployable resource (the hosted slot). Author the worker’s runtime code in TypeScript with createWorker from @cargo-ai/worker-sdk at src/index.ts — bundles are uploaded as source and built server-side: the hosting build runs npm ci then esbuilds the worker entrypoint (esbuild transpiles TypeScript natively) or vite build for apps. A pre-built index.js at the bundle root is still accepted for backwards compatibility. Bundle sub-directories have their own package.json, so the loader treats them as content to upload, not resource files to import.

Scaffolding and deploying standalone

You can also scaffold and ship bundles directly with the CLI:
cargo-ai hosting app init my-app          # scaffold a Vite app
cargo-ai hosting worker init my-worker    # scaffold an edge worker
cargo-ai hosting deployment create --app-uuid <uuid> --source .
cargo-ai hosting deployment promote --uuid <deployment-uuid>
Slugs are kebab-case and must start with a letter (my-worker).