Jido: an agent runtime for Elixir that keeps decisions pure and effects explicit
🤖 Autonomous agent framework for Elixir. Built for distributed, autonomous behavior and dynamic workflows.
At a glance
- What is it?
- Jido is the core package of the Jido ecosystem, an OTP-based framework for defining agents as immutable structs with a single cmd/2 function. It is a reasonable fit if you already run Elixir and want cooperating agents under supervision, and the wrong tool if you want a batteries-included LLM app or a Python-style agent loop.
- Who is it for?
- Adopt Jido if your team already ships OTP services and needs cooperating agents with explicit state transitions, signals and runtime-owned effects; the installation path is mix igniter.install jido, which generates a MyApp.Jido instance module and wires it into your supervision tree. Do not adopt it if your requirement is a single LLM chat loop, since the core package contains no model integration and jido_ai is a separate dependency.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Elixir, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The reinvention problem Jido targets, and who feels it
The README frames the project against raw OTP rather than against other agent frameworks. Its argument is that GenServer works, but once you are building multiple cooperating agents you end up reinventing the same five things: message shapes per server, business logic mixed into callbacks, effects scattered through the code, ad-hoc child tracking, and process exit standing in for task completion. Jido's answer is to formalize each of those as a named construct: signals as a standard envelope, actions as a reusable command pattern, directives as typed effect descriptions, a built-in parent/child hierarchy, and state-based completion semantics.
The audience follows from that framing. This is for Elixir teams that already operate OTP services and want agent behaviour to look like the rest of their system rather than like a separate runtime bolted on. It is explicitly not an AI-first product: the README states that AI is optional, that the core package gives you the agent architecture and runtime, and that companion packages such as jido_ai add model integration when you need it. If your starting point is a prompt and a model endpoint, Jido starts one layer below where you are standing.
cmd/2, the purity boundary, and why directives exist
The core abstraction is small. An agent is an immutable data structure with a single command function, and the README gives this shape:
defmodule MyAgent do use Jido.Agent, name: "my_agent", description: "My custom agent", schema: [ count: [type: :integer, default: 0] ] end
{agent, directives} = MyAgent.cmd(agent, action)
Four roles are separated. Agents hold state and implement cmd/2. Actions do work and transform that state. Signals route events into the system. Directives describe effects for the runtime to execute. The README calls the agent's decision logic the purity boundary: decisions and state transitions stay explicit, actions may be pure or effectful, and directives are reserved for effects you want the runtime to own.
The practical rule is stated plainly. If an action needs a result back immediately to continue reasoning or to update state, it may perform that work itself. If the workflow has already decided on an outbound effect and wants the runtime or integration layer to own delivery, it returns a directive. That is a real design commitment, not a naming convention. It means the decision path can be exercised without performing the effect, and it means effect delivery becomes the runtime's problem.
State is schema-validated, with NimbleOptions or Zoi named as the options. The built-in directive set listed in the README is Emit, Spawn, SpawnAgent, StopChild, StartSensor, StopSensor, Schedule and Stop, with protocol-based extensibility for custom directives. The runtime side is a GenServer-based AgentServer, parent-child agent hierarchies with lifecycle management, and signal routing with configurable strategies.
Getting it running: Igniter versus manual installation
The recommended path is Igniter. Running mix igniter.install jido is documented to add Jido to your dependencies, create a MyApp.Jido instance module using use Jido, otp_app: :my_app, create configuration in config/config.exs, and add MyApp.Jido to your supervision tree. A second form, mix igniter.install jido --example, generates an example agent.
Manual installation is the ordinary Mix route: add jido to your dependency list in mix.exs, with the README's snippet beginning with the elixir code fence and listing jido as a dependency. Note that the supplied README excerpt is truncated at exactly that point, so the full manual snippet, including the version requirement and the application configuration keys, is not visible in the material available here. Treat the Igniter path as the documented default and read the Hex docs for the manual block before pinning a version.
What you get after installation is an instance module rather than a global application. That matters for multi-tenant work: the README mentions instance-scoped supervision plus logical partitions, and durable groups with partition-safe tenancy boundaries. The instance module is the unit those boundaries attach to.
Execution strategies and where the documentation thins out
Jido lists three levels of execution behaviour. Direct execution covers simple workflows. An FSM (Finite State Machine) strategy covers state-driven workflows. Beyond those, an extensible strategy protocol is offered for custom execution patterns. On top of that sit multi-agent workflows with configurable strategies and plan-based orchestration for complex workflows.
This is the part of the README that carries the least operational detail. The feature list names the strategies but does not show a strategy declaration, a module contract, or a worked example of switching between direct and FSM execution. The same is true of plan-based orchestration: it is named as a capability, and the shape of a plan is not described in the material available. That is not evidence the code is missing. It is evidence that the README is a feature inventory at this level, and that anyone choosing an execution strategy should read the Hex docs and the source rather than the project page.
A related gap is the ecosystem table. It lists req_llm as an HTTP client for LLM APIs, jido_action for composable validated actions with AI tool integration, jido_signal as a CloudEvents-based message envelope with routing and pub/sub utilities, jido itself as the core framework, and jido_ai for AI/LLM integration. The README points to jido.run/ecosystem for the package map and support levels, which implies support levels differ across packages. Which packages are covered by which level is not stated in the excerpt, so treat that page as required reading before you commit to a dependency set.
Directives are a boundary you can get wrong
The clearest failure mode in this design is misplacing an effect. The README's own rule is that an action may do work itself when the result is needed immediately, and should return a directive when the workflow has already decided on an outbound effect and wants the runtime to own delivery. Get that backwards and you lose the property the framework is selling. An action that quietly performs an outbound call becomes hard to reason about in isolation, and the runtime never sees the effect it was supposed to own.
The built-in directive list also constrains what the runtime will do for you out of the box: Emit, Spawn, SpawnAgent, StopChild, StartSensor, StopSensor, Schedule and Stop. Anything outside that set needs a custom directive through the protocol-based extension point, which is code you write and maintain. The README does not state a stability guarantee for that protocol, so a custom directive is a place where an upgrade can touch your code.
Two other limits are worth naming. The core package does not integrate with models; that lives in jido_ai, so a team expecting an agent framework with a model client included will need a second dependency and its own configuration. And the framework is built on GenServer, which the README acknowledges directly with the line that Jido is not better GenServer but a formalized agent pattern built on it. If your problem is one process with one loop, the formalization is overhead.
How Jido differs from LangGraph and from plain GenServer
The honest comparison is against two things, not one.
Against plain GenServer, the difference is formalization rather than capability. Both run on the BEAM. With GenServer you define your own message shapes, keep business logic in callbacks, and decide yourself when a process exiting means a task is done. Jido replaces those choices with a signal envelope, an action pattern, typed directives, a parent/child hierarchy and state-based completion. The cost is that you learn Jido's vocabulary and fit your problem into cmd/2. The benefit is that cooperating agents stop being a pile of conventions each team invents separately.
Against LangGraph, the difference is the runtime underneath. LangGraph models an agent as a graph of nodes and edges and is a Python library; its execution model and its deployment story are Python-shaped. Jido models an agent as an immutable struct with a command function and runs on OTP supervision trees, with instance-scoped supervision, logical partitions and parent-child lifecycle management as first-class concerns. If your operational tooling is Elixir releases, telemetry and OTP supervision, Jido fits into it. If your team is Python-first and your orchestration already lives in that ecosystem, adopting Jido means adopting a second runtime for the same job. The README does not benchmark Jido against either alternative, and this article does not claim one is faster.
Maintenance, versioning and the Apache-2.0 terms
Jido is licensed Apache-2.0, which permits commercial and closed-source use and includes an express patent grant, with the usual obligations around retaining notices and stating changes. That is a general description of the licence, not legal advice; have counsel review it if the patent grant or notice requirements matter to your distribution model.
The release cadence visible in the repository is steady: v2.3.1 in early June 2026, v2.3.2 in mid June, v2.3.3 in August, with the last push to the default branch in September 2026. Three patch releases inside a major line suggests active maintenance rather than a frozen project, and the project is not archived.
The upgrade cost is concentrated in the extension points rather than the core. If you only define agents, actions and the built-in directives, a patch upgrade is likely to be uneventful. If you have written custom directives against the protocol, custom execution strategies, or plugins that rely on automatic schema merging and per-plugin state isolation, those are the surfaces where a version bump can require edits. The README lists plugins as reusable capability modules that extend agents, with state isolation per plugin and automatic schema merging, but it does not describe the merge rules for conflicting keys. That is the first thing to check in the Hex docs before you build capabilities on top of it.
Editorial conclusion
Adopt Jido if your team already ships OTP services and needs cooperating agents with explicit state transitions, signals and runtime-owned effects; the installation path is mix igniter.install jido, which generates a MyApp.Jido instance module and wires it into your supervision tree. Do not adopt it if your requirement is a single LLM chat loop, since the core package contains no model integration and jido_ai is a separate dependency. Before committing, verify three things in the repository: which directive set your release actually ships, whether the Execution Strategies you need are documented as stable, and whether the plugin schema-merging rules match how you intend to isolate state per capability.
Community notes