Library / SDK
benavlabs/fastcrud avatar
benavlabs/fastcrud

FastCRUD's own skill file tells you when not to use FastCRUD

FastCRUD is a Python package for FastAPI, offering robust async CRUD operations and flexible endpoint creation utilities.

1,597 stars116 forksPythonMIT

At a glance

What is it?
FastCRUD is an MIT-licensed Python package that wraps SQLAlchemy 2.0 and Pydantic v2 with async CRUD methods, joins, filtering and pagination for FastAPI, plus a router that generates endpoints from a model. It saves a lot of repetitive code on conventional resources, and the library ships a skill file for coding agents that names its own limits, including that aggregates and bulk writes belong in raw SQLAlchemy.
Who is it for?
Adopt FastCRUD when your FastAPI service exposes conventional resources with filters, sorting and pagination, because that is exactly the shape it generates and the shape where hand-written SQLAlchemy is repetitive. Do not adopt it for reporting endpoints, since aggregates, CTEs and GROUP BY projections are outside its remit and belong in raw SQLAlchemy.
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 11 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

Editorial analysis

Two entry points: crud_router and direct FastCRUD

The README is explicit that FastCRUD offers two ways in: `crud_router` for automatic endpoint creation, and integrating `FastCRUD` directly into your own FastAPI endpoints for more control.

That split is the design decision to understand before adopting it. The router generates a full set of CRUD routes for a model, which means a table can become a working API in a handful of lines. The direct path gives you the same async methods inside handlers you write, which is what you want when the endpoint is not a plain resource.

The generated route is not a black box in the sense of being inflexible. The feature list calls out custom dependencies and configurations, and `crud_router` takes schemas and dependencies as parameters, so the generated endpoints fit a dependency-injected application.

The pattern the README's skill file names as canonical is model, then schemas, then `crud_router`. That ordering is worth following, because the router needs Pydantic schemas resolved before it can build request and response models.

Install is one command, with a uv variant:

sh
pip install fastcrud
sh
uv add fastcrud

The requirements are floors, and Python 3.10 is the hard one

The README lists prerequisites with specific version numbers rather than leaving them loose. Python 3.10 or newer. FastAPI, described as essential since the package is built for it. SQLAlchemy 2.0.21 or newer. Pydantic 2.4.1 or newer. SQLAlchemy-Utils, described as optional but recommended.

pyproject.toml agrees on the shape. `requires-python` is `>=3.10,<4`, the runtime dependencies are `SQLAlchemy>=2.0.0,<3`, `pydantic>=2.0.0,<3`, `sqlalchemy-utils>=0.41.2,<0.42` and `fastapi>=0.100.0`. Classifiers cover Python 3.10 through 3.13 and declare `Typing:: Typed`.

The upper bounds are the interesting part. Most dependencies have upper bounds, while sqlalchemy-utils is capped below 0.42. With FastCRUD itself moving quickly, those bounds are likely to move too.

Note the discrepancy between the README's stated SQLAlchemy floor of 2.0.21 and the dependency spec of 2.0.0. If you are pinning deliberately, follow the README's number, since that is what the maintainer states as the tested floor.

Non-native column types raise NotImplementedError until you add python_type

The single most concrete failure mode in the README is a warning box about non-native column types.

If you use a column type that does not come from SQLAlchemy itself, such as the ones from sqlalchemy-utils, you may hit a `NotImplementedError`. The fix is not a FastCRUD option or a version bump: you add a `python_type` attribute to the column type. The README links to a pull request on the sqlalchemy-utils project for the discussion.

This is the shape of a boundary rather than a bug. FastCRUD infers Python types from SQLAlchemy columns in order to build Pydantic schemas, and a third-party type that does not declare what Python type it maps to leaves it with nothing to work from. Adding the attribute satisfies that inference.

SQLAlchemy-Utils is listed as an optional but recommended dependency, so this is a path the project actively expects you to be on.

The bundled skill names the limit=None footgun and the N+1 trap

Version 0.23.0 ships something unusual for a Python library: a bundled agent skill. It ships at `fastcrud/.agents/skills/fastcrud/SKILL.md` following the Agent Skills standard, and you make it available with:

sh
# In any project that has fastcrud installed
uvx library-skills              # for Codex, Cursor, Copilot, OpenCode, etc.
uvx library-skills --claude     # for Claude Code (uses .claude/skills instead)

That symlinks the skill into `.agents/skills/`, or `.claude/skills/` for Claude Code, and you re-run it after upgrading FastCRUD.

What makes this interesting is the content, not the mechanism. The skill teaches the canonical setup pattern, how to choose a method and avoid N+1 when fetching related data, the return-value semantics, the filter operator syntax such as `__gte`, `__in` and `__ilike`, soft delete, and joined-table inheritance gotchas.

Two entries are effectively an admission of limits. It documents a `limit=None` footgun and a three-tier pagination default. And it has a section on when not to use FastCRUD: aggregates, CTEs, GROUP BY projections and bulk writes belong to raw SQLAlchemy.

A library that ships its own usage rules for code generators is telling you its API has sharp edges. That is a good sign, and it is also information you would otherwise have to discover by generating bad queries.

Reference deep-dives live under `fastcrud/.agents/skills/fastcrud/references/` for methods, filters, joins, pagination and endpoints.

What the features actually cover

The feature list is worth reading as a scope statement rather than a claim.

Fully async, using Python's async capabilities for non-blocking database operations. SQLAlchemy 2.0 as the ORM layer. A full suite of CRUD operations with join support. Dynamic query building covering filtering, sorting and pagination. Advanced join operations with automatic join condition detection, which is the piece that saves the most typing, since you point at a related model rather than writing the condition.

