The Cloudflare Durable Objects platform leverages Cloudflare Workers to run ActorCore.

ActorCore relies on features only available in the Workers Paid plan (more info).

To deploy hobby projects with ActorCore for free, try deploying to Rivet.

ActorCore is still pre-v1.0. Please help us by report bugs on GitHub Issues!

Create New Project

1

Create Project with CLI

Run this command:

npx create-actor@latest

Follow the prompts:

  1. Where would you like to create your project? - Choose your project directory
  2. To which platform would you like to deploy? - Select Cloudflare Workers
  3. Which template would you like to use? - Select counter, or your template of choice

The CLI will set up your project and install all dependencies automatically.

2

Start Development Server

Start your development server with:

cd your-project
npm run dev

This will start your ActorCore server in development mode with Wrangler.

3

Test

In a separate terminal, run the auto-generated test client:

npx tsx tests/client.ts
# Outputs:
# Event: 5
# Action: 5

Run this again to see the state update.

4

Deploy

  1. Create a new KV namespace with:

    npx wrangler kv namespace create ACTOR_KV
    
  2. After creating the KV namespace, you will receive an ID. Update your wrangler.json file by replacing the placeholder in the kv_namespaces section with this ID. It should look like this:

    {
    	"kv_namespaces": [
    		{
    			"binding": "ACTOR_KV",
    			"id": "your-namespace-id-here"  // Replace with your actual ID
    		}
    	]
    	// ...etc...
    }
    
  3. Deploy your project to Cloudflare Workers by running:

    npx wrangler deploy
    
  4. Update tests/client.ts (or wherever your client lives) to use the deployed endpoint. Replace the local endpoint in client.ts with your Cloudflare Workers URL:

    import { createClient } from "actor-core/client";
    import type { App } from "../src/index";
    
    const client = createClient<App>("https://your-worker-subdomain.workers.dev");
    

    Ensure you replace your-worker-subdomain with the actual subdomain assigned to your worker.

Integrating With Existing Projects

If you already have a Cloudflare Workers project and want to add ActorCore, you can follow these steps for manual integration. This approach gives you more control over how ActorCore fits into your existing Cloudflare Workers project.

1

Install Packages

# Install ActorCore
npm add actor-core @actor-core/cloudflare-workers
2

Create Actor

Create a new file for your actor at src/counter.ts:

src/app.ts
import { actor, setup } from "actor-core";

// Create actor
const counter = actor({
  state: { count: 0 },
  actions: {
    increment: (c, x: number) => {
      c.state.count += x;
      c.broadcast("newCount", c.state.count);
      return c.state.count;
    }
  }
});

// Create the application
export const app = setup({
  actors: { counter },
  cors: { origin: "http://localhost:8080" }
});

// Export app type for client usage
export type App = typeof app;
3

Configure Cloudflare

Update both src/index.ts and wrangler.json to look like this:

import { setup, createHandler } from "@actor-core/cloudflare-workers";
import { app } from "./app";

// Create handlers for Cloudflare Workers
const { handler, ActorHandler } = createHandler(app);

// Export the handlers for Cloudflare
export { handler as default, ActorHandler };

In src/index.ts, handler is used to handle HTTP requests made to the worker. ActorHandler is a Durable Object used to provide state for your actors.

If you already have an existing application and want to mount ActorCore on a subpath, see our Hono integration guide. Remember to specify the same path in config.basePath as where you mount the router.

4

Create Client & Test

To start your development server, run:

npx wrangler dev

Now, write a file named client.ts with this:

client.ts
import { createClient } from "actor-core/client";
import type { App } from "./src/index";

async function main() {
	const client = createClient<App>("http://localhost:8787");

	const counter = await client.counter.get();

	counter.on("newCount", (count: number) => console.log("Event:", count));

	const out = await counter.increment(5);
	console.log("Action:", out);

	await counter.dispose();
}

main();

Run the file in a second terminal with:

npx tsx client.ts
# Outputs:
# Event: 5
# Action: 5

Run this again to see the state update.

5

Deploy

  1. Create a new KV namespace with:

    npx wrangler kv namespace create ACTOR_KV
    
  2. After creating the KV namespace, you will receive an ID. Update your wrangler.json file by replacing the placeholder in the kv_namespaces section with this ID. It should look like this:

    {
    	"kv_namespaces": [
    		{
    			"binding": "ACTOR_KV",
    			"id": "your-namespace-id-here"  // Replace with your actual ID
    		}
    	]
    	// ...etc...
    }
    
  3. Deploy your project to Cloudflare Workers by running:

    npx wrangler deploy
    
  4. Update tests/client.ts (or wherever your client lives) to use the deployed endpoint. Replace the local endpoint in client.ts with your Cloudflare Workers URL:

    import { createClient } from "actor-core/client";
    import type { App } from "../src/index";
    
    const client = createClient<App>("https://your-worker-subdomain.workers.dev");
    

    Ensure you replace your-worker-subdomain with the actual subdomain assigned to your worker.

Accessing Cloudflare Context And Bindings

Cloudflare-specific DurableObjectState and environment bindings can be accessed from createVars.

import { actor } from "actor-core";

const myActor = actor({
  // Load Cloudflare-specific variables
  createVars: (c, cloudflare) => ({
	ctx: cloudflare.ctx,
	env: cloudflare.env,
  }),
  actions: {
	foo: async (c) => {
	  // Access DurableObjectState
	  await c.vars.ctx.storage.get("foo");

	  // Access bindings
	  await c.vars.env.MY_BUCKET.put(key, "foo");
	},
  }
});

Available Regions

See available regions here.

Cloudflare does not guarantee your code will run in the requested region.

Next Steps