npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@chaisser/chunk-array

v1.0.1

Published

Split arrays into chunks

Readme

✂️ @chaisser/chunk-array

Split arrays into chunks — basic, balanced, overlapping, exact, lazy, async, and more


✨ Features

  • 🎯 Type-safe - Full TypeScript support with generics
  • ✂️ Basic chunking - Split arrays by size
  • ⚖️ Balanced - Split into N equal chunks
  • 🔁 Overlapping - Sliding window chunks
  • 📐 Exact size - Pad or trim to exact chunk sizes
  • 🔍 First / Last - Get only the first or last chunk
  • 🏷️ Chunk by predicate - Split based on custom logic
  • 🔁 Lazy iterator - Iterate chunks on demand
  • ⚙️ Processor class - Process chunks incrementally
  • 📊 Progress tracking - Chunk with progress callbacks
  • 🔄 Async processing - Process chunks sequentially with async functions
  • 🪶 Zero dependencies - Lightweight and tree-shakeable
  • 🏎️ ESM + CJS - Dual module format support

📦 Installation

npm install @chaisser/chunk-array
# or
yarn add @chaisser/chunk-array
# or
pnpm add @chaisser/chunk-array

🚀 Quick Start

import {
  chunk,
  chunkInto,
  chunkBalanced,
  chunkOverlapping,
  chunkBy,
  LazyChunkIterator,
} from '@chaisser/chunk-array';

// Basic chunking
chunk([1, 2, 3, 4, 5], 2);
// [[1, 2], [3, 4], [5]]

