BAML
A domain-specific language for type-safe LLM functions, with generated clients and schema-aligned parsing.
BAML is a small domain-specific language for defining LLM functions with typed inputs and outputs. You write the function and schema once in .baml files and generate type-safe clients for Python, TypeScript, and more; its schema-aligned parser reliably coerces messy model output into your types.
BAML (by BoundaryML) takes a different angle on structured LLM output: instead of a library in one language, it's a small domain-specific language. You define an LLM function — its prompt, typed inputs, and typed output — in a .baml file, and BAML generates type-safe clients for Python, TypeScript, and other languages. Its schema-aligned parsing is built to coerce the imperfect, almost-JSON that models often emit into your declared types.
It is aimed at teams who want their LLM calls to be first-class, version-controlled, type-checked artifacts shared across a polyglot codebase, rather than prompt strings scattered through application code. The DSL also gives you a testing playground for prompts.
Highlights
- Typed LLM functions — declare inputs, outputs, and the prompt in one place; get compile-time types in your app.
- Multi-language clients — generate idiomatic clients (Python, TypeScript, and more) from the same definition.
- Schema-aligned parsing — robustly parses real-world model output, including partial/streaming and malformed-ish JSON.
- Prompt as code —
.bamlfiles live in version control with tests and a playground. - Provider-agnostic — works across model providers.
In an AI-assisted workflow
class User { name string age int }
function ExtractUser(text: string) -> User {
client Claude
prompt #"Extract the user from: {{ text }} {{ ctx.output_format }}"#
}Generate clients, then call ExtractUser(...) from Python or TypeScript and get a typed User back.
TIP
BAML shines when the same prompts are consumed by multiple services/languages, or when you want prompts under test and review like any other code. For a single-language, in-code approach, Instructor is lighter weight.
Good to know
BAML is open source and free; you pay your model provider for tokens. It introduces a build step (generating clients from .baml files), which is the trade for cross-language type safety. See Structured Output vs JSON Mode vs Function Calling for when typed output is worth it.
Related
- InstructorGet structured, validated output from LLMs using plain type definitions, with automatic retries on validation failure.
- Structured Output vs JSON Mode vs Function Calling: Which to Use in 2026The reliable ways to get typed data out of an LLM — what JSON mode, function calling, and native structured outputs each guarantee, and when to use which.
- LLM Output Schema GeneratorTurn an example of the data you want from an LLM into a precise, validated output schema (Pydantic / Zod / JSON Schema) and wire it into structured-output calls. Use when adding typed LLM output, replacing brittle JSON parsing, or designing an extraction shape.