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

# Reintersect-hosted apps

> Deploy with one command and let Reintersect run your app on Cloudflare Workers, with an outbound allowlist and no credentials in your code.

> Reintersect apps are in developer preview. Names and limits can still change before general
> release.

Hosted apps are the default. You export `app`, run `reintersect deploy`, and Reintersect builds your
code into a bundle and runs it in Cloudflare Workers isolates. There is no server to operate, no
endpoint to expose and no install token to store.

## Deploy

```bash theme={null}
npx reintersect deploy --app app_123
npx reintersect deploy --preview
```

The CLI reads your app, bundles it for Workers (`reintersect build --target workerd`, conditions
`workerd`, `worker` and `browser`, at most 10 MB) and uploads the bundle with the manifest. Each deploy
creates an immutable version. A production version is published right away; whether existing
installs move to it depends on the access it asks for. See
[Publishing new versions](/concepts/install-and-consent#publishing-new-versions).

`--preview` without `--app` deploys to your personal development app, creating it if needed. Previews
run only on development installs; see [Previews and versions](/hosting/previews).

Run `reintersect check` before you deploy, or let the [GitHub Action](/ci) run it for you; deploy
itself doesn't run the checks.

### Rolling back

Every version stays available. To roll back, open **Settings → Developer → Apps → your app →
Versions** and pick **Roll back** on an earlier version. Reintersect deploys it again and moves
installs to it, except installs that would need to approve new access.

## The runtime

Your code runs in a Workers isolate with `nodejs_compat` enabled. The SDK pins the compatibility date
(currently `2026-10-01`), so a runtime update never changes your app's behaviour until you upgrade the
SDK.

Write against web-standard APIs: `fetch`, `Request`, `Response`, `URL`, Web Crypto, streams and
timers. These aren't available:

| Not available | Use instead |
| - | - |
| `Bun.*`, `Deno.*` | Web-standard APIs |
| `node:fs` and other file system access | Block state, or your own storage service over HTTPS |
| Native addons | Pure JavaScript or WebAssembly packages |
| Raw TCP sockets | HTTPS APIs |

Handlers are stateless. Don't keep data in module scope between requests: each call may run in a
fresh isolate. Persist what you need in block state, which Reintersect stores, or in your own
service.

To finish work after responding, pass a promise to `waitUntil` from the handler context. The response
goes back to Reintersect immediately and the isolate stays alive until the promise settles. See
[Long-running work](/blocks/state-and-actions#long-running-work).

## Outbound requests

Hosted apps can only call the hosts they declare in `egress`:

```ts theme={null}
export const app = createReintersectApp({
  name: "Launchpad",
  slug: "launchpad",
  egress: ["api.vercel.com", "*.linear.app"],
});
```

Every outbound request passes through Reintersect's egress gateway:

* Only `https` on the default port, without credentials in the URL.
* Only hosts in `egress` (a `*.` entry covers every subdomain) and the Reintersect API.
* Never private, loopback, link-local or cloud metadata addresses, whatever a name resolves to.
* Redirects aren't followed for you across the allowlist: a redirect to a host outside `egress`
  fails.
* Hosts under `reintersect.com` and `reintersect.app` can't be listed; the manifest sync refuses
  them with `reserved-domain`.

The consent screen shows admins the outbound hosts, and adding a host counts as wider access when you
publish a new version.

<Note>
  Outbound requests from hosted apps leave from shared Cloudflare addresses. Third-party APIs that only
  accept requests from an IP allowlist won't work from a hosted app. Self-host the app if you need a
  fixed address.
</Note>

## Credentials

The egress gateway sets the token on every call a hosted app makes to the Reintersect API. Inside a
delivery, it replaces the token the handler's `reintersect` client sends with one it issues for the
delivery's install. `reintersect.forInstall(installId)` sends no token, and the gateway adds one for
that install. In both cases the gateway first checks that the install belongs to your app, is active
and runs the version making the call (a preview counts only on a development install), and the token
carries the install's scopes. The SDK doesn't give your handlers the delivery's install token.

Reintersect binds these to your Worker; you can't override them:

| Binding | Value |
| - | - |
| `REINTERSECT_BASE_URL` | The Reintersect API origin. |
| `REINTERSECT_APP_CLIENT_ID` | Your app's client ID. |
| `REINTERSECT_APP_SIGNING_SECRET` | The secret the SDK verifies deliveries with (a derived secret on previews). |
| `REINTERSECT_HOSTED` | `1`. The SDK decides it runs on Reintersect hosting from this binding, not from the manifest's `hosting`. |

The client secret is never given to a hosted app.

Your own secrets work through `env`: values you set with `reintersect env set` are stored encrypted
and bound to the Worker, production values to published versions and preview values to previews.
Your code reads them as `Secret` values and calls `.reveal()` where it needs the string. See
[Environment and config](/concepts/env-and-config).

## Receiving webhooks from other services

A hosted app has its own origin at `https://<slug>.reintersect.app/`. Requests there reach your
app's [routes](/hosting/routes). Reintersect never sets cookies on `reintersect.app`.

## Logs

`console.*` output and uncaught exceptions are collected per request and kept for seven days. Read
them with the CLI or on **Settings → Developer → Apps → your app → Logs**:

```bash theme={null}
npx reintersect logs --app app_123 --follow
```

Each entry shows the outcome, the delivery id, CPU time, up to 50 log lines and up to 10 exceptions.
**Deliveries**, next to it, lists each delivery with its status, attempts and response.

## Limits

| Limit | Value |
| - | - |
| CPU time per delivery or route request | 50 ms |
| CPU time per MCP request | 200 ms |
| Outbound requests per request | 50 |
| Wall-clock deadline for interactive calls | 5 s, set by the [delivery protocol](/webhooks-and-security) |
| Bundle size | 10 MB |

CPU time counts only time spent running your code, not time waiting on `fetch`. A call that exceeds a
limit fails, and Reintersect keeps the block's last good render.

Hosting is included in every plan.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.