Skip to main content

One pagination engine.
Every language.

Fast pagination, filtering, sorting & search — one Rust core, native Python & TypeScript packages, byte-for-byte parity

pip install pypaginate·npm i @cyblow/paginate·cargo add paginate-core

One Rust core

Filtering, sorting, ranked search, the cursor codec, and pagination math live once in a native engine. The language packages are thin, typed adapters.

Cross-language parity

Python and TypeScript return the same order and byte-identical cursors, pinned by a frozen golden fixture asserted in CI.

Filter, sort & search

20 filter operators with nested And/Or, stable null-aware multi-key sorting, and ranked trigram fuzzy search.

Cursor pagination

Opaque, URL-safe keyset cursors that stay correct under writes and decode byte-for-byte across Python, TypeScript, and Rust.

Framework integrations

SQLAlchemy, Django, and FastAPI in Python; Express, Prisma, and Drizzle in TypeScript — built on the same portable predicate.

Typed & dependency-light

Full type hints (Python) and types (TS) generated from one schema, so they can't drift. Zero runtime dependencies in the core.

Pick your language

Same API. Same results. Two languages.

The Python and TypeScript packages are thin adapters over one Rust core, so they return identical filtered/sorted/ranked order — and byte-identical cursors.

Python · pypaginate
from pypaginate import paginate, filter, OffsetParams, FilterSpec

page = paginate(users, OffsetParams(page=1, limit=20))
page.total # 1_000
page.has_next # True

adults = filter(users, FilterSpec(field="age", operator="gte", value=18))
TypeScript · @cyblow/paginate
import { paginate, filter, OffsetParams } from "@cyblow/paginate";

const page = paginate(users, new OffsetParams({ page: 1, limit: 20 }));
page.total; // 1_000
page.hasNext; // true

const adults = filter(users, { field: "age", operator: "gte", value: 18 });