diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f9ed13666f..4841394a77 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -46,6 +46,12 @@ importers:
specifier: ^8.8.5
version: 8.8.5
+ engine:
+ dependencies:
+ '@vbare/compiler':
+ specifier: ^0.0.3
+ version: 0.0.3(@bare-ts/lib@0.4.0)
+
engine/docker/template:
dependencies:
'@types/js-yaml':
@@ -2331,6 +2337,9 @@ importers:
'@bare-ts/tools':
specifier: ^0.13.0
version: 0.13.0(@bare-ts/lib@0.3.0)
+ '@biomejs/biome':
+ specifier: ^2.2.3
+ version: 2.2.3
'@hono/node-server':
specifier: ^1.18.2
version: 1.19.1(hono@4.9.8)
@@ -3253,6 +3262,13 @@ packages:
peerDependencies:
'@bare-ts/lib': '>=0.3.0 <=0.4.0'
+ '@bare-ts/tools@0.16.1':
+ resolution: {integrity: sha512-eKXTnVqzuKDxr1ozKsFSZfM1wcN4g/iMRnG9GB2fA8oyUcHxwokJC50CANfuSLe6rLnjhZ8Ave1Y2TnZqUqGcQ==}
+ engines: {node: '>=20.0.0'}
+ hasBin: true
+ peerDependencies:
+ '@bare-ts/lib': '>=0.3.0 <=0.4.0'
+
'@base-org/account@2.0.1':
resolution: {integrity: sha512-tySVNx+vd6XEynZL0uvB10uKiwnAfThr8AbKTwILVG86mPbLAhEOInQIk+uDnvpTvfdUhC1Bi5T/46JvFoLZQQ==}
@@ -7024,6 +7040,11 @@ packages:
peerDependencies:
'@urql/core': ^5.0.0
+ '@vbare/compiler@0.0.3':
+ resolution: {integrity: sha512-Dhz0iwYjIhyGAPsNpiqDmDqgwLXfEonjFJLVQ0m/s4Tt9CsTjY0WV3KiQtJi5BdPt9481HR+0uwExH36FuuR2A==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
'@vitejs/plugin-react@4.7.0':
resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -14439,6 +14460,10 @@ snapshots:
'@bare-ts/lib': 0.4.0
commander: 11.1.0
+ '@bare-ts/tools@0.16.1(@bare-ts/lib@0.4.0)':
+ dependencies:
+ '@bare-ts/lib': 0.4.0
+
'@base-org/account@2.0.1(@types/react@19.2.2)(react@19.1.1)(typescript@5.9.2)(use-sync-external-store@1.5.0(react@19.1.1))(zod@3.25.76)':
dependencies:
'@noble/hashes': 1.4.0
@@ -18690,6 +18715,13 @@ snapshots:
'@urql/core': 5.2.0
wonka: 6.3.5
+ '@vbare/compiler@0.0.3(@bare-ts/lib@0.4.0)':
+ dependencies:
+ '@bare-ts/tools': 0.16.1(@bare-ts/lib@0.4.0)
+ commander: 11.1.0
+ transitivePeerDependencies:
+ - '@bare-ts/lib'
+
'@vitejs/plugin-react@4.7.0(vite@5.4.20(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.62.0)(terser@5.44.0))':
dependencies:
'@babel/core': 7.28.4
diff --git a/website/scripts/examplesData.mjs b/website/scripts/examplesData.mjs
index b1439a763a..28f2267aa4 100644
--- a/website/scripts/examplesData.mjs
+++ b/website/scripts/examplesData.mjs
@@ -1,4 +1,4 @@
-// Shared example metadata used by both generateExamples.mjs and generateReadme.mjs
+// Shared example metadata used by both generateExamples.mjs
export const EXAMPLE_METADATA = {
"ai-agent": {
diff --git a/website/scripts/generateExamples.mjs b/website/scripts/generateExamples.mjs
index c1d54f0732..49267c7c92 100644
--- a/website/scripts/generateExamples.mjs
+++ b/website/scripts/generateExamples.mjs
@@ -2,12 +2,12 @@
import { execSync } from 'node:child_process';
import { readFileSync, writeFileSync, existsSync, mkdirSync, cpSync, rmSync } from 'node:fs';
-import { join } from 'node:path';
+import { join, dirname } from 'node:path';
+import { fileURLToPath } from 'node:url';
import { EXAMPLE_METADATA } from './examplesData.mjs';
-const REPO_URL = 'https://github.com/rivet-dev/rivetkit.git';
-const BRANCH = 'main';
-const TEMP_DIR = '/tmp/rivetkit-examples';
+const __dirname = dirname(fileURLToPath(import.meta.url));
+const EXAMPLES_DIR = join(__dirname, '../../examples');
const TEMP_EXAMPLE_DIR = '/tmp/rivet-example-temp';
const OUTPUT_DIR = './src/data/examples';
const OUTPUT_FILE = 'examples.ts';
@@ -17,57 +17,78 @@ if (!existsSync(OUTPUT_DIR)) {
mkdirSync(OUTPUT_DIR, { recursive: true });
}
-// Clone or update the repository
-function updateRepo() {
- if (existsSync(TEMP_DIR)) {
- console.log('Updating existing repository...');
- execSync('git clean -fd', { cwd: TEMP_DIR });
- execSync('git reset --hard', { cwd: TEMP_DIR });
- execSync('git fetch origin', { cwd: TEMP_DIR });
- execSync(`git checkout ${BRANCH}`, { cwd: TEMP_DIR });
- execSync(`git pull origin ${BRANCH}`, { cwd: TEMP_DIR });
- } else {
- console.log('Cloning repository...');
- execSync(`git clone -b ${BRANCH} ${REPO_URL} ${TEMP_DIR}`);
+// Verify examples directory exists
+function verifyExamplesDir() {
+ if (!existsSync(EXAMPLES_DIR)) {
+ throw new Error(`Examples directory not found at ${EXAMPLES_DIR}`);
}
+ console.log(`Using examples from: ${EXAMPLES_DIR}`);
}
-// Replace workspace dependencies with version numbers
+// Get latest version from npm
+function getLatestVersion(packageName) {
+ try {
+ const result = execSync(`npm view ${packageName} version`, { encoding: 'utf-8' });
+ return result.trim();
+ } catch (error) {
+ console.warn(`Warning: Could not fetch version for ${packageName}, using ^0.9.1`);
+ return '0.9.1';
+ }
+}
+
+// Cache for npm versions to avoid repeated lookups
+const versionCache = {};
+
+// Replace workspace dependencies with latest npm versions
function replaceWorkspaceDependencies(content) {
- return content
- .replace(/@rivetkit\/([^"]+)": "workspace:\*"/g, '@rivetkit/$1": "^0.9.1"')
- .replace(/"workspace:\*"/g, '"^0.9.1"');
+ const packageJson = JSON.parse(content);
+
+ // Process both dependencies and devDependencies
+ for (const depType of ['dependencies', 'devDependencies']) {
+ if (packageJson[depType]) {
+ for (const [pkgName, pkgVersion] of Object.entries(packageJson[depType])) {
+ if (pkgVersion === 'workspace:*') {
+ // Get version from cache or fetch from npm
+ if (!versionCache[pkgName]) {
+ console.log(`Fetching latest version for ${pkgName}...`);
+ versionCache[pkgName] = getLatestVersion(pkgName);
+ }
+ packageJson[depType][pkgName] = `^${versionCache[pkgName]}`;
+ }
+ }
+ }
+ }
+
+ return JSON.stringify(packageJson, null, '\t');
}
// Get only the examples defined in metadata
function getExamplesToProcess() {
- const examplesDir = join(TEMP_DIR, 'examples');
-
- if (!existsSync(examplesDir)) {
+ if (!existsSync(EXAMPLES_DIR)) {
throw new Error('Examples directory not found');
}
-
+
const definedExamples = Object.keys(EXAMPLE_METADATA);
const availableExamples = [];
-
+
// Check which defined examples actually exist in the repository
for (const exampleName of definedExamples) {
- const examplePath = join(examplesDir, exampleName);
+ const examplePath = join(EXAMPLES_DIR, exampleName);
if (existsSync(examplePath)) {
availableExamples.push(exampleName);
} else {
throw new Error(`Example defined in metadata but not found in repo: ${exampleName}`);
}
}
-
+
console.log(`Processing ${availableExamples.length} examples: ${availableExamples.join(', ')}`);
return availableExamples;
}
// Copy example to temp folder, install dependencies, then process files
function processExample(exampleName) {
- const exampleDir = join(TEMP_DIR, 'examples', exampleName);
-
+ const exampleDir = join(EXAMPLES_DIR, exampleName);
+
if (!existsSync(exampleDir)) {
throw new Error(`Example directory not found: ${exampleName}`);
}
@@ -95,14 +116,14 @@ function processExample(exampleName) {
// Run npm install to generate lockfile
console.log(`Running npm install for ${exampleName}...`);
try {
- execSync('npm install', {
+ execSync('npm install', {
cwd: tempExampleDir,
- stdio: 'inherit'
+ stdio: 'inherit'
});
} catch (error) {
throw new Error(`npm install failed for ${exampleName}: ${error.message}`);
}
-
+
// Remove node_modules after npm install
console.log(`Removing node_modules for ${exampleName}...`);
const nodeModulesPath = join(tempExampleDir, 'node_modules');
@@ -166,15 +187,15 @@ function processExample(exampleName) {
// Main function
function main() {
console.log('Generating examples...');
-
- // Update the repository
- updateRepo();
-
+
+ // Verify examples directory exists
+ verifyExamplesDir();
+
// Ensure temp example directory exists
if (!existsSync(TEMP_EXAMPLE_DIR)) {
mkdirSync(TEMP_EXAMPLE_DIR, { recursive: true });
}
-
+
// Get examples to process (only those defined in metadata)
const exampleNames = getExamplesToProcess();
diff --git a/website/scripts/generateReadme.mjs b/website/scripts/generateReadme.mjs
deleted file mode 100755
index 40d59a92f7..0000000000
--- a/website/scripts/generateReadme.mjs
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/usr/bin/env node
-
-import { readFileSync, writeFileSync, existsSync } from 'node:fs';
-import { join } from 'node:path';
-import { EXAMPLE_METADATA } from './examplesData.mjs';
-
-const RIVET_TEMPLATE_PATH = join(process.cwd(), '..', 'README.rivet.tpl.md');
-const RIVET_OUTPUT_PATH = join(process.cwd(), '..', 'README.md');
-
-const RIVETKIT_TEMPLATE_PATH = join(process.cwd(), '..', 'README.rivetkit.tpl.md');
-
-const RIVET_QUICKSTART = `Get started with Rivet by following a quickstart guide:
-
-- [Node.js & Bun](https://www.rivet.dev/docs/actors/quickstart/backend/)
-- [React](https://www.rivet.dev/docs/actors/quickstart/react/)
-`
-
-// Content chunks
-const RIVET_FEATURES_CONTENT = `## Features
-
-Rivet Actors are a primitive of RivetKit provide everything you need to build fast, scalable, and real-time applications without the complexity. Rivet Engine is the core of self-hosting and is used for orchestrating actors at scale.
-
-- **Long-Lived, Stateful Compute**: Like AWS Lambda but with memory and no timeouts
-- **Blazing-Fast Reads & Writes**: State stored on same machine as compute
-- **Realtime, Made Simple**: Built-in WebSockets and SSE support
-- **Store Data Near Your Users**: Deploy to the edge for low-latency access
-- **Infinitely Scalable**: Auto-scale from zero to millions without configuration
-- **Fault Tolerant**: Automatic error handling and recovery built-in
-
-## BYO DB (Bring Your Own Database)
-The Rivet Engine supports:
-
-- **PostgreSQL**: For production deployments
-- **FoundationDB**: For enterprise-scale distributed systems
-- **Filesystem**: For single-node deployments`;
-
-const RIVETKIT_FEATURES_CONTENT = `## Features
-
-RivetKit provides everything you need to build fast, scalable, and real-time applications without the complexity.
-
-- **Long-Lived, Stateful Compute**: Like AWS Lambda but with memory and no timeouts
-- **Blazing-Fast Reads & Writes**: State stored on same machine as compute
-- **Realtime, Made Simple**: Built-in WebSockets and SSE support
-- **Store Data Near Your Users**: Deploy to the edge for low-latency access
-- **Infinitely Scalable**: Auto-scale from zero to millions without configuration
-- **Fault Tolerant**: Automatic error handling and recovery built-in`;
-
-const RIVET_COMMUNITY_CONTENT = `## Community & Support
-
-Join thousands of developers building with Rivet Actors today:
-
-- [Discord](https://rivet.dev/discord) - Chat with the community
-- [X/Twitter](https://x.com/rivet_dev) - Follow for updates
-- [Bluesky](https://bsky.app/profile/rivet.dev) - Follow for updates
-- [GitHub Discussions](https://github.com/rivet-dev/rivetkit/discussions) - Ask questions and share ideas
-- [GitHub Issues](https://github.com/rivet-dev/rivetkit/issues) - Report bugs and request features
-- [Talk to an engineer](https://rivet.dev/talk-to-an-engineer) - Discuss your technical needs, current stack, and how Rivet can help with your infrastructure challenges`;
-
-const RIVETKIT_COMMUNITY_CONTENT = `## Community & Support
-
-Join thousands of developers building with RivetKit today:
-
-- [Discord](https://rivet.dev/discord) - Chat with the community
-- [X/Twitter](https://x.com/rivet_dev) - Follow for updates
-- [Bluesky](https://bsky.app/profile/rivet.dev) - Follow for updates
-- [GitHub Discussions](https://github.com/rivet-dev/rivetkit/discussions) - Ask questions and share ideas
-- [GitHub Issues](https://github.com/rivet-dev/rivetkit/issues) - Report bugs and request features
-- [Talk to an engineer](https://rivet.dev/talk-to-an-engineer) - Discuss your technical needs, current stack, and how Rivet can help with your infrastructure challenges`;
-
-const LICENSE_CONTENT = `## License
-
-[Apache 2.0](LICENSE)`;
-
-const RIVET_HEADER = `
-
-`;
-
-const RIVETKIT_HEADER = `
-
-`;
-
-function generateExamplesList() {
- return Object.entries(EXAMPLE_METADATA)
- .map(([id, example]) => {
- const githubUrl = `https://github.com/rivet-dev/rivetkit/tree/main/examples/${id}`;
- const stackblitzUrl = `https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/${id}`;
- return `- ${example.title} — [GitHub](${githubUrl}) · [StackBlitz](${stackblitzUrl})`;
- })
- .join('\n');
-}
-
-function generateRivetReadme() {
- console.log('Generating Rivet README.md...');
-
- // Generate examples list
- const examplesList = generateExamplesList();
-
- // Read template
- const template = readFileSync(RIVET_TEMPLATE_PATH, 'utf-8');
-
- // Replace placeholders
- let content = template.replace('__EXAMPLES__', examplesList);
- content = content.replace('__QUICKSTART__', RIVET_QUICKSTART);
- content = content.replace('__FEATURES__', RIVET_FEATURES_CONTENT);
- content = content.replace('__COMMUNITY__', RIVET_COMMUNITY_CONTENT);
- content = content.replace('__LICENSE__', LICENSE_CONTENT);
-
- const readmeContent = RIVET_HEADER + content;
-
- writeFileSync(RIVET_OUTPUT_PATH, readmeContent);
- console.log(`✓ Generated Rivet README.md at ${RIVET_OUTPUT_PATH}`);
-}
-
-function generateRivetKitReadme() {
- const rivetKitPath = process.env.RIVETKIT_PATH;
-
- if (!rivetKitPath) {
- console.warn('⚠️ Warning: RIVETKIT_PATH environment variable is not set');
- console.warn(' Skipping RivetKit README generation');
- console.warn(' Set RIVETKIT_PATH to the path of your rivetkit repository');
- return;
- }
-
- // Check if RivetKit path exists
- if (!existsSync(rivetKitPath)) {
- console.error(`❌ Error: RIVETKIT_PATH directory does not exist: ${rivetKitPath}`);
- return;
- }
-
- console.log('Generating RivetKit README.md...');
-
- const rivetKitOutputPath = join(rivetKitPath, 'README.md');
-
- // Generate examples list
- const examplesList = generateExamplesList();
-
- // Read template
- const template = readFileSync(RIVETKIT_TEMPLATE_PATH, 'utf-8');
-
- // Replace placeholders
- let content = template.replace('__EXAMPLES__', examplesList);
- content = content.replace('__QUICKSTART__', RIVET_QUICKSTART);
- content = content.replace('__FEATURES__', RIVETKIT_FEATURES_CONTENT);
- content = content.replace('__COMMUNITY__', RIVETKIT_COMMUNITY_CONTENT);
- content = content.replace('__LICENSE__', LICENSE_CONTENT);
-
- const readmeContent = RIVETKIT_HEADER + content;
-
- writeFileSync(rivetKitOutputPath, readmeContent);
- console.log(`✓ Generated RivetKit README.md at ${rivetKitOutputPath}`);
-}
-
-function main() {
- // Always generate Rivet README
- generateRivetReadme();
-
- // Generate RivetKit README if RIVETKIT_PATH is set
- generateRivetKitReadme();
-}
-
-main();
diff --git a/website/src/components/v2/Header.tsx b/website/src/components/v2/Header.tsx
index 9d21b8b31a..23028f4a74 100644
--- a/website/src/components/v2/Header.tsx
+++ b/website/src/components/v2/Header.tsx
@@ -269,7 +269,7 @@ function DocsMobileNavigation({ tree }) {
const sections = [
{ id: "overview", label: "Overview", href: "/docs" },
- { id: "quickstart", label: "Quickstart", href: "/docs/quickstart" },
+ { id: "quickstart", label: "Quickstart", href: "/docs" },
{ id: "actors", label: "Actors", href: "/docs/actors" },
{ id: "integrations", label: "Integrations", href: "/docs/integrations" },
{ id: "api", label: "API Reference", href: "/docs/api" },
diff --git a/website/src/content/docs/index.mdx b/website/src/content/docs/index.mdx
index 3163386bfd..722db7e699 100644
--- a/website/src/content/docs/index.mdx
+++ b/website/src/content/docs/index.mdx
@@ -9,73 +9,22 @@ import {
Rivet is a library for long-lived processes with durable state, realtime, and scalability. It is easily self-hostable and works with your infrastructure.
-## Libraries
+# Quickstart
+
+Get started with Rivet in minutes. Choose your preferred framework or runtime to begin building with actors.
-
- Long-lived processes with durable state, realtime, and hibernation
-
-{/*
+
Set up actors with Node.js, Bun, and web frameworks
-
- Set up actors with Node.js, Bun, and web frameworks
-*/}
-
-
-## Use Cases
-
-
-{useCases.map((useCase) => (
-
- {useCase.description}
-
-))}
-
-
-## Deploy Options
-
-
-{deployOptions.map((option) => (
-
-))}
-
-
-## Integrations
-
-{integrationGroups.map((group) => (
-
- {group.title}
-
- {group.items.map((integration) => (
-
- ))}
-
-
-))}
-
-## Support
-
-
-
- Chat with the community and get realtime help from Rivet engineers
+
+ Build real-time React applications with actors
-
- File bugs or request features directly in our tracker
+
+ Build server-rendered Next.js experiences backed by actors
+
+
+ Deploy actors on Cloudflare Workers with zero infrastructure
+
diff --git a/website/src/content/docs/quickstart/index.mdx b/website/src/content/docs/quickstart/index.mdx
deleted file mode 100644
index 2ab45d7911..0000000000
--- a/website/src/content/docs/quickstart/index.mdx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { faNodeJs, faReact, faNextjs, faCloudflare } from "@rivet-gg/icons";
-
-# Quickstart
-
-Get started with Rivet in minutes. Choose your preferred framework or runtime to begin building with actors.
-
-
-
- Set up actors with Node.js, Bun, and web frameworks
-
-
- Build real-time React applications with actors
-
-
- Build server-rendered Next.js experiences backed by actors
-
-
- Deploy actors on Cloudflare Workers with zero infrastructure
-
-
-
diff --git a/website/src/sitemap/mod.ts b/website/src/sitemap/mod.ts
index 15725770c4..2ca9ed8390 100644
--- a/website/src/sitemap/mod.ts
+++ b/website/src/sitemap/mod.ts
@@ -111,24 +111,49 @@ export const sitemap = [
]
},
{
- title: "Use Cases",
+ title: "Quickstart",
pages: [
- ...useCases.slice(0, 3).map(({ title, href, icon }) => ({
- title,
- href,
- icon,
- })),
{
- title: "More",
- collapsible: true,
- pages: useCases.slice(3).map(({ title, href, icon }) => ({
- title,
- href,
- icon,
- })),
+ title: "Node.js & Bun",
+ href: "/docs/actors/quickstart/backend",
+ icon: faNodeJs,
+ },
+ {
+ title: "React",
+ href: "/docs/actors/quickstart/react",
+ icon: faReact,
+ },
+ {
+ title: "Next.js",
+ href: "/docs/actors/quickstart/next-js",
+ icon: faNextjs,
+ },
+ {
+ title: "Cloudflare Workers",
+ href: "/docs/actors/quickstart/cloudflare-workers",
+ icon: faCloudflare,
},
],
},
+ // {
+ // title: "Use Cases",
+ // pages: [
+ // ...useCases.slice(0, 3).map(({ title, href, icon }) => ({
+ // title,
+ // href,
+ // icon,
+ // })),
+ // {
+ // title: "More",
+ // collapsible: true,
+ // pages: useCases.slice(3).map(({ title, href, icon }) => ({
+ // title,
+ // href,
+ // icon,
+ // })),
+ // },
+ // ],
+ // },
{
title: "Concepts",
pages: [
@@ -330,47 +355,6 @@ export const sitemap = [
},
],
},
- {
- title: "Quickstart",
- href: "/docs/quickstart",
- sidebar: [
- {
- title: "General",
- pages: [
- {
- title: "Overview",
- href: "/docs/quickstart",
- icon: faForward,
- },
- ],
- },
- {
- title: "Guides",
- pages: [
- {
- title: "Node.js & Bun",
- href: "/docs/actors/quickstart/backend",
- icon: faNodeJs,
- },
- {
- title: "React",
- href: "/docs/actors/quickstart/react",
- icon: faReact,
- },
- {
- title: "Next.js",
- href: "/docs/actors/quickstart/next-js",
- icon: faNextjs,
- },
- {
- title: "Cloudflare Workers",
- href: "/docs/actors/quickstart/cloudflare-workers",
- icon: faCloudflare,
- },
- ],
- },
- ],
- },
{
title: "Integrations",
href: "/docs/integrations",