コンテンツにスキップ
日本語

What is actor-ts?

このコンテンツはまだ日本語訳がありません。

actor-ts is a runtime for building concurrent, distributed, and fault-tolerant systems in TypeScript using the actor model. It runs natively on Bun, Node.js, and Deno, picking the right runtime backend (TCP sockets, worker threads, SQLite, HTTP serve primitives) automatically based on which globals are present.

The actor model itself isn’t new — it has prior art in Erlang on the BEAM VM since the 80s, on the JVM via Akka and Pekko since the 2010s, and in .NET via Orleans. actor-ts is the TypeScript-native equivalent, written from scratch to fit the runtime ecosystem TypeScript actually lives in.

An actor is a small unit of state and behaviour that processes one message at a time. Actors don’t share memory; they communicate by sending messages to each other’s mailboxes. A mailbox is just a queue, and the actor’s loop is “pop a message, run the handler, repeat.” Because there’s no shared state and exactly one message in flight per actor, you don’t need locks, you don’t need careful sequencing, you don’t reason about race conditions inside an actor — the model gives you serializability for free. Actors form supervision trees: when a child crashes, its parent gets to decide whether to restart it, escalate the failure, or shut it down. The same model scales from a single process to a cluster of machines via location transparency — an ActorRef doesn’t know or care whether the actor it points at lives in the same process, another process, or another data centre.

That’s the conceptual core. Everything else — sharding, persistence, distributed data, cluster membership, pub-sub — is built on top of that one primitive.

The actor model has been the production answer for highly concurrent backends for forty years. Telecom switches run on it. WhatsApp ran tens of millions of concurrent connections per BEAM node. The model is battle-tested, the literature is extensive, and the design wins out over thread-pool-plus-mutex code the moment your concurrency picture gets non-trivial.

TypeScript is the dominant language for application backends today. Bun, Node, and Deno all give you fast startup, solid TypeScript ergonomics, and a healthy ecosystem. Yet the actor-model toolkit for TS has historically been thin — you’d either write your own primitives, glue together promise/worker-thread soup that approximated actors badly, or accept that “anything beyond a toy needs the JVM.”

actor-ts exists to close that gap. A full-coverage port of the actor-model stack — actors, supervision, cluster, sharding, persistence, observability, HTTP, brokers — built in idiomatic TypeScript, leaning on the type system (discriminated unions, match().exhaustive(), generic actor refs) where JVM ports leaned on traits and type parameters.

A docs reader looking for “an actor library for TS” finds a few on npm. Most of them stop at the basic actor abstraction: a class with a message-handler. That’s the easy part. The hard parts — the ones forty years of production experience with the actor model have established — are the operational pieces around the actor.

actor-ts tries to ship them all in one package:

  • Clustering — gossip-based membership with leader election, weakly-up transitions, φ-accrual failure detection, split-brain resolvers. None of this is something an application developer should write themselves.
  • Sharding — for stateful actors that live forever, you need to distribute them across the cluster, remember which node holds which entity, and rebalance when nodes join or leave. Sharding handles the coordinator, the hand-off, the passivation, the remember-entities backend.
  • PersistencePersistentActor for event-sourced state, DurableState for the simpler “save a snapshot” case, both with pluggable journals (in-memory, SQLite, Cassandra) and snapshot stores. Plus the migration toolchain for evolving schemas without rewriting old events.
  • Distributed data — eight CRDTs (counters, registers, sets, maps) with durable storage and gossip replication, for state that should converge across the cluster without leader coordination.
  • Integrations — HTTP server with a route DSL (Fastify default, Express + Hono backends), brokers for Kafka / MQTT / NATS / AMQP / Redis Streams / gRPC / WebSocket, object storage for S3 / MinIO / R2 / filesystem with compression + encryption.
  • Observability — Prometheus metrics, OpenTelemetry tracing, management endpoints, stock metrics out of the box.

The full feature catalogue sits in the left sidebar — Build Actors, Distribute, Persist, Integrate, Observe. Each section has an overview page that explains the why of its subsystem; each subsystem has its own pages going into detail.

The shape of the API surface — ActorRef, Props, tell / ask, become / stash, supervision strategies, the extensions API, the receptionist, distributed pub/sub, cluster singleton — will feel familiar to anyone who has used a typed actor framework on another runtime. Where JVM idioms didn’t carry, we picked the TypeScript-native equivalent.

It is — a serious, full-coverage actor-model toolkit, with a documentation site, runnable examples (chat, voice), and test coverage well into four digits. Production-shaped: the kind of thing you’d build a real backend on, if you were inclined.

It isn’t — battle-tested at scale. Nobody is running ten million concurrent connections on this today. The framework is pre-1.0; the API surface is broad but not all of it is set in stone. And it was written with heavy AI pair-programming assistance, which is a strength (consistency, coverage, comments) and a caveat (some corners may be more “looks right” than “verified right”).

The framework treats the three runtimes — Bun, Node, Deno — as first-class peers. All three are CI-tested for the features they support; the compatibility matrix is the definitive reference for what works where.

Bun is the primary development target: fastest cold start, built-in SQLite via bun:sqlite, built-in WebSocket server, native test runner. Most internal benchmarks were measured on Bun.

Node is the production reality: by far the most common deployment environment, the runtime your infrastructure team already knows, most npm packages are first-tested against. Some actor-ts features (native WebSocket, native zstd compression) require Node 22+ to avoid a peer-dependency fallback; everything else works on Node 20+.

Deno is the best-effort runtime: works for most features via the npm: specifier, but a handful of integrations have not been exhaustively tested.

Internal abstractions live behind small src/runtime/* modules that auto-detect at startup. You write your application code once; the runtime adapter picks the right backend.

  • Want to try it? Quickstart — five minutes to a running actor.
  • Want the philosophy first? Why actors? — what the actor model gives you that promise-and-worker code doesn’t.
  • Installing? Installation — full walkthrough including the optional peer dependencies.
  • Lost in the surface area? Learning path — suggested reading order based on what you want to build.
  • Coming from Akka, Pekko, Orleans, or Akka.NET? The migration guides map concept-by-concept from those frameworks to actor-ts.