Package Exports
- readline-pager
Readme
๐ readline-pager
โก High-performance paginated file reader for Node.js. Efficiently process large text files without loading them into memory.
- ๐ฆ Zero dependencies
- โก Up to ~3ร faster than Node.js
readline - ๐ Up to ~6ร faster with optional native C++ acceleration
- ๐ Async (
for await...of) and sync (for...of) iteration - ๐ Page-based reading with manual control (
next,nextSync) - ๐ Forward and backward reading support
- ๐งช Fully typed with high test coverage (>90%)
Important:
Performance depends heavily on thechunkSizeoption. Tune it for your storage device. A value of 64 KiB is usually a good starting point. Increasing it may improve throughput until you reach the best value for your hardware.
๐ฆ Installation
npm install readline-pager๐ Quick start
import { createPager } from "readline-pager";
for await (const page of createPager("./bigfile.txt")) {
console.log(page[0]);
}Other usage patterns
import { createPager, createNativePager } from "readline-pager";
// Sync iteration
for (const page of createPager("./bigfile.txt")) {
}
// Manual async
const pager = createPager("./bigfile.txt");
while (true) {
const page = await pager.next();
if (!page) break;
}
// Manual sync
let page;
const pager = createPager("./bigfile.txt");
while ((page = pager.nextSync()) !== null) {}
// Native C++
for await (const page of createNativePager("./bigfile.txt")) {
}โ๏ธ Options
createPager(filepath, {
chunkSize?: number, // default: 64 * 1024 (64 KiB)
pageSize?: number, // default: 1_000
delimiter?: string, // default: "\n"
prefetch?: number, // default: 8
backward?: boolean, // default: false
useWorker?: boolean, // default: false
tryNative?: boolean, // default: true
});
createNativePager(filepath, {
pageSize?: number, // default: 1_000
delimiter?: string, // default: "\n"
backward?: boolean, // default: false
});chunkSizeโ number of bytes read per I/O operation.pageSizeโ number of lines per page.delimiterโ line separator.prefetchโ maximum number of pages buffered internally.backwardโ read the file from end to start.useWorkerโ offload reading to a worker thread (forward reading only).tryNativeโ attempts to use the native reader, falls back to the non-native version if it fails.
Note:
createNativePagerrequires x86 AVX2 or ARM NEON CPU instruction set extensions and will throw if they are not available. It also does not support multi-character delimiters due to fast SIMD-based scanning.
๐ API
pager.next(): Promise<string[] | null>
Returns the next page asynchronously.
Returns null when the end of the file is reached.
Empty lines are preserved.
Note: Unlike Node.js
readline, which may skip empty files or leading empty lines,readline-pageralways returns all lines.
- A completely empty file (
0bytes) produces[""]on the first read.- A file containing multiple empty lines returns each line as an empty string.
pager.nextSync(): string[] | null
Synchronous version of pager.next().
Returns the next page immediately or null when the end of the file is reached.
pager.close(): Promise<void>
Stops reading and releases resources asynchronously. Safe to call at any time.
๐ Benchmark
Run the benchmark locally:
npm run benchmark:node
# or customize with args
node test/benchmark.ts --lines=20000 --page-size=500 --backwardTest setup: generated text files (UUID lines), NVMe SSD, Node.js runtime. Results are averaged across multiple runs. Actual performance depends on hardware.
โก Throughput (MB/s)
| Method | 1M lines (35 MB) | 10M lines (353 MB) | 100M lines (3.5 GB) | 1B lines (35.3 GB) |
|---|---|---|---|---|
readline |
~370 MB/s | ~460 MB/s | ~460 MB/s | ~460 MB/s |
readline-pager (JS) |
~1100 MB/s | ~1300 MB/s | ~1300 MB/s | ~1150 MB/s |
readline-pager (C++) |
~2200 MB/s | ~2500 MB/s | ~2500 MB/s | ~2450 MB/s |
๐ Development & Contributing
- Minimum supported Node.js: v18.12
- Development/test environment: Node v25.8 and TypeScript v6.0
Run tests:
npm i
npm testContributions are welcome. Open an issue or submit a PR.
๐ License
MIT โ ยฉ Morteza Jamshidi