elysia-pagination
v0.1.0
Published
Type-safe pagination plugin for ElysiaJS with cursor and offset support
Readme
elysia-pagination
A lightweight, type-safe pagination plugin for ElysiaJS (Bun) with support for cursor-based and offset pagination.
Features
- Cursor-based pagination (recommended for feeds & infinite scroll)
- Offset-based pagination (with total count support)
- Built-in Array adapter
- Prisma adapter
- Drizzle adapter
- Full TypeScript support
- Secure cursor encoding (base64)
- Easy Elysia integration
Installation
bun add elysia-pagination
## Quick Start
```typescript
import { Elysia } from 'elysia';
import { pagination } from 'elysia-pagination';
const app = new Elysia()
.use(pagination({
defaultLimit: 20,
maxLimit: 100,
}));
app.get('/users', async ({ paginate, query }) => {
// Example with Array (for testing)
const users = [...yourUserArray];
return paginate(users, {
sortField: 'createdAt',
sortDirection: 'desc',
limit: 20,
cursor: query.cursor,
});
});Response Format
{
"data": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
],
"pagination": {
"nextCursor": "eyJpZCI6Mn0=",
"hasMore": true
}
}ORM Adapters
- Prisma
import { prisma } from './db'; // your prisma client
import { createPrismaAdapter } from 'elysia-pagination/orm/prisma';
const prismaAdapter = createPrismaAdapter();
app.get('/users', async ({ paginate, query }) => {
return paginate(prisma.user.findMany(), {
sortField: 'id',
sortDirection: 'asc',
cursor: query.cursor,
limit: 25,
mode: 'cursor', // or 'offset'
});
});- Drizzle
import { db } from './db';
import { createDrizzleAdapter } from 'elysia-pagination/orm/drizzle';
const drizzleAdapter = createDrizzleAdapter(db);
app.get('/products', async ({ paginate, query }) => {
const products = db.select().from(productsTable);
return paginate(products, {
cursor: query.cursor,
limit: 15,
sortField: 'id',
sortDirection: 'desc',
});
});Configuration
pagination({
defaultLimit: 20,
maxLimit: 100,
cursorEncoding: 'base64', // 'base64' | 'plain'
responseKey: 'pagination', // key name in response
})Cursor Mode (Default)
Best for feeds, timelines, infinite scroll.
app.get('/feed', ({ paginate }) => {
return paginate.array(posts, {
sortField: 'createdAt',
sortDirection: 'desc'
})
})Response:
{
"data": [ ... ],
"pagination": {
"nextCursor": "eyJpZCI6MTIzfQ==",
"hasMore": true
}
}Offset Mode
Best for admin panels, tables with page numbers.
app.get('/admin/users', ({ paginate }) => {
return paginate.array(users, {
mode: 'offset',
includeTotal: true
})
})Response:
{
"data": [...],
"pagination": {
"offset": 40,
"limit": 20,
"total": 15420,
"hasMore": true,
"page": 3
}
}Schema Helper
import { t } from 'elysia'
import { paginationSchema } from 'elysia-pagination'
const UserSchema = t.Object({
id: t.Number(),
name: t.String()
})
app.get('/users', handler, {
response: paginationSchema(UserSchema)
})License
MIT
