Sign In
Runtime

JavaScript Runtime

The Rivet JavaScript runtime is built on lightweight JavaScript containers called V8 isolates, providing a high-performance, secure environment for your actor code.

It's designed to be widely compatible with Node.js and NPM dependencies, making it easy to use familiar libraries and tools.


Basic Setup

Step 1: Writing an actor

Add the @rivet-gg/actor package to your project for comprehensive TypeScript definitions:

Command Line
npm install -S @rivet-gg/actor

Every actor must export a default object with an async start function. Here's a simple HTTP server example:

src/index.ts
import type { ActorContext } from "@rivet-gg/actor";
import * as http from "http";

export default {
  async start(ctx: ActorContext) {
    // Get the port from environment variables or use a default
    const port = parseInt(process.env.PORT_HTTP || "8080");
    console.log(`HTTP server running on port ${port}`);
    
    // Create an HTTP server
    const server = http.createServer((req, res) => {
      res.writeHead(200, { "Content-Type": "text/plain" });
      res.end(`Hello from Rivet Actor ${ctx.metadata.actor.id} running in ${ctx.metadata.region.id}!`);
    });
    
    // Start listening on the specified port
    server.listen(port);
    
    // Keep the actor running until explicitly destroyed
    await new Promise((resolve) => {});
  }
};

What this code does:

  • Sets up a simple HTTP server using Node.js's built-in http module
  • Creates a response that includes the actor ID and region information
  • Keeps the actor running indefinitely by returning a promise that never resolves

Step 2: Deploying an actor

Specify the script in your rivet.json:

rivet.json
{
  "builds": {
    "my-actor": {
      "script": "./src/index.ts"
    }
  }
}

Now deploy your actor with:

Command Line
rivet deploy

Step 3: Starting an actor

In this step, you're requesting Rivet to launch your actor code in the cloud:

TypeScript
import { RivetClient } from "@rivet-gg/api";

// Initialize the Rivet client with your API token
// You can get this from the Rivet dashboard
const client = new RivetClient({
  token: process.env.RIVET_TOKEN
});

// Create an actor - this launches your code on Rivet's infrastructure
const { actor } = await client.actors.create({
  // Your project and environment IDs from the Rivet dashboard
  project: "your-project-id",
  environment: "your-environment-id",
  body: {
    // Tags help identify this specific actor instance
    // You can query actors by these tags later
    tags: { name: "my-actor" },
    
    // buildTags determine which actor code to run
    // This should match tags in your rivet.json build configuration
    // The current tag is automatically assigned on deploy
    buildTags: { name: "my-actor", current: "true" },
    
    // Network configuration for your actor
    network: {
      ports: {
        http: {
          // The protocol used for communication
          protocol: "https",
        }
      }
    },
    
    // Optional: Specify a region for lower latency to specific users
    // If not specified, Rivet will choose the optimal region
    // region: "atl",
  }
});

// The actor.id is a unique identifier for this actor instance
console.log("Created actor:", actor.id);

What happens during creation:

  • Rivet finds the latest build matching your buildTags
  • It provisions resources in the specified region (or chooses the best one)
  • It starts your actor code with the provided environment variables
  • The actor starts running and initializes based on your code's start function

See actors.create for more options.

Step 4: Connecting to an actor

Once your actor is running, you can access its URL directly from the actor object:

TypeScript
// The actor response includes the URL information
// You can access it for any port you configured
const httpUrl = actor.network.ports.http.url;

// The URL is a public endpoint to your actor
console.log("Actor HTTP URL:", httpUrl);

// Use the URL to communicate with your actor
// In this example, we're calling the /hello endpoint on our HTTP server
const response = await fetch(`${httpUrl}/hello`);
const text = await response.text();
console.log("Response from actor:", text);

What happens during connection:

  • Each port configured for your actor gets a unique URL
  • These URLs are accessible based on your actor's security settings
  • The URL routes to your actor regardless of which region it's in
  • For additional security, you can use getConnection to generate temporary, authenticated URLs

See actors.get for more details.

Step 5: Destroying an actor

When you're finished using the actor, it's important to destroy it to free up resources:

TypeScript
// Destroy the actor to free up resources and stop billing
await client.actors.destroy(actor.id, {
  project: "your-project-id",
  environment: "your-environment-id",
});

console.log("Actor destroyed");

What happens during destruction:

  • Rivet sends a termination signal to your actor
  • Your actor gets a short grace period to clean up resources
  • All compute resources associated with the actor are freed
  • You stop being billed for the actor's runtime

See actors.destroy for more details.


Configuration

See the configuration documentation for all available options.


The ActorContext Object

Your start function receives an ActorContext object with important metadata and services:

TypeScript
interface ActorContext {
  // Information about your actor and its environment
  metadata: {
    actor: {
      id: string;
      tags: Record<string, string>;
      createdAt: Date;
    };
    project: {
      id: string;
      slug: string;
    };
    environment: {
      id: string;
      slug: string;
    };
    cluster: {
      id: string;
    };
    region: {
      id: string;
      name: string;
    };
    build: {
      id: string;
    };
  };
  // Key-value storage API
  kv: {
    // KV methods (see documentation for details)
  };
}
Suggest changes to this page