Rydantic
v0.7.0 / Stable release

Your data.
One Rust
model.

From the first JSON request to the last database row. Define your data once. Let your types carry it through.

Stable 0.7.0 includes breaking changes from 0.6.0. Review the upgrade and migration guidance before installing.

RydanticAI connects Responses, Chat Completions and Anthropic Messages APIs with typed agents and structured output streams: partial snapshots, validated items and automatic correction.

cargo add rydantic@=0.7.0

Open source · MIT licensed · Available on crates.io ↗

THE TYPE IS THE CONTRACT
models/user.rsfeatures: sqlite
use rydantic::{Model, SqlModel};

#[derive(Debug, Model, SqlModel)]
struct User {
    #[sql(primary_key, auto_increment)]
    id: Option<i64>,

    #[model(trim, min_length = 2)]
    name: String,

    #[model(ge = 18)]
    age: u8,
}
JSON PARSING EXAMPLE" Alice " "Alice"
normalized
Less glue. More Rust.
AT HOME IN YOUR STACK
JSON Cap’n Proto Axum + Tokio SQLx JSON Schema
01 / THE WHOLE JOURNEY

One definition.
A lot less repetition.

Keep the rules close to your data, wherever it goes next.

Make valid data the default.

Parse directly into Rust types. Trim strings, apply constraints and collect useful errors with exact field paths. Coercion is an explicit choice.

Explore validation

Speak JSON. And binary.

Serialize JSON, export input and output schemas, or generate native Cap’n Proto schemas and official Rust bindings from your models.

Explore protocols

Meet your application.

Validated Axum requests and responses. SQLx CRUD with independent SQLite, PostgreSQL and MySQL drivers. Add only what you need.

Explore integrations
02 / BUILT TO CONNECT

Your model.
More possibilities.

Start with the derive. Add the boundaries your application needs.

parse.rs
use rydantic::Model;

#[derive(Debug, Model)]
struct User {
    #[model(trim, min_length = 2)]
    name: String,
    #[model(coerce, ge = 18)]
    age: u8,
}

let user = User::parse_json(
    r#"{"name":" Alice ","age":"25"}"#,
)?;
assert_eq!(user.name, "Alice");
assert_eq!(user.age, 25);

Strict types. Explicit coercion. Normalization at the boundary.

accounts BEFORE
idBIGINTPK
nameTEXT↗
Account::migrate(&pool).await?
accounts AFTER
idBIGINTPK
display_nameTEXTRENAMED
enabledBOOLDEFAULT true

Illustrative schema change · PostgreSQL types shown

03 / MODEL-DRIVEN MIGRATIONS

Your model evolves.
Your tables follow.

Compare your model with the live database schema. Preview the plan, preserve renamed columns and backfill new fields with SQL defaults.

  • Automatic upgrades across three databases
  • Migration history and concurrency locks
  • Explicit opt-in for destructive changes
See automatic migrations
LESS PLUMBING. MORE BUILDING.

Let your types
do the talking.