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
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
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).