Documentation
Paginate arrays in Node (and browsers). Returns JSON with data, meta, and links—use it in your return when sending data to users.
Overview
Takes any array and returns JSON data, meta, links. It works with any data source—Mongoose, Prisma, Sequelize, raw SQL, or plain arrays.
Use it in your return when sending data to users. Pagination happens in memory—fetch your dataset, then pass it to paginate() or paginateFromRequest() in res.json().
// ESM / TypeScript
import { paginateFromRequest } from 'api-paginate';
// CommonJS: const { paginateFromRequest } = require('api-paginate');
const users = await User.find().lean();
return res.json(paginateFromRequest(req, users, { per_page: 15 }));
// returns data, meta, links — ready for usersInstallation
Install via npm or yarn:
The package ships as CommonJS and ESM. TypeScript types are included.
// CommonJS (Node)
const { paginate } = require('api-paginate');
// ESM / TypeScript
import { paginate } from 'api-paginate';Passing Data
Accepts any array. Below are common formats from different ORMs.
// Use .lean() to get plain objects
const docs = await User.find().lean();
const result = paginate(docs, {
current_page: 1, per_page: 20, route: '/users'
});
// result.data, result.meta, result.links// findMany returns plain objects by default
const products = await prisma.product.findMany();
const result = paginate(products,
{
current_page: 2, per_page: 10, route: '/products'
});// Use raw: true for plain row objects
const posts = await Post.findAll({ raw: true });
const result = paginate(posts,
{ current_page: 1, per_page: 15, route: '/posts' });// Raw query returns rows; pass array to paginate
const rows = await db.raw('SELECT * FROM orders ORDER BY created_at DESC');
const orders = rows.rows ?? rows;
const result = paginate(orders, { current_page: 3, per_page: 25 });// Any array shape works—id, type, attributes, etc.
const items = [
{ id: 'a1', type: 'article', attributes: { title, tags }},
{ id: 'a2', type: 'comment', attributes: { body, author }}
];
const result = paginate(items, { per_page: 5, current_page: 1 });// Parse CSV to array of objects, then paginate
const lines = csvText.trim().split('\n');
const headers = lines[0].split(',');
const data = lines.slice(1).map(line => {
const vals = line.split(',');
return Object.fromEntries(headers.map((h, i) => [h, vals[i]]));
});
const result = paginate(data, { page: 1, perPage: 10 });Note: Paginator does not fetch data. Provide a plain array—use .lean(), .toJSON(), or raw: true.
API Reference
paginate(data, options?)
Returns data, meta, and links.
Parameters
| Parameter | Type | Description |
|---|---|---|
| data | T[] | Array to paginate |
| options.current_page | number | Current page, 1-based (default: 1) |
| options.per_page | number | Items per page (default: 15) |
| options.route | string | Route for links (e.g. /api/users); combined with configured baseUrl or auto-detected origin |
| options.baseUrl | string | Optional override; prefer route + configure |
| options.pageParam | string | Query param name (default: "page") |
Return value
{ data, meta: { current_page, per_page, total, ... }, links: { first, prev, next, last } }Examples
Express
Configure once in app.ts or server.ts; in route files only use paginateFromRequest.
import { configure } from 'api-paginate';
configure({ baseUrl: process.env.API_BASE_URL });import { paginateFromRequest } from 'api-paginate';
app.get('/users', async (req, res) => {
try {
const users = await User.find().lean();
res.json(paginateFromRequest(req, users, { route: '/users', per_page: 15 }));
} catch (err) {
res.status(500).json({ error: err.message });
}
});Next.js API route
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const result = paginate(users, {
current_page: parseInt(searchParams.get('page') || '1'),
per_page: 15,
route: '/api/users',
});
return Response.json(result);
}Client-side
import { paginate } from 'api-paginate';
const result = paginate(items, { current_page: 2, per_page: 10, route: '/api/items' });Try it in the Simulator
See pagination in action—use pre-built fixtures or paste CSV. In your API, use api-paginate in the return (e.g. res.json(paginateFromRequest(...))).