ActorInterfaces.jl is a formalisation of the actor model family in Julia. Its main goal is to allow writing actor programs independently from any specific implementation of the model. Programs written on top of ActorInterfaces.jl will potentially run on several actor systems.

There is no such thing as The Actor Model, there are interpretations and extensions of it. ActorInterfaces tries to handle this diversity by defining a minimalistic base called the Classic Model, and extensions to it.

Current State: Early stage. The Classic Model is usable but not yet settled. No extension is defined yet. If you have an idea to discuss, please send a PR or create an issue.

Known implementations:


Please refer the source for more details.


Return the currently active implementation of ActorInterfaces, or throw MissingActorSystem.

become(behavior, [ctx])

Replace the behavior of the current actor with behavior.

The new behavior will be effective at the processing of the next message.

The ctx argument can be automatically injected by @ctx.

send(recipient::Addr, msg, [ctx])

Send the message msg to a recipient actor address.

The ctx argument can be automatically injected by @ctx.

spawn(behavior, [ctx]) :: Addr

Create a new actor from the given behavior and schedule it.

The returned address can be used to send messages to the newly created actor. The actor itself is not accessible directly.

The ctx argument can be automatically injected by @ctx.


Inject the actor context into onmessage methods automatically.

The "actor context" allows the runtime to identify the current actor efficiently. It is passed to onmessage and must be provided to every actor primitive call. It can either be handled explicitly by the user or implicitly by the @ctx macro.

When an onmessage method definition is marked with @ctx, calls to send, spawn, etc. from it need not to handle the ctx argument, it will be injected by the macro.

Classic.onmessage(me, msg, ctx)
@ctx Classic.onmessage(me, msg)

Handle the incoming message msg received by an actor with behavior me.

Messages will be dispatched to methods of this function.

Note on async and blocking: @async is allowed in onmessage, but async code should not operate directly on the actor state, only through messages. Blocking operations will also work inside onmessage, but in the Classic model it is up to the implementation to provide any or no concurrency of blocked actors, so blocking should generally be avoided if possible.


mutable struct Counter

struct Increment end

@ctx function Classic.onmessage(me::Counter, msg::Increment)
    me.counter += 1