Model or dataset
BoundaryML/baml avatar
BoundaryML/baml

BAML: A Type-Safe Programming Language for Agents

The programming language for agents

9,508 stars519 forksRustApache-2.0

At a glance

What is it?
BoundaryML's BAML is a Rust-based programming language for agents whose types persist at runtime. It targets teams who want agents to make fewer mistakes, with typed, statically analyzed errors.
Who is it for?
Adopt BAML if your team spends too much time on brittle output parsing and wants compile-time guarantees around model responses, especially if you already use TypeScript, Python, or Go and can tolerate a nightly release cadence. Skip it if you need a stable, versioned language for agentic control flow.
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 received new commits within the last day.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • BoundaryML/baml9,508 ★ · +344
Star history
Repository2026-09-102026-11-14
BoundaryML/baml9.2k9.5k

344 Stars in the last 65 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

What BAML Actually Solves

BAML positions itself as the programming language for agents, but the README's list of features points at a narrower problem: unreliable, untyped output from large language models. Every feature, from the Rust-like type system to runtime-persistent types and typed errors, targets the moment where an agent returns a string and your code has to turn it into a struct. The pitch is that agents make fewer mistakes when the language makes it impossible to treat an output as an untyped blob. The intended user is a developer who calls models from TypeScript, Python, Go, C#, or Java and is tired of writing validation layers by hand. There is no mention of planning, tool selection, or memory in the README. The README does list a built-in stdlib for agents and says BAML can be run standalone or adopted incrementally.

The Mechanism: Types That Survive Runtime

The core architectural claim is that types persist at runtime. In most compiled languages, types are erased or only used for static checking. BAML says there is no `any` and no casting that can silently corrupt data. That means when a model returns a JSON-like response, BAML can validate it against the declared type at runtime, not just assume the shape matches. The README also mentions typed errors that are statically analyzed. Static analysis of errors is a meaningful difference from a plain JSON schema validator. The filesystem defines modules and namespaces. It also claims green threads and colorless concurrency like Go, though the README gives no example of how that works in practice. The type system is described as compiling faster than Go, but no benchmark supports that claim, so treat it as a marketing statement until you measure it.

Getting Started: Commands You Can Run

The README gives a short, concrete path to a first BAML project. On macOS, the install command is `brew install baml`. After that, you run `baml agent install`, which the README does not explain. Then `baml init` creates a new project scaffold. Finally, `baml ide install --code` installs the IDE extension for Visual Studio Code. The quickstart link on the homepage is the next step, but the README does not reproduce its contents. There is no mention of how to define your first function, how to call a model, or what a BAML file looks like. If you want to see syntax or a full example, you have to visit the website. That is a gap in the README, but the commands themselves are simple and should get a user to a working editor within a few minutes.

Incremental Adoption and Language Bindings

A key design decision is that you can call a BAML function from TypeScript, Python, Go, C#, and Java. That means you do not have to rewrite your entire application in BAML. You can write one function that wraps a model call, compile it, and import it from your existing codebase. This is the pragmatic path for most teams. The README says the language can run standalone or be adopted incrementally. The standalone mode is less clear: does that mean BAML has its own runtime and web server, or just that you can write a script and execute it? The README does not say. The bindings list is broad, but there is no example of the generated API surface. A Python developer would want to see whether the generated function returns a `pydantic` model or a dict. Without that detail, you are committing to an abstraction that could change between nightly releases.

Limitations and Failure Modes

The most obvious limitation is the release cadence. The latest releases are all nightly builds from late October and early November 2026, with version numbers like `0.23.1-nightly.20261101.a`. That is a signal that the project is not at a stable 1.0. Nightly builds can break APIs, change syntax, or introduce bugs. The default branch is named `canary`, which reinforces the point: this is a project where you are expected to live on the edge. A second limitation is the lack of documentation in the README about what happens when a model output does not conform to the declared type. The README says errors are typed, but it does not say whether BAML retries, falls back, or simply throws. That matters for production systems. A third limitation is that the language is new. There is no mention of a migration path from earlier versions. If you adopt BAML today, you are betting that the core type system stays stable through nightly changes.

Comparison with Plain JSON Schema Validation

