brainlid/langchain: an Elixir LLM framework that does not chase Python parity
Elixir implementation of a LangChain style framework that lets Elixir projects integrate with and leverage LLMs.
At a glance
- What is it?
- brainlid/langchain brings a LangChain-style component model to Elixir applications, with adapters for Anthropic, OpenAI, Gemini, Ollama and Bumblebee. The README is explicit that it does not aim for parity with the JavaScript and Python libraries, and that decision shapes what you get.
- Who is it for?
- Adopt brainlid/langchain if your application is already Elixir and you want LLM calls to live in the same supervision tree as the rest of your system, with chat adapters for Anthropic, OpenAI, Gemini, xAI, Ollama, Bumblebee and others. Do not adopt it if you need serialized prompt or chain objects shared with a Python or JS service, or if you want the ecosystem of integrations the Python library has.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 6 days 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 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What brainlid/langchain is for, and who it is not for
This is an Elixir library that lets an Elixir application talk to large language models through a shared set of abstractions. The README frames the value in two parts: components, meaning modular abstractions for working with models, and off-the-shelf chains, meaning pre-assembled structures for common higher-level tasks. The stated goal is that components stay usable whether or not you adopt the rest of the framework.
The intended audience is narrow in a useful way. If your application is Elixir and you want to call Claude, GPT, Gemini, Grok, DeepSeek, Mistral or Perplexity from inside it, this library gives you one dependency instead of one HTTP client per provider. It also covers self-hosted models through Ollama and Bumblebee, and multi-provider routing through ReqLLM.
The README is equally clear about who it is not for. It says the Elixir version does not aim for parity with LangChain JS/TS or LangChain Python, for two stated reasons: those languages are object oriented and Elixir is functional, and the JS and Python versions predate conversational LLMs so they carry machinery for preserving history that the model itself now handles. If you need objects that serialize and move between Python and JavaScript services, this library is the wrong side of that boundary.
How the Elixir LangChain architecture splits providers from chains
The architecture visible in the README is a provider adapter layer under a common chat interface. Supported chat models include Anthropic Claude (with extended thinking and AWS Bedrock), AWS Bedrock Mantle as an OpenAI-compatible gateway, OpenAI ChatGPT through Chat Completions, the newer OpenAI Responses API with WebSocket transport support, Cloudflare Workers AI through ChatOpenAI, xAI Grok, Google Gemini, Google Vertex AI, DeepSeek with prompt caching, Ollama, Mistral, Perplexity, orq.ai, Bumblebee for self-hosted Nx models, and ReqLLM as a multi-provider adapter.
That list is the design. Each provider is a module behind the same chat abstraction, so switching from a hosted API to a local Ollama model is a module change rather than a rewrite of your call sites. Cloudflare Workers AI and Bedrock Mantle are handled by pointing the OpenAI-compatible client at a different gateway, which is why they appear as gateways rather than as separate provider implementations.
HTTP goes through Req, which the README states directly: the library is written to use the Req library for making API calls. That is a meaningful constraint, because it means Req is in your dependency tree and its behaviour, including middleware and retry configuration, is part of how requests leave your application.
Prompt caching is called out separately. The README notes that ChatGPT, Claude and DeepSeek all offer prefix-based prompt caching, which can offer cost and performance benefits for longer prompts. The library exposes that rather than hiding it, so prompt construction order matters: a stable prefix is what makes the cache hit.
Installing brainlid/langchain and making a first call
The README states the requirement plainly: Elixir 1.17 or higher. Add the package to your dependency list in mix.exs. The README shows this snippet, and note that the version constraint in the example is older than the most recent release listed in the repository.
def deps do
[
{:langchain, "~> 0.9.0"}
]
endConfiguration goes in config/runtime.exs. The README gives both a direct value and an environment lookup, and it also documents a tuple or function form for resolving secrets at call time.
config :langchain, openai_key: System.fetch_env!("OPENAI_API_KEY")
config :langchain, openai_org_id: System.fetch_env!("OPENAI_ORG_ID")
# OR
config :langchain, openai_key: "YOUR SECRET KEY"
config :langchain, openai_org_id: "YOUR_OPENAI_ORG_ID"
config :langchain, :anthropic_key, System.fetch_env!("ANTHROPIC_API_KEY")
config :langchain, :xai_api_key, System.fetch_env!("XAI_API_KEY")The README also shows the resolver form, where a tuple names a module and function or an anonymous function is called to produce the value:
config :langchain, openai_key: {MyApp.Secrets, :openai_api_key, []}
config :langchain, openai_org_id: {MyApp.Secrets, :openai_org_id, []}
# OR
config :langchain, openai_key: fn -> System.fetch_env!("OPENAI_API_KEY") end
config :langchain, openai_org_id: fn -> System.fetch_env!("OPENAI_ORG_ID") endThe repository ships a .env.example listing the variables it expects, including OPENAI_API_KEY, OPENAI_ORG_ID, ANTHROPIC_API_KEY, GOOGLE_API_KEY, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_KEY, PERPLEXITY_API_KEY, MISTRAL_API_KEY, VERTEX_API_KEY, VERTEX_API_ENDPOINT, DEEPSEEK_API_KEY, XAI_API_KEY, AWS_BEARER_TOKEN_BEDROCK, CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN. Treat those as secrets; the README says so and shows the fly.io form for setting them.
fly secrets set OPENAI_API_KEY=MyOpenAIApiKey
fly secrets set ANTHROPIC_API_KEY=MyAnthropicApiKey
fly secrets set XAI_API_KEY=MyXaiApiKeyFor a working end-to-end example, the README points at a separate demo project, brainlid/langchain_demo, rather than inlining a full script. That is where to look before writing your own chain, because the README itself stops at configuration.
Where brainlid/langchain will not behave like LangChain Python
The parity decision has concrete consequences. In the Python and JavaScript libraries, prompts, LLMs and chains are designed to be serialized and shared between the two languages. The README states the Elixir version does not aim for that. If your architecture assumes a Python service produces a chain definition that an Elixir service consumes, this library does not give you that path, and no amount of configuration will produce it.
The second consequence is history handling. The README says the JS and Python versions put effort into preserving conversation history because they started before conversational LLMs were standard. The Elixir library does not do that work. If you are porting an application that depends on the older library's history-preservation semantics, expect to rebuild that layer yourself.
The README also does not document rollback, migration or upgrade procedures, and there is no compatibility statement about moving between the 0.12 and 0.13 lines. The repository does carry a CHANGELOG.md, so that file is the place to check before bumping the dependency, not the README.
Finally, the licence field on the repository reads NOASSERTION rather than a recognised identifier. That means the licence terms are not machine-classified, and the LICENSE file in the repository root is the only reliable place to read them. Anyone planning to redistribute the library should read that file rather than assume a licence from the package metadata.
brainlid/langchain compared with LangChain Python and LangGraph
The honest comparison is not feature-for-feature, because the README refuses that framing. LangChain Python and LangChain JS/TS are the original libraries, and their design assumes objects that serialize across languages. LangGraph, which people search for alongside LangChain, is a separate graph-oriented way of expressing agent control flow; this Elixir library's README does not describe an equivalent graph runtime, so if your design depends on that style of orchestration, this is not the replacement.
The real difference is language-level. In Python you get the largest integration surface and the most third-party material. In Elixir you get calls that live inside OTP. That matters when an LLM call needs to be a supervised process, when you want to fan out to several providers from one BEAM node, or when the rest of your system is already there and adding a Python sidecar would mean a second runtime, a second deploy and a second set of secrets.
The trade is integration breadth for runtime coherence. A team that already runs Python for data work will find the Python library cheaper. A team whose product is an Elixir service will find a Python sidecar more expensive than it looks, and this library is the option that avoids it. The README's provider list is long enough that the breadth argument is weaker than it was, but it is not the same breadth.
Maintenance, releases and what to check before upgrading
The repository is not archived, and the last push was on 2026-09-09. The release history shows v0.13.1 on 2026-08-26, v0.13.0 on 2026-08-23 and v0.12.0 on 2026-08-22. Three releases inside a week is a fast-moving 0.x line, and the version numbers themselves say the API is not yet stable.
That cadence is the upgrade cost. On a 0.x library, a minor bump can change behaviour, and the README does not document a migration path between versions. The repository does include CHANGELOG.md, so the practical routine is to read it before moving the constraint in mix.exs. The README's own dependency example still shows "~> 0.9.0", which is behind the current line; that is a documentation lag worth knowing about when you copy the snippet.
There is also maintenance surface outside the library. Because HTTP goes through Req, and because each provider adapter tracks a vendor API, your dependency graph inherits both. The repository carries AGENTS.md, CLAUDE.md, usage-rules.md and MODEL_BEHAVIORS.md at the top level, which suggests the project documents model-specific behaviour separately from the README. If you hit a provider quirk, MODEL_BEHAVIORS.md is the file to read first.
On licensing: the repository's licence field is NOASSERTION, so read LICENSE directly. Nothing here is legal advice, and the terms in that file govern what you may do with the code.
Editorial conclusion
Adopt brainlid/langchain if your application is already Elixir and you want LLM calls to live in the same supervision tree as the rest of your system, with chat adapters for Anthropic, OpenAI, Gemini, xAI, Ollama, Bumblebee and others. Do not adopt it if you need serialized prompt or chain objects shared with a Python or JS service, or if you want the ecosystem of integrations the Python library has. Before writing production code, verify two things in the repository: which chat model module matches your provider, and how the library resolves API keys from your config, since the README shows both direct values and function or tuple resolvers.
Frequently asked questions
What exactly does brainlid/langchain do?
It is an Elixir implementation of a LangChain style framework that lets Elixir applications integrate with LLMs and self-hosted models. It provides components for working with language models plus off-the-shelf chains for higher-level tasks, with chat adapters for Anthropic, OpenAI, Gemini, xAI, DeepSeek, Ollama, Bumblebee and others.
Is brainlid/langchain a library or a framework?
The README calls it a framework for developing applications powered by language models, and describes its main value as components plus off-the-shelf chains. In practice you can use the components on their own without adopting the rest of the framework, which the README states explicitly.
How do I install brainlid/langchain?
Add {:langchain, "~> 0.9.0"} to your deps in mix.exs and run mix deps.get. The README states the requirement is Elixir 1.17 or higher.
How do I use brainlid/langchain with Ollama?
Ollama is listed among the supported chat models for locally hosted open-source models. Configuration follows the same pattern as the other providers, with keys supplied through config/runtime.exs.
How do I use brainlid/langchain with Claude or Gemini?
Both are listed as supported chat models, Anthropic Claude with extended thinking and AWS Bedrock, and Google Gemini alongside Google Vertex AI. The README shows the Anthropic key configured in config/runtime.exs as :anthropic_key.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/brainlid-langchain)
Community notes