> ## Documentation Index
> Fetch the complete documentation index at: https://archie.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Writing Custom Functions

> Author server-side logic for your app.

This page covers authoring custom functions — the editor, the function signature, and the patterns that work well.

## Where you write

* **In-project IDE** — open **Backend → Custom functions** and use the built-in editor
* **Local development** — pull the project via [GitHub integration](/features/github/connecting), edit in your local IDE, push back

Both produce the same result. Local development is better for substantial logic; the in-project IDE is faster for small handlers.

## Function signature

A standard HTTP-triggered function in TypeScript looks like:

```typescript theme={null}
export async function handler(req: Request, ctx: Context): Promise<Response> {
  const body = await req.json()
  // ... your logic
  return Response.json({ ok: true })
}
```

The `ctx` object exposes auth, environment, and helpers (database, integration clients, logger).

## Patterns

* **Validate input** — never trust caller-provided data; use a schema validator
* **Use the integration clients** — `ctx.integrations.stripe`, `ctx.integrations.sendgrid`, and so on, are pre-configured with credentials
* **Return early on errors** — surface clear status codes and JSON error bodies
* **Keep functions focused** — one function per logical task; compose for workflows
* **Log structurally** — `ctx.logger.info({ event: "checkout-started", userId })`

## Triggers

* **HTTP** — exposed at `/api/functions/<name>`
* **Scheduled** — cron expression, runs at the configured interval
* **Webhook** — exposed under `/api/webhooks/<name>`, with signature verification
* **Queue** — invoked when a message lands in the configured queue

## Testing

Unit-test handlers like normal Node code. Use the integration mocks Archie ships for integration calls. End-to-end tests can run against the preview environment.

## FAQ

<AccordionGroup>
  <Accordion title="Can I import npm packages?">
    Yes, with the standard package.json. The build step installs dependencies.
  </Accordion>

  <Accordion title="How do I share code between functions?">
    Put shared code in `lib/` or a workspace package and import it from each function.
  </Accordion>
</AccordionGroup>