The closest alternative to BAML is not another language, but a validation library like `pydantic` in Python or `zod` in TypeScript. Those tools let you define a schema and validate model output, but they do not give you typed errors or compile-time analysis of what a model call can return. With BAML, types persist at runtime and errors are typed and statically analyzed. The difference is that BAML moves the validation from a separate layer into the language itself. That can reduce boilerplate, but it also means you are learning a new language and a new toolchain. If your team already uses `pydantic` with function calling, the added value of BAML is the static error analysis and the filesystem-as-module convention. If you only need a quick validation on a few endpoints, a schema library is lighter and has a larger community. BAML is only worth the switch if you have many model calls with complex nested types and a team that wants compile-time guarantees.

Maintenance and Upgrade Considerations

The repository is written in Rust, which suggests a focus on performance and safety, but it also means that contributing to the core requires Rust knowledge. The README links to a contributing guide, but the README does not describe the contribution process. The license is Apache-2.0, which is permissive for commercial use, but you should read the full license text before shipping, especially if you plan to distribute modified versions. The release history shows a nightly cadence, so upgrades are frequent. That is a maintenance cost: you will need to track changes in the language server, the CLI, and the generated bindings. The README mentions a built-in test and eval framework, which is useful for regression testing, but it is not described in enough detail to judge whether it replaces your existing evaluation harness. Before committing, you should check the changelog for each nightly release and see how often breaking changes appear.

Who Should Adopt BAML Now

The honest answer is that BAML is for teams that feel a specific pain: model outputs that are structurally unpredictable and cause runtime crashes or silent data corruption. If you are already using TypeScript or Python and you want to define a function that returns a typed object from a model call, BAML offers a different model from bolting on a validator. The compile-time error analysis is a genuine advantage over a runtime-only schema check. However, the lack of a stable release, the canary default branch, and the thin README mean you need to be comfortable with uncertainty. The project is not for a team that needs a dependable, long-term dependency with a clear upgrade path. It is for an early adopter who is willing to file issues, read source code, and adapt to changes. Before you start, verify that the language bindings for your language are mature enough for your use case, and test a small proof of concept against your real model outputs.

Editorial conclusion

Adopt BAML if your team spends too much time on brittle output parsing and wants compile-time guarantees around model responses, especially if you already use TypeScript, Python, or Go and can tolerate a nightly release cadence. Skip it if you need a stable, versioned language for agentic control flow. Before adopting, verify that the canary branch and nightly releases match your risk tolerance, and test whether the runtime type persistence actually eliminates the parsing failures you currently see. The project is young, so check the current state of the built-in test framework and eval tooling against your own evaluation needs.

Frequently asked questions

How do I install BAML on a machine without Homebrew?

The only install command shown in the README is `brew install baml`, followed by `baml agent install`, `baml init`, and `baml ide install --code`. Alternative installs are not listed there, so the quickstart page at boundaryml.com/quickstart is where a non-Homebrew path would have to be found.

Can I call BAML from TypeScript or Python without rewriting my app?

Yes. BAML can be run standalone or adopted incrementally, and you can call a BAML function from TS, Py, Go, C#, Java, and other hosts. A Python SDK is published on PyPI under the name baml-py.

Does BAML keep types at runtime, and does it have an any type?

The project states that BAML has a type system like Rust, that types persist at runtime, and that there is no `any` and no casting dangerously to any type. It also states that errors are typed and statically analyzed, and that the filesystem describes the modules and namespaces.

What should I check before putting BAML in production?

Start with TELEMETRY.md in the repository root, which the README never mentions, then pin an explicit version rather than following the canary default branch, since the three newest release artifacts are nightly builds of the 0.23.1 line dated 2026-10-30 through 2026-11-02.

What is BAML actually written in?

Rust is the primary language, under an Apache-2.0 license. The repository also carries a Go module at the root with module path github.com/boundaryml/baml requiring Go 1.24.0, a pnpm and turbo JavaScript workspace, and directories for the CLI, the language server, and the engine.

Official sources

  1. BoundaryML/baml on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/boundaryml-baml.svg)](https://hysenlabs.com/projects/boundaryml-baml)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/boundaryml-baml.svg)](https://hysenlabs.com/projects/boundaryml-baml)

Was this useful?