diff --git a/website/public/llms-full.txt b/website/public/llms-full.txt
index 6744fdbd6a..af3dfd6eda 100644
--- a/website/public/llms-full.txt
+++ b/website/public/llms-full.txt
@@ -182,262 +182,6 @@ See [helper types](/docs/actors/helper-types) for more details on using `ActionC
- [`ActorDefinition`](/typedoc/interfaces/rivetkit.mod.ActorDefinition.html) - Interface for defining actors with actions
- [`ActorHandle`](/typedoc/types/rivetkit.client_mod.ActorHandle.html) - Handle for calling actions from client
- [`ActorActionFunction`](/typedoc/types/rivetkit.client_mod.ActorActionFunction.html) - Type for action functions
-## AI and User-Generated Rivet Actors
-
-# AI and User-Generated Rivet Actors
-
-Deploy AI or user-generated Rivet Actor code with sandboxed namespaces and serverless infrastructure.
-
-Complete example showing how to deploy user-generated Rivet Actor code.
-
-## Overview
-
-This guide shows you how to programmatically create isolated Rivet environments and deploy custom actor code to them. This pattern is useful for:
-
-- **AI-generated code deployments** - Deploy code generated by LLMs in isolated environments
-- **User sandbox environments** - Give users their own isolated Rivet namespace to experiment
-- **Preview deployments** - Create ephemeral environments for testing pull requests
-- **Multi-tenant applications** - Isolate each customer in their own namespace
-
-## How It Works
-
-The deployment process involves four key steps:
-
-1. **Create sandboxed Rivet namespace** - Programmatically create an isolated Rivet namespace using the Cloud API or self-hosted Rivet API
-2. **Generate tokens** - Create the necessary tokens for authentication (runner, publishable, and access tokens)
-3. **Deploy to Freestyle** - Deploy the actor code and frontend to Freestyle's serverless platform
-4. **Configure runner** - Connect Rivet to the Freestyle deployment so actors can be executed
-
-## Sandboxed Rivet Namespaces
-
-Rivet provides the ability to create sandboxed namespaces programmatically. Each namespace is completely isolated with its own:
-
-- Actor instances and state
-- Authentication tokens
-- Configuration settings
-- Resource limits
-
-Namespaces can be created on-demand through the Rivet API, making them perfect for scenarios where you need to quickly spin up isolated environments.
-
-## Deploying Code to Freestyle
-
-[Freestyle](https://docs.freestyle.sh/web/overview) is a serverless platform optimized for deploying JavaScript/TypeScript code, particularly code written by users or AI systems. It provides:
-
-- Fast cold starts (around 5ms)
-- Automatic TLS certificates
-- Built-in security for untrusted code
-- Easy deployment API
-
-We use Freestyle to host the backend logic for your Rivet Actors, making it easy to deploy custom code without managing infrastructure.
-
-## Setup
-
- 1. Visit your project on [Rivet Cloud](https://dashboard.rivet.dev/)
- 2. Click on "Tokens" in the sidebar
- 3. Under "Cloud API Tokens" click "Create Token"
- 4. Copy the token for use in your deployment script
-
- Create a deployment script that handles namespace creation, token generation, Freestyle deployment, and runner configuration.
-
- This code demonstrates the complete flow for deploying user-generated Rivet Actor code to Freestyle with Rivet Cloud:
-
- ```typescript
- // Configuration
- const CLOUD_API_URL = "https://api.rivet.dev/cloud";
- const CLOUD_API_TOKEN = "your-cloud-api-token";
- const ENGINE_ENDPOINT = "https://api.rivet.dev";
- const FREESTYLE_DOMAIN = "your-app.style.dev";
- const FREESTYLE_API_KEY = "your-freestyle-api-key";
- const DATACENTER = "us-west-1";
-
- async function deploy(registryCode: string, appCode: string) );
-
- const = await cloudRivet.apiTokens.inspect();
- const namespaceName = `ns-$-$`;
-
- const = await cloudRivet.namespaces.create(project, );
-
- // Step 2: Generate tokens
- const = await cloudRivet.namespaces.createSecretToken(
- project,
- namespace.name,
- -runner-token`,
- org: organization,
- },
- );
-
- const = await cloudRivet.namespaces.createPublishableToken(
- project,
- namespace.name,
- ,
- );
-
- const = await cloudRivet.namespaces.createAccessToken(
- project,
- namespace.name,
- ,
- );
-
- // Step 3: Deploy to Freestyle
- // Build your project directory with the custom registry and app code
- // See the example repository for the complete template structure
- const freestyle = new FreestyleSandboxes();
- const deploymentSource = prepareDirForDeploymentSync(projectDir);
-
- const = await freestyle.deployWeb(deploymentSource, `,
- RIVET_RUNNER_KIND: "serverless",
- VITE_RIVET_ENDPOINT: ENGINE_ENDPOINT,
- VITE_RIVET_NAMESPACE: namespace.access.engineNamespaceName,
- VITE_RIVET_TOKEN: publishableToken,
- VITE_RIVET_DATACENTER: DATACENTER,
- RIVET_ENDPOINT: ENGINE_ENDPOINT,
- RIVET_NAMESPACE: namespace.access.engineNamespaceName,
- RIVET_RUNNER_TOKEN: runnerToken,
- RIVET_PUBLISHABLE_TOKEN: publishableToken,
- },
- timeout: 60 * 5,
- entrypoint: "src/backend/server.ts",
- domains: [FREESTYLE_DOMAIN],
- build: false,
- });
-
- // Step 4: Configure Rivet runner
- const engineRivet = new RivetClient();
-
- await engineRivet.runnerConfigsUpsert("default", /api/rivet`,
- headers: ,
- runnersMargin: 1,
- minRunners: 1,
- maxRunners: 1,
- slotsPerRunner: 1,
- requestLifespan: 60 * 4 + 30,
- },
- },
- },
- namespace: namespace.access.engineNamespaceName,
- });
-
- return /projects/$/ns/$`,
- freestyleUrl: `https://admin.freestyle.sh/dashboard/deployments/$`,
- };
- }
- ```
-
- **Step 1: Create sandboxed namespace** - Uses the Cloud API to create a new isolated namespace with a unique name.
-
- **Step 2: Generate tokens** - Creates three types of tokens: runner token (for executing actors), publishable token (for frontend clients), and access token (for API access).
-
- **Step 3: Deploy to Freestyle** - Deploys the actor code and frontend to Freestyle with all necessary environment variables configured. The deployment uses a 5-minute timeout to handle long-running operations.
-
- **Step 4: Configure runner** - Configures Rivet to route actor execution requests to the Freestyle deployment. The runner config specifies scaling limits and request lifespans.
-
- See the [example repository](https://github.com/rivet-dev/rivet/tree/main/examples/ai-and-user-generated-actors-freestyle) for the complete project structure including the template directory and build process.
-
- For self-hosted Rivet, you'll need:
- - Your Rivet Engine endpoint (e.g., `http://your-rivet-instance:6420`)
- - An API token with permissions to create namespaces
-
- See the [self-hosting documentation](/docs/self-hosting) for details on setting up authentication.
-
- Create a deployment script for self-hosted Rivet.
-
- This code demonstrates the complete flow for deploying user-generated Rivet Actor code to Freestyle with self-hosted Rivet:
-
- ```typescript
- // Configuration
- const RIVET_ENDPOINT = "http://your-rivet-instance:6420";
- const RIVET_TOKEN = "your-rivet-token";
- const FREESTYLE_DOMAIN = "your-app.style.dev";
- const FREESTYLE_API_KEY = "your-freestyle-api-key";
- const DATACENTER = "us-west-1";
-
- async function deploy(registryCode: string, appCode: string) );
-
- const namespaceName = `ns-$-$`;
-
- const = await rivet.namespaces.create();
-
- // Step 2: Generate tokens (use the same token for self-hosted)
- // For self-hosted, you typically use the same token for all operations
- const token = RIVET_TOKEN;
-
- // Step 3: Deploy to Freestyle
- // Build your project directory with the custom registry and app code
- // See the example repository for the complete template structure
- const freestyle = new FreestyleSandboxes();
- const deploymentSource = prepareDirForDeploymentSync(projectDir);
-
- const = await freestyle.deployWeb(deploymentSource, `,
- RIVET_RUNNER_KIND: "serverless",
- VITE_RIVET_ENDPOINT: RIVET_ENDPOINT,
- VITE_RIVET_NAMESPACE: namespace.name,
- VITE_RIVET_TOKEN: token,
- VITE_RIVET_DATACENTER: DATACENTER,
- RIVET_ENDPOINT: RIVET_ENDPOINT,
- RIVET_NAMESPACE: namespace.name,
- RIVET_RUNNER_TOKEN: token,
- RIVET_PUBLISHABLE_TOKEN: token,
- },
- timeout: 60 * 5,
- entrypoint: "src/backend/server.ts",
- domains: [FREESTYLE_DOMAIN],
- build: false,
- });
-
- // Step 4: Configure Rivet runner
- await rivet.runnerConfigsUpsert("default", /api/rivet`,
- headers: ,
- runnersMargin: 1,
- minRunners: 1,
- maxRunners: 1,
- slotsPerRunner: 1,
- requestLifespan: 60 * 4 + 30,
- },
- },
- },
- namespace: namespace.name,
- });
-
- return `,
- };
- }
- ```
-
- **Step 1: Create sandboxed namespace** - Creates a new isolated namespace using the self-hosted Rivet API.
-
- **Step 2: Generate tokens** - For self-hosted Rivet, you typically use the same token for all operations. The token system is simpler than Rivet Cloud.
-
- **Step 3: Deploy to Freestyle** - Deploys the actor code and frontend to Freestyle with environment variables pointing to your self-hosted Rivet instance.
-
- **Step 4: Configure runner** - Configures your self-hosted Rivet to route actor execution requests to the Freestyle deployment.
-
- See the [example repository](https://github.com/rivet-dev/rivet/tree/main/examples/ai-and-user-generated-actors-freestyle) for the complete project structure including the template directory and build process.
-
-## Project Structure
-
-The example uses this structure:
-
-```
-src/
- backend/ # Backend used to deploy sandboxed Rivet code
- frontend/ # Frontend for the deploy UI
-template/ # Template Rivet project to deploy
- src/
- backend/ # Actor code (registry.ts gets replaced with user code)
- frontend/ # Frontend code (App.tsx gets replaced with user code)
-```
-
-The deployment script:
-1. Copies the template directory
-2. Replaces `registry.ts` and `App.tsx` with user-provided code
-3. Builds and deploys to Freestyle
-4. Configures Rivet to connect to the deployment
-
-## Next Steps
-
-- Explore the [complete example](https://github.com/rivet-dev/rivet/tree/main/examples/ai-and-user-generated-actors-freestyle)
-- Learn more about [Freestyle deployment](https://docs.freestyle.sh/web/overview)
-- Read about [Rivet namespaces and tokens](/docs/actors/authentication)
## Authentication
# Authentication
diff --git a/website/src/app/(v2)/(marketing)/(index)/sections/RedesignedHero.tsx b/website/src/app/(v2)/(marketing)/(index)/sections/RedesignedHero.tsx
index 12efcba67f..e8fafec21f 100644
--- a/website/src/app/(v2)/(marketing)/(index)/sections/RedesignedHero.tsx
+++ b/website/src/app/(v2)/(marketing)/(index)/sections/RedesignedHero.tsx
@@ -250,3 +250,5 @@ export const chatRoom = actor({
);
+
+
diff --git a/website/src/app/(v2)/(marketing)/pricing/PricingPageClient.tsx b/website/src/app/(v2)/(marketing)/pricing/PricingPageClient.tsx
index f6788ba809..1ad73edd92 100644
--- a/website/src/app/(v2)/(marketing)/pricing/PricingPageClient.tsx
+++ b/website/src/app/(v2)/(marketing)/pricing/PricingPageClient.tsx
@@ -1,604 +1,723 @@
"use client";
-import { CheckIcon, MinusIcon, PlusIcon } from "@heroicons/react/16/solid";
-import { MobilePricingTabs } from "./components/MobilePricingTabs";
-import { useState } from "react";
-import clsx from "clsx";
-import Link from "next/link";
-import { Icon, faArrowRight } from "@rivet-gg/icons";
-
-
-const tiers = [
- {
- name: "Free",
- priceMonthly: "$0",
- href: "https://dashboard.rivet.dev/",
- highlights: [
- { description: "5GB Limit", icon: "check" },
- { description: "5 Million Writes /mo Limit", icon: "check" },
- { description: "200 Million Reads /mo Limit", icon: "check" },
- { description: "100GB Egress Limit", icon: "check" },
- { description: "Community Support", icon: "check" },
- ],
- },
- {
- name: "Hobby",
- priceMonthly: "$5",
- href: "https://dashboard.rivet.dev/",
- highlights: [
- { description: "25 Billion Reads /mo included", icon: "gift" },
- { description: "50 Million Writes /mo included", icon: "gift" },
- { description: "5GB Storage included", icon: "gift" },
- { description: "1TB Egress included", icon: "gift" },
- { description: "Email Support", icon: "check" },
- ],
- },
- {
- name: "Team",
- priceMonthly: "$200",
- href: "https://dashboard.rivet.dev/",
- highlights: [
- { description: "25 Billion Reads /mo included", icon: "gift" },
- { description: "50 Million Writes /mo included", icon: "gift" },
- { description: "5GB Storage included", icon: "gift" },
- { description: "1TB Egress included", icon: "gift" },
- { description: "MFA", icon: "check" },
- { description: "Slack Support", icon: "check" },
- ],
- },
- {
- name: "Enterprise",
- priceMonthly: "Custom",
- href: "/sales",
- highlights: [
- { description: "Everything in Team", icon: "check" },
- { description: "Priority Support", icon: "check" },
- { description: "SLA", icon: "check" },
- { description: "OIDC SSO provider", icon: "check" },
- { description: "On-Prem Deployment", icon: "check" },
- { description: "Audit Logs", icon: "check" },
- { description: "Custom Roles", icon: "check" },
- { description: "Device Tracking", icon: "check" },
- { description: "Volume Pricing", icon: "check" },
- ],
- },
-];
-
-const sections = [
- {
- name: "Usage Included",
- features: [
- {
- name: "Storage",
- tiers: {
- Free: "5GB",
- Hobby: "5GB included",
- Team: "5GB included",
- Enterprise: "Custom",
- },
- },
- {
- name: "Reads per month",
- tiers: {
- Free: "200 Million",
- Hobby: "25 Billion included",
- Team: "25 Billion included",
- Enterprise: "Custom",
- },
- },
- {
- name: "Writes per month",
- tiers: {
- Free: "5 Million",
- Hobby: "50 Million included",
- Team: "50 Million included",
- Enterprise: "Custom",
- },
- },
- {
- name: "Egress",
- tiers: {
- Free: "100GB Limit",
- Hobby: "1TB included",
- Team: "1TB included",
- Enterprise: "Custom",
- },
- },
- ],
- },
- {
- name: "Support",
- features: [
- {
- name: "Support",
- tiers: {
- Free: "Community Support",
- Hobby: "Email",
- Team: "Slack & Email",
- Enterprise: "Slack & Email",
- },
- },
- ],
- },
- {
- name: "Security & Enterprise",
- features: [
- {
- name: "MFA",
- tiers: {
- Free: false,
- Hobby: false,
- Team: true,
- Enterprise: true,
- },
- },
- {
- name: "Custom Regions",
- tiers: {
- Free: false,
- Hobby: false,
- Team: false,
- Enterprise: true,
- },
- },
- {
- name: "SLA",
- tiers: {
- Free: false,
- Hobby: false,
- Team: false,
- Enterprise: true,
- },
- },
- {
- name: "Audit Logs",
- tiers: {
- Free: false,
- Hobby: false,
- Team: false,
- Enterprise: true,
- },
- },
- {
- name: "Custom Roles",
- tiers: {
- Free: false,
- Hobby: false,
- Team: false,
- Enterprise: true,
- },
- },
- {
- name: "Device Tracking",
- tiers: {
- Free: false,
- Hobby: false,
- Team: false,
- Enterprise: true,
- },
- },
- {
- name: "Volume Pricing",
- tiers: {
- Free: false,
- Hobby: false,
- Team: false,
- Enterprise: true,
- },
- },
- ],
- },
-];
-
-function PricingTable() {
- return (
-
- Pricing plan comparison
-
-
-
-
-
-
-
-
-
- Compare Rivet Cloud Plans
-
- {tiers.slice(1).map((_, idx) => (
-
- ))}
-
-
-
- {tiers.map((tier) => (
-
-
- {tier.name}{" "}
- plan
-
-
- ))}
-
-
- {sections.map((section) => (
-
- {section.features.map((feature) => (
-
-
- {feature.name}
-
- {tiers.map((tier) => (
-
- {typeof feature.tiers[tier.name] ===
- "string" ? (
- feature.name === "Regions" ? (
-
-
- Learn more about regions:{" "}
-
- {feature.tiers[tier.name]}
-
- ) : (
- <>
-
- {tier.name} includes:
-
-
- {feature.tiers[tier.name]}
-
- >
- )
- ) : (
- <>
- {feature.tiers[tier.name] ===
- true ? (
-
- ) : (
-
- )}
-
-
- {feature.tiers[tier.name] ===
- true
- ? `Included in ${tier.name}`
- : `Not included in ${tier.name}`}
-
- >
- )}
-
- ))}
-
- ))}
-
- ))}
-
- );
-}
-function PricingTiers() {
- return (
-
- {tiers.map((tier) => (
-
-
-
-
- {tier.name}{" "}
- plan
-
-
- {(tier.name === "Hobby" ||
- tier.name === "Team") && (
-
- From
-
- )}
-
-
- {tier.priceMonthly}
-
- {tier.name !== "Enterprise" && (
-
- /mo
-
- )}
-
- {(tier.name === "Hobby" ||
- tier.name === "Team") && (
-
- + Usage
-
- )}
-
-
-
- Includes:
-
-
- {tier.highlights.map((highlight, idx) => (
-
- {highlight.icon === "gift" ? (
-
-
-
- ) : (
-
-
-
- )}
- {highlight.description}
-
- ))}
-
-
-
-
-
-
- ))}
-
- );
-}
+import React, { useState } from 'react';
+import Link from 'next/link';
+import {
+ Terminal,
+ Zap,
+ Globe,
+ ArrowRight,
+ Box,
+ Check,
+ Server,
+ Cloud,
+ Activity,
+ CreditCard,
+ Command,
+ Network,
+ HardDrive,
+ Laptop
+} from 'lucide-react';
-function UsagePricingTable() {
- return (
-
-
-
- Usage Pricing
-
-
- Pay only for what you use beyond the included allowances
-
-
-
-
-
-
-
-
-
- Resource
-
-
- Price
-
-
-
-
-
-
- Storage
-
-
- $0.40 per GB-month
-
-
-
-
- Reads
-
-
- $1.00 per billion reads
-
-
-
-
- Writes
-
-
- $1.00 per million writes
-
-
-
-
- Egress
-
-
- $0.15 per GB
-
-
-
-
-
-
-
- );
-}
+// --- Shared Design Components ---
-interface ToggleProps {
- options: { value: string; label: string }[];
- activeValue: string;
- onChange: (value: string) => void;
-}
+const Badge = ({ text, color = "orange" }) => {
+ const colorClasses = {
+ orange: "text-[#FF4500] border-[#FF4500]/20 bg-[#FF4500]/10",
+ blue: "text-blue-400 border-blue-500/20 bg-blue-500/10",
+ red: "text-red-400 border-red-500/20 bg-red-500/10",
+ zinc: "text-zinc-400 border-zinc-500/20 bg-zinc-500/10",
+ };
+
+ return (
+
+
+ {text}
+
+ );
+};
+
+const CodeBlock = ({ code, fileName = 'rivet.json' }) => {
+ return (
+
+ );
+};
+
+const FeatureCard = ({ title, description, icon: Icon, color = "orange" }) => {
+ const getColorClasses = (col) => {
+ switch (col) {
+ case "orange":
+ return {
+ iconBg: "bg-[#FF4500]/10 text-[#FF4500] group-hover:bg-[#FF4500]/20",
+ glow: "rgba(255, 69, 0, 0.15)",
+ borderColor: "border-[#FF4500]",
+ iconShadow: "group-hover:shadow-[0_0_15px_rgba(255,69,0,0.5)]"
+ };
+ case "blue":
+ return {
+ iconBg: "bg-blue-500/10 text-blue-400 group-hover:bg-blue-500/20",
+ glow: "rgba(59, 130, 246, 0.15)",
+ borderColor: "border-blue-500",
+ iconShadow: "group-hover:shadow-[0_0_15px_rgba(59,130,246,0.5)]"
+ };
+ case "red":
+ return {
+ iconBg: "bg-red-500/10 text-red-400 group-hover:bg-red-500/20",
+ glow: "rgba(239, 68, 68, 0.15)",
+ borderColor: "border-red-500",
+ iconShadow: "group-hover:shadow-[0_0_15px_rgba(239,68,68,0.5)]"
+ };
+ default:
+ return {
+ iconBg: "bg-zinc-500/10 text-zinc-400 group-hover:bg-zinc-500/20",
+ glow: "rgba(161, 161, 170, 0.15)",
+ borderColor: "border-zinc-500",
+ iconShadow: "group-hover:shadow-[0_0_15px_rgba(161,161,170,0.5)]"
+ };
+ }
+ };
+
+ const colors = getColorClasses(color);
+
+ return (
+
+ {/* Top Shine Highlight */}
+
+
+ {/* Top Left Reflection/Glow */}
+
+
+ {/* Sharp Edge Highlight (Masked to Fade) */}
+
+
+
+
+ {description}
+
+
+ );
+};
+
+// --- Page Sections ---
+
+const Hero = () => (
+
+
+
+
+
+
+
+ Rivet Cloud
+
+
+
+ Rivet sits between your clients and your infrastructure. We manage the persistent connections, global routing, and actor state orchestrating your logic wherever it runs.
+
+
+
+
+ Get Started for Free
+
+
+
document.getElementById('pricing')?.scrollIntoView({ behavior: 'smooth' })}
+ className="font-v2 inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md border border-white/10 bg-white/5 px-4 py-2 text-sm text-white subpixel-antialiased shadow-sm transition-colors hover:border-white/20 w-full sm:w-auto"
+ >
+
+ See Pricing
+
+
+
+
+ {/* Main Diagram Container */}
+
+
+ {/* 1. Source: Clients */}
+
+
+
+
+
Any Client
+
Web • Mobile • Console • CLI
+
+
+ {/* Connection Line 1 */}
+
+ {/* Desktop Horizontal Line */}
+
+ {/* Mobile Vertical Line */}
+
+
+
+ {/* 2. The Gateway: Rivet */}
+
+
+
+
+
+
+
Rivet Cloud
+
+ Gateway & Orchestrator
+
+
+
+ {/* Connection Line 2 - The Branching System */}
+ {/* This container manages the split lines */}
+
+
+ {/* Desktop: The Branch Connector */}
+
+ {/* Main Feed Line from Gateway */}
+
+
+ {/* Top Branch - Added overflow-hidden */}
+
+
+ {/* Middle Branch - Added overflow-hidden */}
+
+
+ {/* Bottom Branch - Added overflow-hidden */}
+
+
+
+ {/* Mobile: Vertical Line */}
+
+
+
+ {/* 3. Destination: User Backend */}
+
+ {/* 1. Docker */}
+
+
+
+
+
+
Docker Containers
+
AWS ECS • Kubernetes
+
+
+
+ {/* 2. Serverless */}
+
+
+
+
+
+
Serverless Functions
+
Vercel • Cloudflare
+
+
+
+ {/* 3. Dedicated */}
+
+
+
+
+
+
Dedicated Servers
+
Bare Metal • EC2
+
+
+
+
+
-function Toggle({ options, activeValue, onChange }: ToggleProps) {
- return (
-
-
- {options.map((option) => (
- onChange(option.value)}
- className={clsx(
- "px-4 py-2 text-sm font-medium rounded-md transition-all duration-200 whitespace-nowrap",
- activeValue === option.value
- ? "bg-white/10 text-white border border-white/20"
- : "text-white/60 hover:text-white/80 hover:bg-white/5"
- )}
- >
- {option.label}
-
- ))}
-
-
- );
+
+
+
+
+);
+
+
+const CloudFeatures = () => {
+ const features = [
+ { title: "Orchestration", desc: "The control plane handles actor placement, lifecycle management, and health checks across your cluster automatically.", icon: Command, color: "zinc" },
+ { title: "Managed Persistence", desc: "State is persisted with strict serializability using FoundationDB, ensuring global consistency without the ops burden.", icon: HardDrive, color: "orange" },
+ { title: "Multi-Region", desc: "Deploy actors across regions worldwide. Compute and state live together at the edge, delivering ultra-low latency responses.", icon: Globe, color: "blue" },
+ { title: "Bring Your Own Compute", desc: "Run your business logic on AWS, Vercel, Railway, or bare metal. Rivet connects them all into a unified platform.", icon: Network, color: "zinc" },
+ { title: "Serverless & Containers", desc: "Works with your serverless or container deployments, giving you the flexibility to choose the best runtime for your workload.", icon: Box, color: "orange" },
+ { title: "Observability", desc: "Live state inspection, event monitoring, network inspector, and REPL for debugging and monitoring actors.", icon: Activity, color: "blue" }
+ ];
+
+ return (
+
+
+
+
Platform Features
+
Everything you need to run stateful workloads in production.
+
+
+ {features.map((f, i) => (
+
+ ))}
+
+
+
+ );
}
-export default function PricingPageClient() {
- const [activeTab, setActiveTab] = useState("cloud");
-
- const toggleOptions = [
- { value: "cloud", label: "Cloud" },
- { value: "selfhost", label: "Self-Host" },
- ];
-
- return (
-
-
-
-
-
- Rivet {activeTab === "cloud" ? "Cloud Pricing" : "Self-Host"}
-
-
- {activeTab === "cloud"
- ? "Start with free and scale as you grow."
- : "Deploy Rivet on your own infrastructure."
- }
-
-
-
-
-
-
-
-
- {activeTab === "cloud" ? (
- <>
-
-
-
- >
- ) : (
-
-
-
- Self-Hosted Rivet
-
-
- Deploy Rivet on your own infrastructure with full control and no usage limits.
-
-
-
-
-
Open Source
-
- Rivet is open source and free to use on your own infrastructure.
-
-
-
-
- No usage limits
-
-
-
- Full source code access
-
-
-
- Community support
-
-
-
-
-
-
-
Enterprise Support
-
- Get professional support and additional features for your self-hosted deployment.
-
-
-
-
- Priority support
-
-
-
- SLA guarantees
-
-
-
- Custom integrations
-
-
-
-
-
-
-
- )}
-
- );
+const SelfHostingComparison = () => {
+ const burdens = [
+ "Provisioning a Distributed Store",
+ "Configuring Cross-Region VPC Peering",
+ "Managing TLS Certificates & Rotation",
+ "Scaling the Coordination Plane",
+ "Handling Partition Tolerance",
+ "Implementing Zero-Downtime Drains"
+ ];
+
+ return (
+
+
+
+
Compare Deployment Models
+
+ Rivet is open source. Run it yourself for total control, or use Rivet Cloud for a hands-off experience.
+
+
+
+
+ {/* Rivet Cloud Card */}
+
+
+
+
+ Managed cloud solution for personal projects to enterprise.
+
+
+
+
+ Scaling
+ Managed
+
+
+ Database
+ FoundationDB
+
+
+ Networking
+ Global Mesh
+
+
+ Updates
+ Automatic
+
+
+
+
+ Get Started
+
+
+
+ {/* Open Source Card */}
+
+
+
+
+ Maximum control for air-gapped environments or specific compliance requirements.
+
+
+
+
+ Scaling
+ You Manage
+
+
+ Database
+ BYO (postgres or filesystem)
+
+
+ Networking
+ Manual VPC
+
+
+ Updates
+ Manual
+
+
+
+
+ View on Github
+
+
+
+
+
+ )
}
+const ComparisonTable = () => {
+ const features = [
+ { name: "Storage", free: "5GB", hobby: "5GB", team: "5GB", ent: "Custom" },
+ { name: "Reads / mo", free: "200 Million", hobby: "25 Billion", team: "25 Billion", ent: "Custom" },
+ { name: "Writes / mo", free: "5 Million", hobby: "50 Million", team: "50 Million", ent: "Custom" },
+ { name: "Egress", free: "100GB", hobby: "1TB", team: "1TB", ent: "Custom" },
+ { name: "Support", free: "Community", hobby: "Email", team: "Slack & Email", ent: "Slack & Email" },
+ { name: "MFA", free: false, hobby: false, team: true, ent: true },
+ { name: "Custom Regions", free: false, hobby: false, team: false, ent: true },
+ { name: "SLA", free: false, hobby: false, team: false, ent: true },
+ { name: "Audit Logs", free: false, hobby: false, team: false, ent: true },
+ { name: "Custom Roles", free: false, hobby: false, team: false, ent: true },
+ { name: "Device Tracking", free: false, hobby: false, team: false, ent: true },
+ { name: "Volume Pricing", free: false, hobby: false, team: false, ent: true },
+ ];
+
+ const renderCell = (value) => {
+ if (typeof value === 'boolean') {
+ return value ?
+
:
+ ;
+ }
+ return {value} ;
+ };
+
+ return (
+
+
Compare Plans
+
+
+
+
+ Feature
+ Free
+ Hobby
+ Team
+ Enterprise
+
+
+
+ {features.map((feature, i) => (
+
+ {feature.name}
+ {renderCell(feature.free)}
+
+ {renderCell(feature.hobby)}
+
+ {renderCell(feature.team)}
+ {renderCell(feature.ent)}
+
+ ))}
+
+
+
+
+ );
+ };
+
+const Pricing = () => {
+ const [isCloud, setIsCloud] = useState(true);
+
+ const cloudPlans = [
+ {
+ name: "Free",
+ price: "$0",
+ period: "/mo",
+ desc: "For prototyping and small projects.",
+ features: [
+ "5GB Limit",
+ "5 Million Writes /mo Limit",
+ "200 Million Reads /mo Limit",
+ "100GB Egress Limit",
+ "Community Support"
+ ],
+ cta: "Get Started",
+ highlight: false
+ },
+ {
+ name: "Hobby",
+ prefix: "From",
+ price: "$5",
+ period: "/mo + Usage",
+ desc: "For scaling applications.",
+ features: [
+ "25 Billion Reads /mo included",
+ "50 Million Writes /mo included",
+ "5GB Storage included",
+ "1TB Egress included",
+ "Email Support"
+ ],
+ cta: "Get Started",
+ highlight: true
+ },
+ {
+ name: "Team",
+ prefix: "From",
+ price: "$200",
+ period: "/mo + Usage",
+ desc: "For growing teams and businesses.",
+ features: [
+ "25 Billion Reads /mo included",
+ "50 Million Writes /mo included",
+ "5GB Storage included",
+ "1TB Egress included",
+ "MFA",
+ "Slack Support"
+ ],
+ cta: "Get Started",
+ highlight: false
+ },
+ {
+ name: "Enterprise",
+ price: "Custom",
+ period: "",
+ desc: "For high-volume, mission-critical workloads.",
+ features: [
+ "Everything in Team",
+ "Priority Support",
+ "SLA",
+ "OIDC SSO provider",
+ "Audit Logs",
+ "Custom Roles",
+ "Device Tracking",
+ "Volume Pricing"
+ ],
+ cta: "Contact",
+ highlight: false
+ }
+ ];
+
+ const selfHostedPlans = [
+ {
+ name: "Open Source",
+ price: "Free",
+ period: "Forever",
+ desc: "Rivet is open source and free to use on your own infrastructure.",
+ features: [
+ "No usage limits",
+ "Full source code access",
+ "Community support"
+ ],
+ cta: "Get Started",
+ highlight: false
+ },
+ {
+ name: "Enterprise Support",
+ price: "Custom",
+ period: "",
+ desc: "Get professional support and additional features for your self-hosted deployment.",
+ features: [
+ "Priority support",
+ "SLA guarantees",
+ "Custom integrations"
+ ],
+ cta: "Contact Sales",
+ highlight: false
+ }
+ ];
+ const plans = isCloud ? cloudPlans : selfHostedPlans;
+
+ const usagePricing = [
+ { resource: "Awake Actors", price: "$0.05", unit: "per 1k awake actor-hours" },
+ { resource: "State Storage", price: "$0.40", unit: "per GB-month" },
+ { resource: "Egress", price: "$0.15", unit: "per GB" },
+ { resource: "Compute", price: "BYO", unit: "Paid to your provider" },
+ ];
+
+ return (
+
+
+
+
+ {isCloud ? "Simple, Predictable Pricing" : "Rivet Self-Host"}
+
+
+ {isCloud
+ ? "Pay for coordination and state. Compute costs are billed directly by your chosen cloud provider."
+ : "Deploy Rivet on your own infrastructure."
+ }
+
+
+ {/* Toggle */}
+
+ setIsCloud(true)}
+ className={`px-6 py-2 rounded-md text-sm font-medium transition-all flex items-center gap-2 ${isCloud ? 'bg-white/10 text-white border border-white/20' : 'text-zinc-500 hover:text-zinc-300'}`}
+ >
+ Cloud
+
+ setIsCloud(false)}
+ className={`px-6 py-2 rounded-md text-sm font-medium transition-all flex items-center gap-2 ${!isCloud ? 'bg-white/10 text-white border border-white/20' : 'text-zinc-500 hover:text-zinc-300'}`}
+ >
+ Self-Hosted
+
+
+
+
+
+ {plans.map((plan, idx) => (
+
+ {/* Highlight Effects for Pro Card */}
+ {plan.highlight && (
+ <>
+ {/* Top Shine */}
+
+ >
+ )}
+
+ {!plan.highlight && (
+
+ )}
+
+
+
{plan.name}
+
+
+ {plan.prefix &&
{plan.prefix} }
+
+ {plan.price}
+ {plan.period && {plan.period} }
+
+
+
+ {plan.desc &&
{plan.desc}
}
+
+
+ {plan.features.map((feat, i) => (
+
+
+ {feat}
+
+ ))}
+
+
+
+
+ {plan.cta}
+
+
+ ))}
+
+
+ {/* Only show usage and comparison for Cloud */}
+ {isCloud && (
+ <>
+ {/* Usage Pricing Section */}
+
+
+
Usage Pricing
+
Metered costs for scaling beyond plan limits.
+
+
+
+ {usagePricing.map((item, i) => (
+
+
{item.resource}
+
{item.price}
+
{item.unit}
+
+ ))}
+
+
+
+
+ >
+ )}
+
+
+ );
+};
+
+
+export default function PricingPageClient() {
+ return (
+
+ );
+}
diff --git a/website/src/app/(v2)/(marketing)/solutions/collaborative-state/page.tsx b/website/src/app/(v2)/(marketing)/solutions/collaborative-state/page.tsx
index 20ce09b027..3a8cd10a86 100644
--- a/website/src/app/(v2)/(marketing)/solutions/collaborative-state/page.tsx
+++ b/website/src/app/(v2)/(marketing)/solutions/collaborative-state/page.tsx
@@ -673,3 +673,5 @@ export default function CollaborativeStatePage() {
);
}
+
+
diff --git a/website/src/app/(v2)/(marketing)/solutions/user-session-store/page.tsx b/website/src/app/(v2)/(marketing)/solutions/user-session-store/page.tsx
index bb06e9a0ee..0a6c577c8b 100644
--- a/website/src/app/(v2)/(marketing)/solutions/user-session-store/page.tsx
+++ b/website/src/app/(v2)/(marketing)/solutions/user-session-store/page.tsx
@@ -715,3 +715,5 @@ export default function UserSessionStorePage() {
);
}
+
+
diff --git a/website/src/app/(v2)/[section]/doc-page.tsx b/website/src/app/(v2)/[section]/doc-page.tsx
index 334662ec70..997e6289a6 100644
--- a/website/src/app/(v2)/[section]/doc-page.tsx
+++ b/website/src/app/(v2)/[section]/doc-page.tsx
@@ -204,3 +204,5 @@ export async function getAllDocParams(): Promise> {
return staticParams;
}
+
+
diff --git a/website/src/app/(v2)/[section]/util.ts b/website/src/app/(v2)/[section]/util.ts
index 9015299740..1175a2a06e 100644
--- a/website/src/app/(v2)/[section]/util.ts
+++ b/website/src/app/(v2)/[section]/util.ts
@@ -17,3 +17,5 @@ export function buildFullPath(pathComponents: string[]): string {
return `/${pathComponents.join("/")}`;
}
+
+
diff --git a/website/src/components/Header.jsx b/website/src/components/Header.jsx
index 1fabac3ee5..6a7e4c6e00 100644
--- a/website/src/components/Header.jsx
+++ b/website/src/components/Header.jsx
@@ -200,7 +200,7 @@ export const Header = forwardRef(function Header(
Changelog
- Pricing
+ Cloud
diff --git a/website/src/components/Navigation.jsx b/website/src/components/Navigation.jsx
index 5c19b4589b..c5c99d090e 100644
--- a/website/src/components/Navigation.jsx
+++ b/website/src/components/Navigation.jsx
@@ -114,7 +114,7 @@ export function Navigation({ navigation, ...props }) {
Changelog
- Pricing
+ Cloud
{/* Sidebar */}
diff --git a/website/src/components/v2/Header.tsx b/website/src/components/v2/Header.tsx
index cd93bb08c2..eb02f83746 100644
--- a/website/src/components/v2/Header.tsx
+++ b/website/src/components/v2/Header.tsx
@@ -260,7 +260,7 @@ export function Header({
active === "pricing" ? "page" : undefined
}
>
- Pricing
+ Cloud
- Pricing
+ Cloud