# Deploying to Freestyle

> Source: `src/content/docs/connect/freestyle.mdx`
> Canonical URL: https://rivet.dev/docs/connect/freestyle
> Description: Deploy RivetKit app to Freestyle.sh, a cloud platform for running AI-generated code with built-in security and scalability.

---

Freestyle provides built-in security for running untrusted AI-generated code, making it ideal for AI agent applications. Using Rivet, it is easy to deploy your vibe-coded or user-provided RivetKit backends straight to Freestyle.

- [Freestyle + Rivet](https://github.com/rivet-dev/rivet/tree/main/examples/freestyle) — Complete example of deploying RivetKit app to Freestyle.sh.

## Setup

### Install packages

Install RivetKit and Hono and create your registry:

```bash
npm install rivetkit hono
```

### Configure serverless driver

Update your server code to run the registry serverless with Deno.

```typescript actors.ts @hide
import { actor, setup } from "rivetkit";

export const counter = actor({
  state: { count: 0 },
  actions: {
    increment: (c, x: number) => {
      c.state.count += x;
      return c.state.count;
    },
  },
});

export const registry = setup({
  use: { counter },
});
```

```typescript server.ts @nocheck
import { registry } from "./actors";

// Freestyle uses Deno under the hood for web deployments
// @ts-ignore Deno is a Freestyle runtime global
Deno.serve((request: Request) => registry.handler(request));
```

The `Deno.serve` API is provided by Freestyle's runtime environment. The `@ts-ignore` comment suppresses TypeScript errors for this platform-specific API.

### Deploy to Freestyle

Deploy your application to Freestyle with the correct configuration. Create a deployment script or add this to your existing deployment process:

```typescript @nocheck
const FREESTYLE_DOMAIN = "my-domain.style.dev"; // Change to your desired Freestyle domain

declare const freestyle: any;
declare const buildDir: string;

const res = await freestyle.deployWeb(buildDir, {
  envVars: {
    FREESTYLE_ENDPOINT: `https://${FREESTYLE_DOMAIN}`,
    RIVET_RUNNER_KIND: "serverless",
    // For self-hosted instances:
    // RIVET_ENDPOINT: "http://127.0.0.1:6420",
    RIVET_ENDPOINT: "api.rivet.dev",
  },
  timeout: 60 * 5, // Increases max request lifetime on the runner
  entrypoint: "server.ts", // File which starts serverless runner
  domains: [FREESTYLE_DOMAIN],
  build: false,
});
```

Details on `buildDir` and other settings are available on [Freestyle docs](https://docs.freestyle.sh/web/web).

Run this deployment script to push your application to Freestyle.

**Deployment Configuration:**

- `timeout: 60 * 5` - Set timeout to 5 minutes for actor operations - it's important to keep this high
- `entrypoint: "server.ts"` - Entry point file with your serverless setup
- `domains` - Your Freestyle domain(s)
- `build: false` - Disable build if you're pre-building your assets

### Configure runner

Update the runner configuration on the Rivet side to connect with your Freestyle deployment. Create a configuration script and run it after your Freestyle deployment is live:

```typescript @nocheck
import { RivetClient } from "rivetkit/client";

const rivet = new RivetClient({
  endpoint: "api.rivet.dev",
  token: process.env.RIVET_API_TOKEN,
});

const FREESTYLE_DOMAIN = "my-domain.style.dev"; // Change to your desired Freestyle domain
const RIVET_NAMESPACE = "my-rivet-namespace"; // Change to your Rivet namespace

await rivet.runnerConfigs.upsert("freestyle-runner", {
  serverless: {
    url: `https://${FREESTYLE_DOMAIN}/start`,
    runnersMargin: 1,
    minRunners: 1,
    maxRunners: 1,
    slotsPerRunner: 1,
    // Must be shorter than Freestyle request `timeout` config
    requestLifespan: 60 * 5 - 5,
  },
  namespace: RIVET_NAMESPACE,
});
```

Execute this configuration script to register your Freestyle deployment with Rivet.

**Runner Configuration:**

- `url` - Freestyle deployment URL with `/start` endpoint
- `runnersMargin` - Buffer of runners to maintain
- `minRunners/maxRunners` - Scaling limits
- `slotsPerRunner` - Concurrent actors per runner
- `requestLifespan` - Request timeout (slightly less than Freestyle timeout)

Once executed, Rivet will be connected to your Freestyle serverless instance.

_Source doc path: /docs/connect/freestyle_
