langchain-rust: LangChain's composability model ported to Rust
🦜️🔗LangChain for Rust, the easiest way to write LLM-based programs in Rust
At a glance
- What is it?
- langchain-rust mirrors the LangChain abstractions in Rust, with LLM, embedding, vector store, chain, agent and loader traits behind one crate. The README lists broad provider coverage, but the port is partial and the async loader API has sharp edges.
- Who is it for?
- Adopt langchain-rust if you are building a Rust service that needs an LLM call, an embedding call, or a retrieval chain behind a stable trait boundary, and you are willing to read the examples because the docs are a tutorial site rather than a full API reference. Do not adopt it if you need LangGraph-style stateful orchestration or broad third-party integration coverage; the README does not list those.
- Can I use it commercially?
- Yes. MIT 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 8 days ago.
- What is it written in?
- Mainly Rust, 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 problem langchain-rust solves for Rust services
Rust has HTTP clients for every LLM API, but it does not have a shared vocabulary for what sits above them. A team that wants a prompt template, a retriever and a vector store in one pipeline ends up writing the same glue in every project: request structs, response parsing, retry logic, and a hand-rolled trait to swap providers in tests. langchain-rust is an attempt to put that vocabulary in one crate. The README describes it as "the Rust language implementation of LangChain", and the feature list reads like the Python project's table of contents: LLMs, embeddings, vector stores, chains, agents, tools, semantic routing, document loaders. The intended audience is a Rust developer who already knows what a retrieval chain is and wants the pieces to compose without leaving the type system. It is not a framework for people who have not built an LLM pipeline before. The examples directory is the real documentation, and the README links to a file per feature rather than explaining concepts in prose.
The trait-based architecture and how a chain is assembled
The design is a set of traits with provider-specific implementations behind them. The LLM list covers OpenAI, Azure OpenAI, Ollama and Anthropic Claude. Embeddings cover OpenAI, Azure OpenAI, Ollama, FastEmbed for local inference, and MistralAI. Vector stores cover OpenSearch, Postgres, Qdrant, Sqlite (via the sqlite-vss example) and SurrealDB. Because the providers are implementations of the same interface, a chain written against the trait does not name OpenAI anywhere. The chain layer is where this pays off. The README lists an LLM Chain, a Conversational Chain, a Conversational Retriever Simple, a Conversational Retriever With Vector Store, a Sequential Chain, a Q&A Chain and an SQL Chain. The conversational retriever chain with a vector store is the one that matters for retrieval-augmented generation: it takes a retriever, a vector store and a conversation history, and it is the composition that most teams would otherwise build by hand. Agents are split into a chat agent with tools and an OpenAI-compatible tools agent, with tools for Serpapi/Google, DuckDuckGo, Wolfram/Math, the command line, and text-to-speech. Semantic routing comes in static and dynamic variants, which is a smaller surface than the Python project's router, but it exists as a named feature rather than an example of prompt engineering.
Getting it running: the crate, the examples and the loader API
The README points at crates.io for the package name langchain-rust, and the badge links to the crate page. The quickstart lives at langchain-rust.sellie.tech/get-started/quickstart, and a Discord invite is in the header. The repository's examples directory is organized by feature, with one file per integration, for example examples/llm_openai.rs, examples/embedding_fastembed.rs, examples/vector_store_qdrant.rs and examples/conversational_retriever_chain_with_vector_store.rs. The document loaders are the only place the README shows code, and the pattern is consistent across all of them. You construct a loader from a path, call .load() to get a stream, then collect it. The PDF example uses PdfExtractLoader::from_path(path) with a commented-out LoPdfLoader alternative, then .load().await, then a .map(|d| d.unwrap()).collect::<Vec<_>>().await. The Pandoc example takes an InputFormat and a path. The HTML loader takes a path and a parsed Url. The HTML-to-Markdown loader adds HtmlToMarkdownOptions::default().with_skip_tags(vec!["figure".to_string()]). The CSV loader takes a path and an explicit vector of column names as strings. The Git commit loader takes a repository path. The shape never changes: from_path, load, stream, collect. That consistency is the strongest signal in the README about how the crate is meant to be used.
The load() stream is the sharpest edge in the API
Look closely at the loader examples, because they encode a real constraint. The return type of .load().await is not a Vec<Document>. It is a stream of Results, and the examples immediately call .map(|d| d.unwrap()) before collecting. That unwrap is in the official example code. It means the documented happy path discards per-document errors: a single malformed PDF page or a CSV row that fails to parse will panic rather than surface as an error the caller can handle. A production loader would need to collect into a Vec<Result<Document, _>> and decide per item, which is more code than the README shows. The second edge is the stream itself. Every loader example starts with use futures_util::StreamExt, which tells you the crate expects the caller to bring futures-util and to understand stream combinators. That is a reasonable choice for a Rust-native API, but it is a different mental model from the Python project's list-returning loaders, and it makes the loader layer harder to wrap in a simple function. The third edge is the CSV loader's explicit column list: headers are not inferred, so a schema change in the source file is a code change.
Where the port is thinner than the Python original
The README's feature list is a checklist of what has been ported, and the gaps are visible by omission. There is no LangGraph equivalent, no stateful graph execution, no checkpointing, and no human-in-the-loop primitive. The chain set is a fixed list of seven named chains rather than a general composition DSL, so a pipeline that does not match one of them means writing your own orchestration. The tool set is five entries: Serpapi/Google, DuckDuckGo, Wolfram/Math, command line, and text-to-speech. The Python project's integration count is not comparable, and the README makes no claim that it is. LLM providers are four (OpenAI, Azure OpenAI, Ollama, Claude), embeddings are five, vector stores are five. If your stack uses a provider outside those lists, this crate does not help you, and you are back to writing the HTTP layer yourself. That is the honest boundary of the project. It is a port of the core abstractions, not a port of the ecosystem.
An alternative: calling provider SDKs directly
The realistic alternative is not another Rust LangChain port. It is the provider's own crate or a thin HTTP client, plus your own traits. The difference is where the abstraction lives. With langchain-rust, the abstraction is in the crate: you get a VectorStore trait and a Chain trait defined by someone else, and you adapt your code to them. With direct SDK calls, you define the two or three traits your application actually needs, which for most services is one method for completion and one for embedding. The direct approach costs you the chain implementations, the document loaders and the semantic routing, and it costs you the ability to swap providers by changing a type parameter. It buys you a dependency surface you control, no futures-util stream handling unless you want it, and error types that match your application. For a service that calls one provider and stores vectors in one database, the direct route is less code than the README's examples suggest, because the examples carry the generality of the trait layer. For a service that needs to run the same pipeline against Ollama in development and OpenAI in production, langchain-rust earns its keep.
Maintenance, release cadence and the MIT licence
The recent release list shows v4.6.0 and v4.5.0 both dated 2024-10-06, and v4.4.2 dated 2024-09-10. Two releases on the same day suggests a fix landed quickly after a version bump, which is normal for a project of this size. The last push recorded for the repository is 2026-09-08, so the project is not archived and is receiving commits. There is no homepage field, so the tutorial site at langchain-rust.sellie.tech is the documentation entry point, and it is separate from the repository. The licence is MIT, which permits commercial use and modification provided the copyright notice and permission notice are included; this is a statement about the licence text, not legal advice, and anyone embedding the crate in a distributed product should read the LICENSE file in the repository. The practical upgrade cost is the trait surface. Because providers are trait implementations, a breaking change to a trait signature propagates to every custom implementation in your codebase, not just to the crate's own code. Pin the version in Cargo.toml and read the changelog between majors.
Editorial conclusion
Adopt langchain-rust if you are building a Rust service that needs an LLM call, an embedding call, or a retrieval chain behind a stable trait boundary, and you are willing to read the examples because the docs are a tutorial site rather than a full API reference. Do not adopt it if you need LangGraph-style stateful orchestration or broad third-party integration coverage; the README does not list those. Before committing, verify that the specific provider and vector store you need are in the feature list, and check the crate version on crates.io against the v4.6.0 release, since the README does not state a minimum supported Rust version.
Community notes