Skip to content

Commit cef217f

Browse files
authored
docs: prep for site (#5096)
# Description Please include a summary of the changes and the related issue. Please also include relevant motivation and context. ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes
1 parent e0cf642 commit cef217f

5 files changed

Lines changed: 366 additions & 1 deletion

File tree

draft.md

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
# RivetKit Setup & Deploy
2+
3+
Read https://rivet.dev/llms.txt to understand how RivetKit works (actors, state, events, actions, connections, clients).
4+
5+
Add a note to the project's \`CLAUDE.md\` / \`AGENTS.md\` (create one if missing) linking to https://rivet.dev/llms.txt as the reference for future RivetKit work.
6+
7+
## Step 1: New project or existing?
8+
9+
Ask the user:
10+
11+
> Do you want to **build a new project with RivetKit**, or **integrate RivetKit into this existing project**?
12+
13+
Branch based on their answer.
14+
15+
---
16+
17+
## Path A: New project
18+
19+
### 1. Suggest something to build
20+
21+
Recommend something realtime, fast to spin up, and with a simple frontend. Good starting points:
22+
23+
- **Chat app** (rooms + messages, great default)
24+
- Collaborative todo / list
25+
- Live cursors / presence demo
26+
- Simple multiplayer game (tic-tac-toe, drawing board)
27+
28+
Ask what they want to build. If they're unsure, default to a chat app.
29+
30+
### 2. Build it
31+
32+
Scaffold a minimal project with RivetKit:
33+
34+
- \`npm install rivetkit\` (or pnpm/yarn/whatever is being used)
35+
- Add a frontend (plain HTML/JS or React via \`@rivetkit/react\` — keep it small).
36+
- Define actors + registry (see https://rivet.dev/docs/actors).
37+
- Serve via \`registry.listen({ port: 3001, publicDir: "<frontend-output-dir>" })\` so one command serves both API and frontend.
38+
- Add a local dev script (e.g. \`npm run dev\`) that builds the frontend and starts the server.
39+
40+
Reference quickstarts:
41+
- Node.js / Bun: https://rivet.dev/docs/actors/quickstart/backend
42+
- React: https://rivet.dev/docs/actors/quickstart/react
43+
44+
### 3. Verify
45+
46+
- \`GET /api/rivet/metadata\` returns 200.
47+
- Drive actors via the inspector HTTP API: https://rivet.dev/docs/actors/debugging
48+
- If there's a frontend, open it in a browser and confirm the realtime behavior works end-to-end.
49+
50+
### 4. Wrap up
51+
52+
Give the user:
53+
54+
- A brief overview of the project (what was built, where the actors live, how state/events flow).
55+
- The command to run locally.
56+
- Next steps to deploy + Rivet link.
57+
58+
**Deploy steps:**
59+
60+
1. Review the docs for ${provideStr} (the following docs are available, pick the one that relates to ${provideStr}
61+
https://rivet.dev/docs/connect/rivet-compute/
62+
https://rivet.dev/docs/connect/aws-ecs/
63+
https://rivet.dev/docs/connect/aws-lambda/
64+
https://rivet.dev/docs/connect/cloudflare/
65+
https://rivet.dev/docs/connect/custom/
66+
https://rivet.dev/docs/connect/freestyle/
67+
https://rivet.dev/docs/connect/gcp-cloud-run/
68+
https://rivet.dev/docs/connect/hetzner/
69+
https://rivet.dev/docs/connect/kubernetes/
70+
https://rivet.dev/docs/connect/railway/
71+
https://rivet.dev/docs/connect/supabase/
72+
https://rivet.dev/docs/connect/vercel/
73+
https://rivet.dev/docs/connect/vm-and-bare-metal/
74+
)
75+
2. Configure and deploy using the following environment variables:
76+
RIVET_PUBLIC_ENDPOINT=${publishableToken}
77+
RIVET_ENDPOINT=${secretToken}${
78+
runnerName !== "default"
79+
? \`
80+
RIVET_POOL=${runnerName}\`
81+
: ""
82+
}
83+
3. Finally, if applicable (not necessary for Rivet Compute), tell the user the URL to paste in to the Rivet dashboard
84+
85+
---
86+
87+
## Path B: Integrate into existing project
88+
89+
### 1. Understand the project + propose
90+
91+
Read through the project to understand what it does. Then ask:
92+
93+
> What do you want to build, or how do you want to integrate RivetKit?
94+
95+
Give recommendations grounded in what you see. Examples:
96+
- Chat app with video → move chat into a RivetKit actor for realtime + state.
97+
- Todo app → per-list actor for collaborative editing.
98+
- Dashboard → per-user actor for live metrics / presence.
99+
100+
### 2. Plan
101+
102+
Describe the plan before writing code:
103+
- Which features become actors.
104+
- What state each actor holds.
105+
- Which actions + events the frontend will use.
106+
107+
Get confirmation before implementing.
108+
109+
### 3. Integrate (actors only)
110+
111+
- \`npm install rivetkit\`
112+
- Add actors + registry (see https://rivet.dev/docs/actors).
113+
- Mount on the existing server: \`app.all("/api/rivet/*", (c) => registry.handler(c.req.raw))\` (or the equivalent for the project's framework).
114+
- Do **not** touch the frontend yet unless the user asks.
115+
116+
Verify with \`/api/rivet/metadata\` and the inspector API (https://rivet.dev/docs/actors/debugging).
117+
118+
### 4. Wrap up
119+
120+
Give the user:
121+
- A short overview of what was added.
122+
- The command to run locally.
123+
124+
Then ask:
125+
126+
1. **Want to integrate this into the frontend?** Point at https://rivet.dev/docs/clients/react (or the relevant client doc) and wire it up if yes.
127+
2. **Want to deploy?** If yes, **Deploy steps:**
128+
129+
a. Review the docs for ${provideStr} (the following docs are available, pick the one that relates to ${provideStr}
130+
https://rivet.dev/docs/connect/rivet-compute/
131+
https://rivet.dev/docs/connect/aws-ecs/
132+
https://rivet.dev/docs/connect/aws-lambda/
133+
https://rivet.dev/docs/connect/cloudflare/
134+
https://rivet.dev/docs/connect/custom/
135+
https://rivet.dev/docs/connect/freestyle/
136+
https://rivet.dev/docs/connect/gcp-cloud-run/
137+
https://rivet.dev/docs/connect/hetzner/
138+
https://rivet.dev/docs/connect/kubernetes/
139+
https://rivet.dev/docs/connect/railway/
140+
https://rivet.dev/docs/connect/supabase/
141+
https://rivet.dev/docs/connect/vercel/
142+
https://rivet.dev/docs/connect/vm-and-bare-metal/
143+
)
144+
b. Configure and deploy using the following environment variables:
145+
RIVET_PUBLIC_ENDPOINT=${publishableToken}
146+
RIVET_ENDPOINT=${secretToken}${
147+
runnerName !== "default"
148+
? \`
149+
RIVET_POOL=${runnerName}\`
150+
: ""
151+
}
152+
c. Finally, if applicable (not necessary for Rivet Compute), tell the user the URL to paste in to the Rivet dashboard
153+
154+
Link docs:
155+
- Actors: https://rivet.dev/docs/actors
156+
- Clients: https://rivet.dev/docs/clients
157+
- Troubleshooting: https://rivet.dev/docs/actors/troubleshooting
158+
159+
---
160+
161+
## If you get stuck
162+
163+
Check https://rivet.dev/docs/actors/troubleshooting. If that doesn't help, point the user at:
164+
- Discord: https://rivet.dev/discord
165+
- GitHub issues: https://github.com/rivet-dev/rivet
166+
167+
Include in the report: symptoms, what was tried, RivetKit version, runtime, HTTP router.
168+
169+
170+
----
171+
## Step 1: Load Rivet Skill
172+
173+
Load the Rivet skill. If the skill is not installed, tell the user to run this and restart the agent:
174+
175+
\`\`\`
176+
npx skills add rivet-dev/skills -s rivetkit
177+
\`\`\`
178+
179+
## Step 2: Create Dockerfile
180+
181+
If the project does not already have a \`Dockerfile\`, create one. Use this as a starting point and adjust the package manager (npm/pnpm/yarn), file paths, and entrypoint to match the project:
182+
183+
\`\`\`dockerfile
184+
FROM node:24-alpine
185+
186+
WORKDIR /app
187+
188+
COPY package.json package-lock.json ./
189+
RUN npm ci
190+
191+
COPY . .
192+
RUN npm run build --if-present
193+
194+
CMD ["node", "dist/index.js"]
195+
\`\`\`
196+
197+
If the project does not already have a \`.dockerignore\`, create one:
198+
199+
\`\`\`
200+
node_modules/
201+
dist/
202+
.env
203+
.git/
204+
\`\`\`
205+
206+
If Docker is installed, build and run the image to verify it works before proceeding:
207+
208+
\`\`\`bash
209+
docker build -t rivet-test . && docker run --rm -p 3000:3000 rivet-test
210+
\`\`\`
211+
212+
Verify the container starts and is connectable (e.g. \`curl http://localhost:3000/health\`). If Docker is not installed, skip this and proceed.
213+
214+
## Step 3: Add GitHub Secret
215+
216+
Add the secret RIVET_CLOUD_TOKEN to your GitHub repository:
217+
218+
\`\`\`
219+
gh secret set RIVET_CLOUD_TOKEN --body "${cloudToken}"
220+
\`\`\`
221+
222+
## Step 4: Create GitHub Action
223+
224+
Create .github/workflows/rivet-deploy.yml using rivet-dev/deploy-action@v1.1:
225+
226+
\`\`\`
227+
name: Rivet Deploy
228+
229+
on:
230+
pull_request:
231+
types: [opened, synchronize, reopened, closed]
232+
push:
233+
branches: [main]
234+
workflow_dispatch:
235+
236+
concurrency:
237+
group: rivet-deploy-\${{ github.event.pull_request.number || github.ref }}
238+
cancel-in-progress: true
239+
240+
jobs:
241+
rivet-deploy:
242+
runs-on: ubuntu-latest
243+
permissions:
244+
contents: read
245+
pull-requests: write
246+
steps:
247+
- uses: actions/checkout@v4
248+
- uses: rivet-dev/deploy-action@v1.1
249+
with:
250+
rivet-token: \${{ secrets.RIVET_CLOUD_TOKEN }}
251+
\`\`\`
252+
253+
## Step 5: Push and Verify
254+
255+
Push the changes and monitor the GitHub Action until it completes:
256+
257+
1. Push to the repository.
258+
2. Use \`gh run list\` and \`gh run watch\` to poll the action status. Do not move on until the run finishes.
259+
3. If the action succeeds, proceed to Step 6.
260+
4. If the action fails, inspect the logs with \`gh run view --log-failed\`, fix the issue, push again, and repeat from step 2.
261+
262+
## Step 6: Verify Deployment
263+
264+
**Token types used in this step:**
265+
- \`cloud_api_*\` (the \`RIVET_CLOUD_TOKEN\` secret) — a management token scoped to the Cloud API (cloud-api.rivet.dev). Use this for admin operations like checking deployment status and fetching logs.
266+
- \`pk_*\` (the publishable token below) — a public key scoped to the Rivet Engine API (api.rivet.dev). Use this for creating actors and calling gateway endpoints.
267+
268+
These are different tokens with different scopes. Do not mix them up.
269+
270+
Once deployed, verify the deployment works:
271+
272+
1. Poll the deployment status every 5 seconds until status is "ready". Stop and investigate if status is "error".
273+
\`\`\`bash
274+
curl -s "${cloudApiUrl}/projects/${project}/namespaces/${cloudNamespace}/managed-pools/default?org=${organization}" \\
275+
-H "Authorization: Bearer ${cloudToken}"
276+
\`\`\`
277+
278+
2. Create an actor. Actors require a key field (string, not array):
279+
\`\`\`bash
280+
curl -X POST "${apiUrl}/actors?namespace=${namespace}" \\
281+
-H "Authorization: Bearer ${publishableToken}" \\
282+
-H "Content-Type: application/json" \\
283+
-d '{"name": "<ACTOR_NAME>", "key": "<KEY>", "runner_name_selector": "default", "crash_policy": "restart"}'
284+
\`\`\`
285+
Replace \`<ACTOR_NAME>\` with a valid actor name from the registry and \`<KEY>\` with an appropriate key string (e.g. "general"). Note the \`actor_id\` from the response.
286+
287+
3. Wait ~10 seconds for the actor to start, then hit its health endpoint through the gateway using the public token:
288+
\`\`\`bash
289+
curl "${apiUrl}/gateway/<ACTOR_ID>/health" \\
290+
-H "x-rivet-token: ${publishableToken}"
291+
\`\`\`
292+
This should return ok with a 200 status.
293+
294+
4. If the health check returns actor_runner_failed, check the runner logs via SSE to diagnose:
295+
\`\`\`bash
296+
curl --max-time 15 "${cloudApiUrl}/projects/${project}/namespaces/${cloudNamespace}/managed-pools/default/logs?org=${organization}" \\
297+
-H "Authorization: Bearer ${cloudToken}"
298+
\`\`\`
299+
300+
5. Common issues:
301+
- "actor should have a key": The key field was missing from the create request.
302+
- Token 401: Make sure you're using the correct API URLs (${apiUrl}, ${cloudApiUrl}).
303+
304+
## Troubleshooting
305+
306+
- There is no Rivet CLI. Do not attempt to use or install one. All deployment is done via the GitHub Action and all interaction is done via HTTP APIs (curl).
307+
- Architecture: The GitHub Action builds your Docker image and pushes it to Rivet. Rivet runs the container serverlessly. When you create an actor, Rivet communicates with the \`/api/rivet/*\` endpoint inside the container to manage its lifecycle.
308+
- For more troubleshooting help, see: https://rivet.dev/docs/actors/troubleshooting/

rivetkit-typescript/packages/rivetkit/src/registry/index.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { Hono } from "hono";
12
import { ENGINE_ENDPOINT } from "@/common/engine";
23
import { configureServerlessPool } from "@/serverless/configure";
3-
import { VERSION } from "@/utils";
4+
import { detectRuntime, VERSION } from "@/utils";
5+
import { crossPlatformServe, loadRuntimeServeStatic } from "@/utils/serve";
46
import {
57
type RegistryActors,
68
type RegistryConfig,
@@ -279,6 +281,36 @@ export class Registry<A extends RegistryActors> {
279281
};
280282
}
281283

284+
/**
285+
* Starts an HTTP server that dispatches every request through the
286+
* serverless handler. Uses `crossPlatformServe` to pick the right
287+
* runtime (Node, Bun, Deno).
288+
*
289+
* @param opts.port Port to listen on. Defaults to 3000.
290+
* @param opts.publicDir If set, serves static files from this directory
291+
* before falling through to the registry handler.
292+
*
293+
* @example
294+
* ```ts
295+
* await registry.listen();
296+
* await registry.listen({ port: 8080, publicDir: "./public" });
297+
* ```
298+
*/
299+
public async listen(
300+
opts: { port?: number; publicDir?: string } = {},
301+
): Promise<void> {
302+
const port = opts.port ?? 3000;
303+
const config = this.parseConfig();
304+
const runtime = detectRuntime();
305+
const app = new Hono();
306+
if (opts.publicDir) {
307+
const serveStatic = await loadRuntimeServeStatic(runtime);
308+
app.use("*", serveStatic({ root: opts.publicDir }));
309+
}
310+
app.all("*", (c) => this.handler(c.req.raw));
311+
await crossPlatformServe(config, port, app, runtime);
312+
}
313+
282314
public async diagnostics(): Promise<RegistryDiagnostics> {
283315
const candidates = [
284316
this.#runtimeServerlessPromise,

website/src/components/mdx.jsx

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

website/src/content/docs/connect/rivet-compute.mdx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,22 @@ The dashboard shows live status as Rivet Compute provisions your backend:
111111

112112
Once the status reaches **Ready**, your backend is live and actors are available for connections.
113113

114+
<LLMOnly>
115+
116+
If you are an agent monitoring the deployment via API rather than the dashboard, poll the managed-pool endpoint on the Cloud API.
117+
118+
The `RIVET_CLOUD_TOKEN` secret is a `cloud_api_*` management token scoped to the Cloud API at `cloud-api.rivet.dev`. Use it for `Authorization: Bearer ...` against the Cloud API. Do not confuse it with a `pk_*` publishable key, which is scoped to the Rivet Engine API at `api.rivet.dev` and will 401 against this endpoint.
119+
120+
Substitute `$CLOUD_API_URL` (typically `https://cloud-api.rivet.dev`), `$PROJECT`, `$ORG`, `$CLOUD_NAMESPACE`, and `$CLOUD_TOKEN`.
121+
122+
Poll every 5 seconds until `status` is `ready`. Stop and investigate if `status` is `error`.
123+
124+
```bash
125+
curl -s "$CLOUD_API_URL/projects/$PROJECT/namespaces/$CLOUD_NAMESPACE/managed-pools/default?org=$ORG" -H "Authorization: Bearer $CLOUD_TOKEN"
126+
```
127+
128+
</LLMOnly>
129+
114130
</Step>
115131
</Steps>
116132

0 commit comments

Comments
 (0)