Pagination comes in two forms, and the difference matters. Built-in offset pagination is the conventional page-number approach. Cursor-based pagination is described as efficient for large datasets and aimed at infinite scrolling interfaces, which is the case where offset pagination degrades because the database still has to count past everything you skip.

Auto-generated endpoints with custom dependencies and configurations is the fourth structural piece, and modularity is claimed for extension.

The underlying query model is visible in the filter operator names: double-underscore suffixes on field names select an operator, so the same query builder handles ranges, membership and substring matching.

Soft delete appears in the skill documentation rather than the feature list, which suggests it is available but is not a headline capability.

Against writing the endpoints yourself, and against a code generator

The alternative is not another library. It is writing the same handlers and query code by hand, which is what a FastAPI project does without FastCRUD.

Hand-written endpoints give you full control and no abstraction to learn. The cost is repetition: a resource needs a list route with filtering, sorting and pagination, a create route, a read route, an update route and a delete route, and each of those repeats session handling, schema conversion and error translation. That is the code FastCRUD generates, and on a service with a dozen resources it is a lot of code that changes rarely and is tested often.

A third option is a code generator that writes the boilerplate into your repository instead of handling it at runtime. The difference is where the code lives. Generated code is yours after generation, diffable in review, and debuggable with a stack trace that points at your file. A runtime layer means you are debugging framework internals when something goes wrong.

FastCRUD's bet is that the abstraction is worth it and that the surface is small enough to hold in your head. The shipped skill file, with its explicit method-choice guidance and N+1 warnings, is the maintainer's own attempt to keep that surface learnable.

If your resources are unusual enough that most endpoints are custom anyway, the router earns you nothing and the direct integration is all you should take.

Beta status, release cadence and the 0.x version line

The classifier says `Development Status:: 4 - Beta`, and the version is 0.23.0. Both are honest signals rather than marketing.

The release cadence is fast. v0.23.0 was tagged on 2026-10-12, the same day as the last push. Before it, v0.22.3 on 2026-06-21 and v0.22.2 on 2026-05-28. The listed versions include both patch and minor releases.

The 0.x version and beta classification are signals to upgrade deliberately. For an internal service where you control the upgrade, that is acceptable. For a library you expose to other teams inside your organisation, pin a version and read the changelog on each bump.

There is a related operational detail for anyone using the skill file. Since the skill teaches agents how to call the library, a FastCRUD upgrade can change what your coding agent does, and the README's instruction to re-run `uvx library-skills` after upgrading exists for that reason. Your agent's behaviour has a version dependency that is easy to forget about.

The repository also carries SECURITY.md, CONTRIBUTING.md and CODE_OF_CONDUCT.md, plus a Discord community linked from the README.

Licence, documentation and the sibling admin package

FastCRUD is MIT licensed, declared in pyproject.toml with `license = "MIT"` and a LICENSE file at the repository root. That permits commercial use and modification, which is a licensing note and not legal advice.

Documentation lives at benavlabs.github.io/fastcrud, generated from the repository's docs/ directory. The tooling for that is in the dev dependency groups: zensical, mkdocstrings and mkdocs-autorefs. Generated API reference plus a getting-started guide is the shape of what you get, which means the details of filter operators and pagination options live in the hosted docs rather than in the README.

The README also points to a sibling project, CRUDAdmin, described as a modern admin interface for FastAPI. It is described as a modern admin interface for FastAPI. If your service needs an internal tool as well as a public API, evaluating both together is more efficient than building the admin side from nothing.

The dev group includes testcontainers, asyncpg, psycopg, aiomysql and aiosqlite.

Editorial conclusion

Adopt FastCRUD when your FastAPI service exposes conventional resources with filters, sorting and pagination, because that is exactly the shape it generates and the shape where hand-written SQLAlchemy is repetitive. Do not adopt it for reporting endpoints, since aggregates, CTEs and GROUP BY projections are outside its remit and belong in raw SQLAlchemy. Verify first that your column types expose a python_type, because the README warns that non-native types from sqlalchemy-utils raise a NotImplementedError until you add that attribute.

Frequently asked questions

How do I install FastCRUD?

Run pip install fastcrud, or uv add fastcrud if you use uv. FastCRUD requires Python 3.10 or newer, SQLAlchemy 2.0.21 or newer, Pydantic 2.4.1 or newer, and FastAPI in your project.

What is the difference between crud_router and using FastCRUD directly?

crud_router generates CRUD endpoints automatically from a model and its schemas, with custom dependencies and configurations. Using FastCRUD directly means calling its async CRUD methods inside endpoints you write yourself, which gives more control.

Why do I get a NotImplementedError with sqlalchemy-utils column types?

The README states that non-native column types can raise a NotImplementedError, and that you need to add a python_type attribute to the column type. sqlalchemy-utils itself has a pull request discussing the issue.

When should I not use FastCRUD?

The bundled skill file states that aggregates, CTEs, GROUP BY projections and bulk writes belong to raw SQLAlchemy rather than FastCRUD. It also documents a limit=None footgun and a three-tier pagination default.

Does FastCRUD support cursor-based pagination?

Yes. Alongside built-in offset pagination, FastCRUD implements cursor-based pagination described as efficient for large datasets and aimed at infinite scrolling interfaces.

What is the bundled skill file in FastCRUD?

Version 0.23.0 ships a skill at fastcrud/.agents/skills/fastcrud/SKILL.md following the Agent Skills standard. Run uvx library-skills to symlink it into .agents/skills/, or uvx library-skills --claude for Claude Code, and re-run it after upgrading.

Official sources

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

Was this useful?