Hono is a lightweight web framework that works well with ActorCore across multiple deployment platforms. This guide explains how to integrate ActorCore with Hono on different platforms.

Mounting The ActorCore Router

When mounting the ActorCore router at a custom path, you must specify the same path in the router configuration using basePath:

// Setup the ActorCore app
const app = setup({
  actors: { counter },
  // IMPORTANT: Must specify the same basePath where your router is mounted
  basePath: "/my-path"
});

// Create a router from the app
const { router: actorRouter } = createRouter(app);

// Mount at the same path specified in basePath
honoApp.route("/my-path", actorRouter);

This ensures that WebSocket connections and other functionality work correctly when accessing your actors through the custom path.

Platform-Specific Examples

Each platform has specific requirements for integrating Hono with ActorCore.

Cloudflare Workers

import { setup, createRouter } from "@actor-core/cloudflare-workers";
import { Hono } from "hono";
import counter from "./counter";

// Create your Hono app inside the fetch handler
const honoApp = new Hono();

// Add your custom routes
honoApp.get("/", (c) => c.text("Welcome to my app!"));
honoApp.get("/hello", (c) => c.text("Hello, world!"));

// Setup the ActorCore app
const app = setup({
  actors: { counter },
  // IMPORTANT: Must specify the same basePath where your router is mounted
  basePath: "/my-path"
});

// Create a router and handler from the app
const { router: actorRouter, ActorHandler } = createRouter(app);

// Mount the ActorCore router at /my-path
honoApp.route("/my-path", actorRouter);

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

// IMPORTANT: Must export `ActorHandler` as this exact name
export { honoApp as default, ActorHandler };

Make sure to update your client connection URL to include the custom path:

// If you mounted ActorCore at /my-path
import { createClient } from "actor-core/client";
import type { App } from "./src/index";

const client = createClient<App>("https://your-worker.workers.dev/my-path");

For this to work with Cloudflare Workers, your wrangler.json must include specific Durable Object and KV namespace bindings with the exact names expected by ActorCore:

{
  "name": "counter",
  "main": "src/index.ts",
  "compatibility_date": "2025-01-29",
  "migrations": [
    {
      "new_classes": ["ActorHandler"],
      "tag": "v1"
    }
  ],
  "durable_objects": {
    "bindings": [
      {
        "class_name": "ActorHandler", // Must match exported class
        "name": "ACTOR_DO"            // Must use this exact name
      }
    ]
  },
  "kv_namespaces": [
    {
      "binding": "ACTOR_KV",          // Must use this exact name
      "id": "YOUR_KV_NAMESPACE_ID"    // Replace with your KV ID
    }
  ]
}

Node.js

import { serve } from "@hono/node-server";
import { Hono } from "hono";
import { setup, createRouter } from "@actor-core/nodejs";
import counter from "./counter";

// Create your Hono app
const honoApp = new Hono();

// Add your custom routes
honoApp.get("/", (c) => c.text("Welcome to my app!"));
honoApp.get("/hello", (c) => c.text("Hello, world!"));

// Setup the ActorCore app
const app = setup({
  actors: { counter },
  // IMPORTANT: Must specify the same basePath where your router is mounted
  basePath: "/my-path"
});

// Create a router from the app
const { router: actorRouter, injectWebSocket } = createRouter(app);

// Mount the ActorCore router at /my-path
honoApp.route("/my-path", actorRouter);

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

// Create server with the combined app
const server = serve({
  fetch: honoApp.fetch,
  port: 6420,
});

// IMPORTANT: Inject the websocket handler into the server
injectWebSocket(server);

console.log("Server running at http://localhost:6420");

Make sure to update your client connection URL to include the custom path:

// If you mounted ActorCore at /my-path
import { createClient } from "actor-core/client";
import type { App } from "./src/index";

const client = createClient<App>("http://localhost:6420/my-path");

Bun

import { Hono } from "hono";
import { setup, createRouter } from "@actor-core/bun";
import counter from "./counter";

// Create your Hono app
const honoApp = new Hono();

// Add your custom routes
honoApp.get("/", (c) => c.text("Welcome to my app!"));
honoApp.get("/hello", (c) => c.text("Hello, world!"));

// Setup the ActorCore app
const app = setup({
  actors: { counter },
  // IMPORTANT: Must specify the same basePath where your router is mounted
  basePath: "/my-path"
});

// Create a router from the app
const { router: actorRouter, webSocketHandler } = createRouter(app);

// Mount the ActorCore router at /my-path
honoApp.route("/my-path", actorRouter);

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

// Create and start the server
export default {
  port: 6420,
  fetch: honoApp.fetch,
  // IMPORTANT: Pass the webSocketHandler to Bun
  websocket: webSocketHandler,
};

Make sure to update your client connection URL to include the custom path:

// If you mounted ActorCore at /my-path
import { createClient } from "actor-core/client";
import type { App } from "./src/index";

const client = createClient<App>("http://localhost:6420/my-path");