Functions

The core building block — a handler that receives a Request and returns a Response.

Functions

A Cluster function is a JavaScript or TypeScript module that exports a handler function. It receives a standard Request and returns a Response.

Basic Handler

export function handler(request: Request): Response {
  return new Response("Hello from Cluster!");
}

Async Handler

Handlers can be async — use await for fetch() calls, crypto operations, or any async work:

export async function handler(request: Request): Promise<Response> {
  const data = await fetch("https://api.example.com/data");
  const json = await data.json();
  return Response.json(json);
}

Routing

Route matching is done in your handler code using the URL and Request APIs:

export async function handler(request: Request): Promise<Response> {
  const url = new URL(request.url);

  if (url.pathname === "/api/hello" && request.method === "GET") {
    return Response.json({ message: "Hello!" });
  }

  if (url.pathname === "/api/time") {
    return Response.json({ time: new Date().toISOString() });
  }

  return Response.json({ error: "Not found" }, { status: 404 });
}

You can also use URLPattern for more complex routing:

const pattern = new URLPattern({ pathname: "/users/:id" });

export function handler(request: Request): Response {
  const match = pattern.exec(request.url);
  if (match) {
    const userId = match.pathname.groups.id;
    return Response.json({ userId });
  }
  return new Response("Not found", { status: 404 });
}

Environment Variables

Access environment variables via process.env:

export function handler(request: Request): Response {
  const apiKey = process.env.API_KEY;
  return new Response(`Key starts with: ${apiKey?.slice(0, 4)}...`);
}

See Environment Variables for how to set them.

Organizations

Functions belong to organizations. When you first deploy or run ccp init, you select which organization to deploy to. A single organization can have many functions.

Managing Functions

# Context-aware listing:
#   inside a linked project  -> that function's deployments
#   outside one              -> every function in the organization
ccp list        # or: ccp ls
ccp ls --org-id <org>   # outside a project: choose the org explicitly

# Delete the linked function
ccp remove      # or: ccp rm

# Link current directory to an existing function
ccp link

ccp ls adapts to where you run it, the same way ccp compute ls does:

  • Inside a linked project (a .cluster/config.json with a function_id) it lists that function's deployments, headed Deployments for <org>/<function>.
  • Outside a project it lists every serverless function in the organization — name, canonical URL (shown only once a function has a live production deployment), custom domains, cron, and last update — headed Functions in <org>. The organization is resolved from --org-id, then the project config, then the CCP_ORG_ID env var, then an interactive picker (auto-selected when you belong to a single org; in headless/non-interactive mode with multiple orgs and no --org-id or CCP_ORG_ID, it errors rather than prompting).

Reading Logs

ccp logs prints a deployed function's logs — its runtime console.* output — the serverless counterpart to ccp compute logs:

ccp logs [FUNCTION_ID] [-n LIMIT] [--level info,warn,error] [--deployment DEP_ID] [-f]
  • FUNCTION_ID falls back to the current directory's .cluster/config.json, the same resolution as the other function-scoped commands. Pass it explicitly to read logs from outside a linked project.
  • -n / --limit — number of most recent lines to print. Default 100, max 1000 (clamped client-side with a warning).
  • --level — comma-separated level filter: info, warn, error, debug.
  • --deployment — restrict to a single deployment id.
  • -f / --follow — stream new lines as they arrive until you press Ctrl-C.

Output is one plain line per entry — <iso-8601-utc> <LEVEL> <message>, with no colors or decoration, so it pipes cleanly into grep. The snapshot returns the newest LIMIT lines.

ccp logs                      # last 100 lines for the linked function
ccp logs -n 50 --level error  # last 50 error lines
ccp logs <FUNCTION_ID>        # from outside the project dir
ccp logs -f                   # live tail

If the function can't be found you get a single actionable line pointing at ccp ls; an expired session points at ccp auth login.

What's Not Available

Cluster runs V8 isolates, not Node.js. There are no Node.js built-in modules:

  • No fs, path, os, child_process, net, http
  • No Buffer (use Uint8Array and TextEncoder)
  • No require() (use ES modules — the bundler handles modules for you)

Use fetch() for HTTP requests to external services. See the full Runtime API reference.

On this page