type under their own binding name and ship no class — their binding routes to the owner’s actor and its state.
Why Share an Actor
- Split read and write paths into separate functions with their own auth, rate limits, and deploy cadence — without duplicating state.
- Let a second function call into a domain the first one owns (e.g., a reporting function reads an account actor that a payments function owns).
- Keep one durable actor behind many entrypoints. Both functions talk to the same per-name state; writes through one binding are visible to reads through the other.
The Pattern
The owner function is a normal Stateful Actor project — it ships the class. The reference function declares the sametype under a different binding and ships no actor class — its binding routes to the owner’s actor and state; no second instance is created.
There’s no new-func flag for “reference-only,” so the workflow is: scaffold with --actor (to mint a func_id and write telnyx.toml), then drop the actor class and rename the binding.
Walkthrough: a Read-Only Account Reference
Prereq: an owner function for the type already shipped on your account (theaccount from the Quick Start, type Account).
1. Mint a func_id and scaffold, then drop the class
2. Point telnyx.toml at the owner’s type under a new binding
Edit the [[actors]] block — keep type equal to the owner’s type, change binding:
name, main, compatibility_date, and the [edge_compute] func_id as scaffolded.
3. Replace src/index.ts with a class-free handler that calls env.READONLY
export class Account in this file. The bundler roots at main, so with nothing importing the class, the reference bundle ships class-free (a few KB) — that’s what makes it reference-only.
4. Install deps and ship (same as the owner)
5. Prove they share one actor
ACCOUNT, read through READONLY, same balance → one durable actor (Account), two functions. Both must be on the same account; the reference’s type must exactly match the owner’s.
Rules of Thumb
- Same account, same
type. Reference bindings whosetypedoesn’t match an owner already on the account won’t resolve. - Only one function owns the class. The owner ships the actor class; every other function declares the same
typeand ships no class. - Renaming the binding is fine. Each function picks its own
bindingname — that’s the property onenvfor that function. Thetypeis what glues them together. - Reference bundles are small. With no class import, the bundler emits a class-free bundle. Keep it that way: don’t import the actor class from your reference function.
Next Steps
- Quick Start — ship the owner function this reference calls into
- Runtime API —
ActorNamespace,ActorStub, and the binding surface - Alarms — schedule deferred work from inside an actor method