// Split into N chunks
chunkInto([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3);
// [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]

// Balanced chunks (equal distribution)
chunkBalanced([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 3);
// [[1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]

// Overlapping (sliding window)
chunkOverlapping([1, 2, 3, 4, 5], 3, 1);
// [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

// Chunk by predicate
chunkBy([1, 'a', 2, 'b', 3], (_, i) => i % 2 === 1);
// [[1], [2], [3]]

📖 What It Does

This package provides a comprehensive set of array chunking utilities for JavaScript and TypeScript. It handles basic splitting, balanced distribution, overlapping windows, exact-size padding, lazy iteration, predicate-based splitting, and async processing — all with full TypeScript generics.


🎯 How It Works

The package provides:

  • Core functions - chunk, chunkInto, chunkBalanced, chunkApprox
  • Size variants - chunkMinSize, chunkMaxSize, chunkExact
  • Special splits - chunkOverlapping, chunkBy, chunkFirst, chunkLast
  • Processing - chunkAndProcess, chunkWithProgress, chunkAsync, chunkAndCollect
  • Iteration - chunkIterator, LazyChunkIterator
  • Utilities - getChunkSize, getChunkCount, getChunkIndex, getChunk, flattenChunks, validateChunkOptions
  • Classes - ChunkProcessor, LazyChunkIterator

🎨 What It's Useful For

  • Pagination - Split results into pages
  • Batch Processing - Process data in chunks (API calls, DB writes)
  • Data Visualization - Split data into chart segments
  • Sliding Windows - Moving averages, time-series analysis
  • Parallel Processing - Distribute work across workers
  • Lazy Evaluation - Process large datasets without loading all into memory

💡 Usage Examples

Basic Chunking

import { chunk } from '@chaisser/chunk-array';

chunk([1, 2, 3, 4, 5, 6, 7], 3);
// [[1, 2, 3], [4, 5, 6], [7]]

chunk([], 3);
// []

Split Into N Chunks

import { chunkInto } from '@chaisser/chunk-array';

chunkInto([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3);
// [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]

Balanced Chunks

import { chunkBalanced } from '@chaisser/chunk-array';

chunkBalanced([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 3);
// [[1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]

Overlapping Chunks (Sliding Window)

import { chunkOverlapping } from '@chaisser/chunk-array';

chunkOverlapping([1, 2, 3, 4, 5], 3, 1);
// Sliding window of size 3, overlap of 1

Exact Size with Padding

import { chunkExact } from '@chaisser/chunk-array';

chunkExact([1, 2, 3, 4, 5], 2, 0);
// [[1, 2], [3, 4], [5, 0]]

Chunk by Predicate

import { chunkBy } from '@chaisser/chunk-array';

chunkBy([1, 2, 3, 4, 5], (_, i) => i % 2 === 1);
// Split before odd indices: [[1], [2], [3], [4], [5]]

First and Last Chunk

import { chunkFirst, chunkLast } from '@chaisser/chunk-array';

chunkFirst([1, 2, 3, 4, 5], 2); // [1, 2]
chunkLast([1, 2, 3, 4, 5], 2);  // [5]

chunkFirst([], 2); // null

Lazy Iterator

import { LazyChunkIterator } from '@chaisser/chunk-array';

const iterator = new LazyChunkIterator([1, 2, 3, 4, 5, 6], 2);

iterator.getTotalChunks();  // 3
iterator.next();           // [1, 2]
iterator.next();           // [3, 4]
iterator.hasNext();        // true
iterator.next();           // [5, 6]
iterator.hasNext();        // false
iterator.next();           // null

// Reset and iterate again
iterator.reset();
iterator.next();           // [1, 2]

Generator Iterator

import { chunkIterator } from '@chaisser/chunk-array';

for (const c of chunkIterator([1, 2, 3, 4, 5], 2)) {
  console.log(c);
}
// [1, 2]
// [3, 4]
// [5]

Process Chunks

import { chunkAndProcess } from '@chaisser/chunk-array';

const sums = chunkAndProcess([1, 2, 3, 4, 5, 6], 2, c => c.reduce((a, b) => a + b, 0));
// [3, 7, 11]

Async Processing

import { chunkAsync } from '@chaisser/chunk-array';

const results = await chunkAsync(
  [1, 2, 3, 4, 5, 6],
  2,
  async (c) => {
    const res = await fetch('/api', { method: 'POST', body: JSON.stringify(c) });
    return res.json();
  }
);

Process with Progress

import { chunkWithProgress } from '@chaisser/chunk-array';

const { results, progressUpdates } = chunkWithProgress(
  [1, 2, 3, 4, 5, 6],
  2,
  (chunk) => chunk.reduce((a, b) => a + b, 0)
);
// results: [3, 7, 11]
// progressUpdates: [33.33, 66.66, 100]

ChunkProcessor Class

import { ChunkProcessor } from '@chaisser/chunk-array';

const processor = new ChunkProcessor<number>(2);
processor.setChunks([[1, 2], [3, 4], [5, 6]]);

processor.nextChunk();    // [1, 2]
processor.hasMore();     // true
processor.nextChunk();   // [3, 4]
processor.processRemaining(c => c); // [[5, 6]]

processor.reset();
processor.getChunks();   // []

Utilities

import { getChunkSize, getChunkCount, getChunkIndex, getChunk, flattenChunks } from '@chaisser/chunk-array';

getChunkSize(10, 3);      // 4
getChunkCount(10, 3);     // 4
getChunkIndex([1, 2, 3, 4, 5], 3, 2); // 1
getChunk([1, 2, 3, 4, 5], 3, 2);      // [3, 4]
flattenChunks([[1, 2], [3, 4]]);       // [1, 2, 3, 4]

📚 API Reference

Core Chunking

| Function | Signature | Description | |---|---|---| | chunk(array, size) | (T[], number) → T[][] | Split into chunks of size | | chunkWithOptions(array, options) | (T[], ChunkOptions) → T[][] | Chunk with size and preserveTail options | | chunkInto(array, count) | (T[], number) → T[][] | Split into count chunks | | chunkApprox(array, target) | (T[], number) → T[][] | Approximately target chunks | | chunkBalanced(array, count) | (T[], number) → T[][] | Evenly balanced chunks | | chunkOverlapping(array, size, overlap) | (T[], number, number) → T[][] | Overlapping/sliding window chunks | | chunkMinSize(array, minSize) | (T[], number) → T[][] | Chunks with minimum size | | chunkMaxSize(array, maxSize) | (T[], number) → T[][] | Chunks with maximum size | | chunkExact(array, size, filler) | (T[], number, T) → T[][] | Exact size, pad last chunk | | chunkBy(array, predicate) | (T[], (item, index) => boolean) → T[][] | Split by custom predicate | | chunkFirst(array, size) | (T[], number) → T[] \| null | Get first chunk only | | chunkLast(array, size) | (T[], number) → T[] \| null | Get last chunk only |

Processing

| Function | Description | |---|---| | chunkAndProcess(array, size, fn) | Process each chunk synchronously | | chunkAsync(array, size, fn) | Process chunks sequentially with async fn | | chunkWithProgress(array, size, fn) | Process with progress tracking | | chunkAndCollect(array, size, collector) | Collect results into custom accumulator | | flattenChunks(chunks) | Flatten T[][] into T[] |

Iteration

| Function / Class | Description | |---|---| | chunkIterator(array, size) | Generator yielding chunks | | LazyChunkIterator | Class with next(), hasNext(), reset(), getTotalChunks() |

ChunkProcessor

const p = new ChunkProcessor<T>(chunkSize);
p.setChunks(chunks);            // Set chunks to process
p.getChunks();                  // Get current chunks
p.nextChunk();                  // Get next chunk (or null)
p.hasMore();                    // Check if more chunks available
p.processRemaining(fn);         // Process all remaining chunks
p.reset();                      // Clear all chunks

LazyChunkIterator

const it = new LazyChunkIterator<T>(array, chunkSize);
it.next();                  // Next chunk or null
it.hasNext();               // More chunks available?
it.reset();                 // Reset to start
it.getTotalChunks();        // Total chunk count
it.getCurrentChunkNumber(); // Current 1-based chunk number
it.getIndex();              // Current byte index in array

Utilities

| Function | Description | |---|---| | getChunkSize(arrayLength, chunkCount) | Calculate chunk size | | getChunkCount(arrayLength, chunkSize) | Calculate chunk count | | getChunkIndex(array, element, chunkSize) | Get chunk index for element | | getChunk(array, element, chunkSize) | Get chunk containing element | | validateChunkOptions(options) | Validate options, throws on invalid |


🔗 Related Packages

Explore our other utility packages in the @chaisser namespace:


🔒 License

MIT - Free to use in personal and commercial projects


👨 Developed by

Doruk Karaboncuk [email protected]


📄 Repository


🤝 Contributing

Contributions are welcome! Feel free to:

  • Report bugs
  • Suggest new features
  • Submit pull requests
  • Improve documentation

📞 Support

For issues, questions, or suggestions, please reach out through:


Made with ❤️ by @chaisser

npm license downloads typescript