Open-source project
pydantic/pydantic avatar
pydantic/pydantic

Pydantic coerces rather than rejects, and V2 still ships V1 inside it

Data validation using Python type hints

29,497 stars3,173 forksPythonMIT

At a glance

What is it?
Pydantic validates data against Python type hints, and its clearest example shows the behaviour that matters: a string '123' becomes the integer 123, a timestamp string becomes a datetime, and a bytes value becomes a plain int. V2 is a ground-up rewrite with performance improvements and a Rust pydantic-core in the repository, it requires Python 3.10 or newer, and it bundles the last V1 so a codebase can migrate a module at a time.
Who is it for?
Pydantic fits a Python 3.10 or newer codebase that wants its data shapes declared once and enforced at the boundary, with an IDE and linter reading the same annotations the runtime checks.
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 received new commits within the last day.
What is it written in?
Mainly Python, 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

  • pydantic/pydantic29,497 ★ · +654
Star history
Repository2026-09-212026-11-14
pydantic/pydantic28.8k29.5k

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

Editorial analysis

The example coerces three types and tells you nothing

The README's example is short and does the explaining:

python
from datetime import datetime
from typing import Optional
from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str = 'John Doe'
    signup_ts: Optional[datetime] = None
    friends: list[int] = []

external_data = {'id': '123', 'signup_ts': '2017-06-01 12:22', 'friends': [1, '2', b'3']}
user = User(**external_data)

A string id becomes the integer 123, a timestamp string becomes a `datetime` object, and `b'3'` becomes `3` in the friends list. The types are declared, and the values are converted to match.

That is the design decision to accept or reject. Validation here means coercion, so a payload that is loosely typed is accepted and normalised rather than refused. If your API contract requires a 400 when a client sends an id in quotes, the default behaviour is the wrong one and the strictness has to be configured deliberately.

V1 lives inside V2, which is both the migration path and the hazard

Pydantic V2 is described as a ground-up rewrite, with new features, performance improvements and some breaking changes against V1. For a team still on 1.10 the README offers two exits: the V1.10 documentation, and a `1.10.X-fixes` git branch that keeps receiving fixes.

The third option is the interesting one. V2 ships with the latest version of V1 built in, so a single install can do this:

`from pydantic import v1 as pydantic_v1`

That is what makes an incremental upgrade possible: one module at a time, with the old import path kept alive under a namespace. The cost is that a single process can now hold two generations of the library, each with its own error types, its own validator signatures and its own documentation. A team that takes this route needs a rule about which modules have moved, and a plan for when the compatibility path is dropped.

The speed claim is a Rust directory in the repository

The top level of the repository contains `pydantic/` and `pydantic-core/`, and the second one is Rust. The Makefile reaches into it for formatting with `cargo fmt --manifest-path pydantic-core/Cargo.toml` and delegates linting with a recursive make into `pydantic-core`.

The same variable lists the Python side of the work, and it is longer than a Python project usually is: `pydantic`, `tests`, `docs/plugins`, `release`, `pydantic-core/python`, `pydantic-core/tests` and `pydantic-core/wasm-preview/run_tests.py`. That last path is a WebAssembly preview with its own test entry point, so the core is built and exercised in more than one target.

For a reader, the consequence is about what installing versus building means. `pip install pydantic` gets you a wheel and no toolchain. Building from source needs uv, and the `install` target syncs every group except pyodide-build, every package and every extra before installing pre-commit hooks, with a separate `.rust` check that tells you to install Rust.

Python 3.10 through 3.15, on CPython and PyPy

The packaging metadata is explicit. The project is MIT licensed, built with hatchling and hatch-fancy-pypi-readme, classified as a production-stable 3.x-only library, and classified for CPython and PyPy on Python 3.10, 3.11, 3.12, 3.13, 3.14 and 3.15. The README phrases the floor the same way, telling you to define data in pure, canonical Python 3.10 or newer.

Two things follow. A runtime on 3.9 or older is out. And the install section of the documentation covers more options for making Pydantic faster, which means the plain pip install is the starting point rather than the fastest one.

bash
pip install -U pydantic
conda install pydantic -c conda-forge

Both routes install the same library; the second is the conda-forge channel. The lockfile in the repository is `uv.lock`, so contributors work through uv while users install through pip.

The README gives Logfire a section above the library itself

The structure of the README is worth noticing. Between the one-line description and the version comparison sits a section announcing Pydantic Logfire, described as an observability and evaluation platform for AI applications and agents, with a link pointing off to pydantic.dev/logfire.

That is not a complaint about the library, which is the subject of everything else on the page. It is a note about where the documentation lives. This README covers what Pydantic is, how to install it, one example, the V1 question and where the contributing and security policies live. Everything else is in the documentation site it links to.

So if you are evaluating the library, judge it on the validation docs rather than on the ordering of the front page.

2.14.0a1 was tagged before the 2.13 patches landed

The release list shows two lines moving together: v2.14.1 is dated 2026-10-11, and v2.14.2 and v1.10.27 are both dated 2026-10-29. The 2.14 line is past its alpha, and the V1 line still takes releases alongside it.

The repository is not archived and the last push was on 2026-11-02, so both lines are being worked on.

The upgrade path is documented in the repository rather than in the README. `HISTORY.md` sits at the root for the change record, `CITATION.cff` is there for citation metadata.

Editorial conclusion

Pydantic fits a Python 3.10 or newer codebase that wants its data shapes declared once and enforced at the boundary, with an IDE and linter reading the same annotations the runtime checks. It does not fit a service that must reject a loosely typed payload rather than normalize it, since the default behaviour is coercion, and it does not fit a team that wants a single API surface during a migration, because `from pydantic import v1 as pydantic_v1` puts two generations of the library in one process. Before upgrading, read HISTORY.md at the repository root; the current release is v2.14.2 from 2026-10-29.

Frequently asked questions

What is Pydantic used for?

It is a data validation library built on Python type hints. You declare how data should look in pure, canonical Python 3.10 or newer, and Pydantic validates incoming data against those declarations, converting values such as a string id into the declared type.

Why should you use Pydantic?

The README's argument is that it is fast and extensible and plays nicely with your linters, your IDE and your own judgement, because the same type hints you write for the checker are the ones the library validates against. Define the shape once in ordinary Python and validate with Pydantic.

How do I install Pydantic?

Use `pip install -U pydantic` or `conda install pydantic -c conda-forge`. Python 3.10 or newer is required, and the documentation's install section lists further options aimed at making Pydantic faster.

How do I use a Pydantic BaseModel?

Subclass BaseModel, annotate the fields, then instantiate with your data. In the README's example, User(**external_data) with a string id, a timestamp string and a list containing b'3' produces an integer id, a datetime and a list of integers.

Official sources

  1. License: MIT
  2. Project website
  3. pydantic/pydantic on GitHub
  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/pydantic-pydantic.svg)](https://hysenlabs.com/projects/pydantic-pydantic)

Star history chart for your README

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

Was this useful?