š¤ Autonomous agent framework for Elixir. Built for distributed, autonomous behavior and dynamic workflows.
See the codeJido is an autonomous agent framework for Elixir, built for workflows and multi-agent systems.
Define agents, connect them to actions, signals, and directives, and run them with supervision and fault tolerance built in.
The name "Jido" (čŖå) comes from the Japanese word meaning "automatic" or "automated", where čŖ (ji) means "self" and å (dÅ) means "movement".
Learn more about Jido at jido.run.
Jido helps you build agent systems as ordinary Elixir and OTP software.
cmd/2The purity boundary is the agent's decision logic: Jido keeps agent decisions and state transitions explicit, actions may be pure or effectful, and directives are for effects you want the runtime to own.
Use Jido when software needs to inspect context, choose among multiple steps, coordinate with other agents, and keep running reliably over time.
AI is optional. The core package gives you the agent architecture and runtime;
companion packages such as jido_ai add model integration when you need it.
At the core, Jido agents are immutable data structures with a single command function:
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)
State changes are explicit data transformations. If an action needs a result back immediately to continue reasoning or 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, return a directive.
Jido is the core package of the Jido ecosystem. The ecosystem is built around the core Jido Agent behavior and offer several opt-in packages to extend the core behavior.
| Package | Description |
|---|---|
| req_llm | HTTP client for LLM APIs |
| jido_action | Composable, validated actions with AI tool integration |
| jido_signal | CloudEvents-based message envelope and supporting utilities for routing and pub/sub messaging |
| jido | Core agent framework with state management, directives, and runtime |
| jido_ai | AI/LLM integration for agents |
For demos and examples of what you can build with the Jido Ecosystem, see https://jido.run. For the package map and support levels, see https://jido.run/ecosystem.
OTP primitives are excellent. You can build agent systems with raw GenServer. But when building multiple cooperating agents, you'll reinvent:
| Raw OTP | Jido Formalizes |
|---|---|
| Ad-hoc message shapes per GenServer | Signals as standard envelope |
| Business logic mixed in callbacks | Actions as reusable command pattern |
| Implicit effects scattered in code | Directives as typed effect descriptions |
| Custom child tracking per server | Built-in parent/child hierarchy |
| Process exit = completion | State-based completion semantics |
Jido isn't "better GenServer" - it's a formalized agent pattern built on GenServer.
cmd/2 as the core operation: actions in, updated agent + directives outThe fastest way to get started is with Igniter:
mix igniter.install jido
This automatically:
MyApp.Jido instance module (use Jido, otp_app: :my_app)config/config.exsMyApp.Jido to your supervision treeGenerate an example agent to get started:
mix igniter.install jido --example
Add jido to your list of dependencies in mix.exs:
def deps do
[
{:jido, "~> 2.0"}
]
end
Then define a Jido instance module and add it to your supervision tree:
# In lib/my_app/jido.ex
defmodule MyApp.Jido do
use Jido, otp_app: :my_app
end
# In config/config.exs
config :my_app, MyApp.Jido,
max_tasks: 1000,
agent_pools: []
# In your application.ex
children = [
MyApp.Jido
]
Supervisor.start_link(children, strategy: :one_for_one)
defmodule MyApp.CounterAgent do
use Jido.Agent,
name: "counter",
description: "A simple counter agent",
schema: [
count: [type: :integer, default: 0]
],
signal_routes: [
{"increment", MyApp.Actions.Increment}
]
end
defmodule MyApp.Actions.Increment do
use Jido.Action,
name: "increment",
description: "Increments the counter by a given amount",
schema: [
amount: [type: :integer, default: 1]
]
def run(params, context) do
current = context.state[:count] || 0
{:ok, %{count: current + params.amount}}
end
end
# Create an agent
agent = MyApp.CounterAgent.new()
# Execute an action - returns updated agent + directives
{agent, directives} = MyApp.CounterAgent.cmd(agent, {MyApp.Actions.Increment, %{amount: 5}})
# Check the state
agent.state.count
# => 5
# Start the agent server
{:ok, pid} = MyApp.Jido.start_agent(MyApp.CounterAgent, id: "counter-1")
# Send signals to the running agent (synchronous)
# Signal types must be declared in signal_routes
{:ok, agent} = Jido.AgentServer.call(pid, Jido.Signal.new!("increment", %{amount: 10}, source: "/user"))
# Look up the agent by ID
pid = MyApp.Jido.whereis("counter-1")
# List all running agents
agents = MyApp.Jido.list_agents()
cmd/2 ContractThe fundamental operation in Jido:
{agent, directives} = MyAgent.cmd(agent, action)
Key invariants:
agent is always complete - no "apply directives" step neededdirectives describe runtime-owned external effects only - they never modify
agent statecmd/2 resultsUse this rule of thumb for side effects:
| Actions | Directives | State Operations |
|---|---|---|
| Transform state, may perform side effects | Describe runtime-owned effects | Describe internal state changes |
Executed by cmd/2, update agent.state | Bare structs emitted by agents | Applied by strategy layer |
| Can call APIs, read files, query databases | Runtime (AgentServer) interprets them | Never leave the strategy |
Jido.Agent.StateOp)State operations are internal state transitions handled by the strategy layer during cmd/2. Unlike directives, they never reach the runtime.
| StateOp | Purpose |
|---|---|
SetState | Deep merge attributes into state |
ReplaceState | Replace state wholesale |
DeleteKeys | Remove top-level keys |
SetPath | Set value at nested path |
DeletePath | Delete value at nested path |
| Directive | Purpose |
|---|---|
Emit | Dispatch a signal via configured adapters |
Error | Signal an error from cmd/2 |
Spawn | Spawn a generic BEAM child process |
SpawnAgent | Spawn a tracked child Jido agent (restart: :transient by default) |
StopChild | Gracefully stop and remove a tracked child agent |
StartSensor | Start or replace a tagged sensor runtime |
StopSensor | Stop a tagged sensor runtime |
Schedule | Schedule a delayed message |
Stop | Stop the agent process |
Sensor runtimes started by StartSensor are tracked under {:sensor, tag} and
are owner-monitored by default. Unexpected sensor exits emit
jido.agent.sensor.exit back to the owning agent; controlled StopSensor
shutdowns do not. Use link?: true only when a sensor should fail fast with
its owning AgentServer.
Start here:
Guides:
SpawnAgent, InstanceManager, Pod, and partitionAdvanced:
API Reference: hexdocs.pm/jido
Q: What is Jido and how does it differ from other agent frameworks?
A: Jido is an autonomous agent framework for Elixir, built for workflows and multi-agent systems. Key differentiators:
Compared to LangChain/CrewAI:
Q: What is the Agent/Action/Signal/Directive architecture?
A:
cmd/2cmd/2 returns the updated agent plus directives. Directives never mutate agent
state; the OTP runtime interprets them for runtime-owned external effects.
Actions may still perform work such as API calls, file I/O, or database queries
when that result is needed immediately by the action or state transition.
Q: Is AI required for Jido?
A: No! The core package (jido) provides agent architecture and runtime without AI. AI/LLM integration is optional via companion packages:
jido_ai: AI/LLM integration for agentsreq_llm: HTTP client for LLM APIsUse Jido when software needs to inspect context, choose steps, coordinate agents, and run reliably - AI is optional.
Q: What are the Jido ecosystem packages?
A:
| Package | Description |
|---|---|
| req_llm | HTTP client for LLM APIs |
| jido_action | Composable, validated actions with AI tool integration |
| jido_signal | CloudEvents-based message envelope and routing utilities |
| jido | Core agent framework with state management, directives, runtime |
| jido_ai | AI/LLM integration for agents |
Q: How do I install Jido?
A: Jido is available on Hex.pm:
def deps do
[
{:jido, "~> 2.0"}
]
end
See jido.run for demos and examples.
Q: How do I create an agent?
A:
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)
See hexdocs.pm/jido for API reference.
Q: How do I run agents in production?
A: Use AgentServer (GenServer-based) for production deployment:
Q: What directives are available?
A: Built-in directives:
cmd/2cmd/2External packages can also define custom directive structs. See Agent Directives for details.
Q: How do plugins work?
A: Composable plugins extend agents with:
See Plugins Guide for details.
Q: What execution strategies are available?
A:
See Strategies Guide and FSM Strategy Deep Dive.
Q: I'm getting GenServer timeout errors. What should I check?
A:
guides/worker-pools.md)Q: My agents aren't receiving signals. What's wrong?
A:
mix test
mix quality # Runs formatter, dialyzer, and credo
mix docs
HTML and Markdown documentation is generated in doc/, including Markdown pages and llms.txt.
We welcome contributions! Please see our Contributing Guide for details on:
Copyright 2024-2025 Mike Hostetler
Licensed under the Apache License, Version 2.0. See LICENSE for details.
(top 24 of 44)
2,943 followers Ā· starred Apr 2025
170 followers Ā· starred Feb 2026
146 followers Ā· starred Jan 2025
287 followers Ā· starred Feb 2026
š¤ Autonomous agent framework for Elixir. Built for distributed, autonomous behavior and dynamic workflows.
See the codeJido is an autonomous agent framework for Elixir, built for workflows and multi-agent systems.
Define agents, connect them to actions, signals, and directives, and run them with supervision and fault tolerance built in.
The name "Jido" (čŖå) comes from the Japanese word meaning "automatic" or "automated", where čŖ (ji) means "self" and å (dÅ) means "movement".
Learn more about Jido at jido.run.
Jido helps you build agent systems as ordinary Elixir and OTP software.
cmd/2The purity boundary is the agent's decision logic: Jido keeps agent decisions and state transitions explicit, actions may be pure or effectful, and directives are for effects you want the runtime to own.
Use Jido when software needs to inspect context, choose among multiple steps, coordinate with other agents, and keep running reliably over time.
AI is optional. The core package gives you the agent architecture and runtime;
companion packages such as jido_ai add model integration when you need it.
At the core, Jido agents are immutable data structures with a single command function:
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)
State changes are explicit data transformations. If an action needs a result back immediately to continue reasoning or 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, return a directive.
Jido is the core package of the Jido ecosystem. The ecosystem is built around the core Jido Agent behavior and offer several opt-in packages to extend the core behavior.
| Package | Description |
|---|---|
| req_llm | HTTP client for LLM APIs |
| jido_action | Composable, validated actions with AI tool integration |
| jido_signal | CloudEvents-based message envelope and supporting utilities for routing and pub/sub messaging |
| jido | Core agent framework with state management, directives, and runtime |
| jido_ai | AI/LLM integration for agents |
For demos and examples of what you can build with the Jido Ecosystem, see https://jido.run. For the package map and support levels, see https://jido.run/ecosystem.
OTP primitives are excellent. You can build agent systems with raw GenServer. But when building multiple cooperating agents, you'll reinvent:
| Raw OTP | Jido Formalizes |
|---|---|
| Ad-hoc message shapes per GenServer | Signals as standard envelope |
| Business logic mixed in callbacks | Actions as reusable command pattern |
| Implicit effects scattered in code | Directives as typed effect descriptions |
| Custom child tracking per server | Built-in parent/child hierarchy |
| Process exit = completion | State-based completion semantics |
Jido isn't "better GenServer" - it's a formalized agent pattern built on GenServer.
cmd/2 as the core operation: actions in, updated agent + directives outThe fastest way to get started is with Igniter:
mix igniter.install jido
This automatically:
MyApp.Jido instance module (use Jido, otp_app: :my_app)config/config.exsMyApp.Jido to your supervision treeGenerate an example agent to get started:
mix igniter.install jido --example
Add jido to your list of dependencies in mix.exs:
def deps do
[
{:jido, "~> 2.0"}
]
end
Then define a Jido instance module and add it to your supervision tree:
# In lib/my_app/jido.ex
defmodule MyApp.Jido do
use Jido, otp_app: :my_app
end
# In config/config.exs
config :my_app, MyApp.Jido,
max_tasks: 1000,
agent_pools: []
# In your application.ex
children = [
MyApp.Jido
]
Supervisor.start_link(children, strategy: :one_for_one)
defmodule MyApp.CounterAgent do
use Jido.Agent,
name: "counter",
description: "A simple counter agent",
schema: [
count: [type: :integer, default: 0]
],
signal_routes: [
{"increment", MyApp.Actions.Increment}
]
end
defmodule MyApp.Actions.Increment do
use Jido.Action,
name: "increment",
description: "Increments the counter by a given amount",
schema: [
amount: [type: :integer, default: 1]
]
def run(params, context) do
current = context.state[:count] || 0
{:ok, %{count: current + params.amount}}
end
end
# Create an agent
agent = MyApp.CounterAgent.new()
# Execute an action - returns updated agent + directives
{agent, directives} = MyApp.CounterAgent.cmd(agent, {MyApp.Actions.Increment, %{amount: 5}})
# Check the state
agent.state.count
# => 5
# Start the agent server
{:ok, pid} = MyApp.Jido.start_agent(MyApp.CounterAgent, id: "counter-1")
# Send signals to the running agent (synchronous)
# Signal types must be declared in signal_routes
{:ok, agent} = Jido.AgentServer.call(pid, Jido.Signal.new!("increment", %{amount: 10}, source: "/user"))
# Look up the agent by ID
pid = MyApp.Jido.whereis("counter-1")
# List all running agents
agents = MyApp.Jido.list_agents()
cmd/2 ContractThe fundamental operation in Jido:
{agent, directives} = MyAgent.cmd(agent, action)
Key invariants:
agent is always complete - no "apply directives" step neededdirectives describe runtime-owned external effects only - they never modify
agent statecmd/2 resultsUse this rule of thumb for side effects:
| Actions | Directives | State Operations |
|---|---|---|
| Transform state, may perform side effects | Describe runtime-owned effects | Describe internal state changes |
Executed by cmd/2, update agent.state | Bare structs emitted by agents | Applied by strategy layer |
| Can call APIs, read files, query databases | Runtime (AgentServer) interprets them | Never leave the strategy |
Jido.Agent.StateOp)State operations are internal state transitions handled by the strategy layer during cmd/2. Unlike directives, they never reach the runtime.
| StateOp | Purpose |
|---|---|
SetState | Deep merge attributes into state |
ReplaceState | Replace state wholesale |
DeleteKeys | Remove top-level keys |
SetPath | Set value at nested path |
DeletePath | Delete value at nested path |
| Directive | Purpose |
|---|---|
Emit | Dispatch a signal via configured adapters |
Error | Signal an error from cmd/2 |
Spawn | Spawn a generic BEAM child process |
SpawnAgent | Spawn a tracked child Jido agent (restart: :transient by default) |
StopChild | Gracefully stop and remove a tracked child agent |
StartSensor | Start or replace a tagged sensor runtime |
StopSensor | Stop a tagged sensor runtime |
Schedule | Schedule a delayed message |
Stop | Stop the agent process |
Sensor runtimes started by StartSensor are tracked under {:sensor, tag} and
are owner-monitored by default. Unexpected sensor exits emit
jido.agent.sensor.exit back to the owning agent; controlled StopSensor
shutdowns do not. Use link?: true only when a sensor should fail fast with
its owning AgentServer.
Start here:
Guides:
SpawnAgent, InstanceManager, Pod, and partitionAdvanced:
API Reference: hexdocs.pm/jido
Q: What is Jido and how does it differ from other agent frameworks?
A: Jido is an autonomous agent framework for Elixir, built for workflows and multi-agent systems. Key differentiators:
Compared to LangChain/CrewAI:
Q: What is the Agent/Action/Signal/Directive architecture?
A:
cmd/2cmd/2 returns the updated agent plus directives. Directives never mutate agent
state; the OTP runtime interprets them for runtime-owned external effects.
Actions may still perform work such as API calls, file I/O, or database queries
when that result is needed immediately by the action or state transition.
Q: Is AI required for Jido?
A: No! The core package (jido) provides agent architecture and runtime without AI. AI/LLM integration is optional via companion packages:
jido_ai: AI/LLM integration for agentsreq_llm: HTTP client for LLM APIsUse Jido when software needs to inspect context, choose steps, coordinate agents, and run reliably - AI is optional.
Q: What are the Jido ecosystem packages?
A:
| Package | Description |
|---|---|
| req_llm | HTTP client for LLM APIs |
| jido_action | Composable, validated actions with AI tool integration |
| jido_signal | CloudEvents-based message envelope and routing utilities |
| jido | Core agent framework with state management, directives, runtime |
| jido_ai | AI/LLM integration for agents |
Q: How do I install Jido?
A: Jido is available on Hex.pm:
def deps do
[
{:jido, "~> 2.0"}
]
end
See jido.run for demos and examples.
Q: How do I create an agent?
A:
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)
See hexdocs.pm/jido for API reference.
Q: How do I run agents in production?
A: Use AgentServer (GenServer-based) for production deployment:
Q: What directives are available?
A: Built-in directives:
cmd/2cmd/2External packages can also define custom directive structs. See Agent Directives for details.
Q: How do plugins work?
A: Composable plugins extend agents with:
See Plugins Guide for details.
Q: What execution strategies are available?
A:
See Strategies Guide and FSM Strategy Deep Dive.
Q: I'm getting GenServer timeout errors. What should I check?
A:
guides/worker-pools.md)Q: My agents aren't receiving signals. What's wrong?
A:
mix test
mix quality # Runs formatter, dialyzer, and credo
mix docs
HTML and Markdown documentation is generated in doc/, including Markdown pages and llms.txt.
We welcome contributions! Please see our Contributing Guide for details on:
Copyright 2024-2025 Mike Hostetler
Licensed under the Apache License, Version 2.0. See LICENSE for details.
(top 24 of 44)
2,943 followers Ā· starred Apr 2025
170 followers Ā· starred Feb 2026
146 followers Ā· starred Jan 2025
287 followers Ā· starred Feb 2026