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

@anil-labs/collection-js

v0.1.0

Published

A fluent, Laravel-inspired Collection library for JavaScript and TypeScript. Provides 120+ chainable methods for elegant array manipulation.

Readme

@anil-labs/collection-js

A fluent, Laravel-inspired Collection library for JavaScript and TypeScript. Full parity with the Laravel 13.x Collections API — plus statistics, SQL-style joins, combinatorics, async streams, and CSV/JSONL I/O that go beyond it.

npm version License: MIT

  • Strict TypeScript — written in strict mode with deep type inference; no any in the public surface.
  • Immutable by default — methods return new collections; the handful of mutators mirror Laravel exactly.
  • Three flavours — eager Collection, generator-backed LazyCollection, and AsyncCollection for AsyncIterable sources.
  • Tree-shakable — every operation is also a standalone pure function you can import directly.
  • Zero runtime dependencies.

Installation

npm install @anil-labs/collection-js

Quick Start

import collect from '@anil-labs/collection-js'

collect([1, 2, 3, 4, 5])
  .filter((item) => item > 2)
  .map((item) => item * 10)
  .all()
// => [30, 40, 50]

Working with Objects

const users = collect([
  { id: 1, name: 'Alice', role: 'admin', score: 95 },
  { id: 2, name: 'Bob', role: 'user', score: 80 },
  { id: 3, name: 'Charlie', role: 'admin', score: 92 },
  { id: 4, name: 'Diana', role: 'user', score: 88 }
])

users.where('role', 'admin').sortByDesc('score').pluck('name').all()
// => ['Alice', 'Charlie']

users.groupBy('role')
// => { admin: [...], user: [...] }

users.avg('score') // => 88.75
users.max('score') // => 95
users.median('score') // => 90

const [admins, regular] = users.partition((u) => u.role === 'admin')

where-style filters support dot-notation paths and comparison operators, and max/min work on numbers, strings, and Dates:

collect(['banana', 'apple', 'cherry']).max() // => 'cherry'
collect(orders).where('customer.country', 'FR').sum('total')

Pattern filtering with whereLike

whereLike / whereNotLike filter by an SQL-LIKE pattern, where % matches any run of characters and _ matches a single one (case-insensitive by default):

collect(users).whereLike('name', '%Smith') // ends with "Smith"
collect(users).whereLike('email', '%@gmail.com') // gmail addresses
collect(users).whereNotLike('name', 'A%', true) // case-sensitive: not starting with "A"

Lazy Collections

For large or infinite datasets, use generator-backed lazy evaluation — values are produced on demand:

import { LazyCollection } from '@anil-labs/collection-js'

new LazyCollection(function* () {
  for (let i = 0; i < 1_000_000; i++) yield i
})
  .filter((n) => n % 2 === 0)
  .map((n) => n * 2)
  .take(5)
  .toArray()
// => [0, 4, 8, 12, 16] — only 5 items ever evaluated

Lazy-only helpers: tapEach, remember (memoize pulled values), takeUntilTimeout, throttle, withHeartbeat.

Async Collections

Stream and transform AsyncIterable sources with bounded concurrency:

import { AsyncCollection } from '@anil-labs/collection-js'

const results = await AsyncCollection.from(userIds)
  .mapAsync((id) => fetchUser(id), { concurrency: 8 }) // ≤ 8 in flight, source order preserved
  .filter((user) => user.active)
  .take(100)
  .toArray()

Beyond Laravel

These extend the Laravel API for real-world data work:

Statisticsvariance · sampleVariance · stddev · sampleStddev · quantile · percentileAt · histogram · correlation

collect(samples).stddev('latency')
collect(rows).correlation('spend', 'revenue')
collect(values).histogram(10)

SQL-style joinsjoinOn (inner) · leftJoin · rightJoin · outerJoin

collect(orders).joinOn(customers, 'customerId', 'id', (order, customer) => ({
  ...order,
  customerName: customer.name
}))

Combinatorics & itertoolsscan · pairwise · enumerate · cycle · interleave · permutations · combinations · powerSet

collect([1, 2, 3]).permutations().all() // all 3! orderings
collect([1, 2, 3, 4]).combinations(2).all()
collect([1, 2, 3])
  .scan((sum, n) => sum + n, 0)
  .all() // running totals: [1, 3, 6]

CSV / JSONL / streams

import { parseCsv, toCsv, parseJsonl, toJsonl, lines } from '@anil-labs/collection-js'

const rows = collect(parseCsv(csvText, { header: true }))
const csv = toCsv(rows.all())

Higher-Order Messages

users.sum.score // => 355   (property-style)
users.where('role', 'admin').each.notify()

Extending with Macros

Add your own methods at runtime — they participate in chaining like built-ins:

import { Collection } from '@anil-labs/collection-js'

Collection.macro('toUpper', function (this: Collection<string>) {
  return this.map((s) => s.toUpperCase())
})

collect(['a', 'b']).toUpper().all() // => ['A', 'B']

Available Methods

Creation

make · collect · fromJson · fromEntries · fromMap · fromSet · times · range · wrap · unwrap · empty · lazy

Filtering

filter · reject · where · whereStrict · whereBetween · whereNotBetween · whereIn · whereInStrict · whereNotIn · whereNotInStrict · whereNull · whereNotNull · whereLike · whereNotLike · whereInstanceOf · compact · first · firstOrFail · firstWhere · last · sole · unique · uniqueStrict · except · only · select

Transformation

map · mapInto · mapSpread · mapToGroups · mapWithKeys · flatMap · flatten · collapse · collapseWithKeys · chunk · chunkWhile · sliding · split · splitIn · dot · undot · flip · pluck · values · keys · zip · combine · crossJoin

Aggregation

sum · average / avg · min · max · minBy · maxBy · median · mode · count · countBy · percentage

Statistics

variance · sampleVariance · stddev · sampleStddev · quantile · percentileAt · histogram · correlation

Joins

joinOn · leftJoin · rightJoin · outerJoin

Itertools & combinatorics

scan · pairwise · enumerate · cycle · interleave · permutations · combinations · powerSet

Sorting

sort · sortBy · sortByDesc · sortDesc · sortKeys · sortKeysDesc · sortKeysUsing · reverse · shuffle

Searching

contains · containsStrict · containsOneItem · doesntContain · doesntContainStrict · search · has · hasAny · hasMany · hasSole · every · some

Iteration

each · eachSpread · tap · tapEach · transform · pipe · pipeInto · pipeThrough

Addition & Removal

push · prepend · concat · merge · mergeRecursive · union · diff · diffAssoc · diffAssocUsing · diffKeys · intersect · intersectUsing · intersectAssoc · intersectAssocUsing · intersectByKeys · pop · shift · pull · forget · splice

Partitioning

partition · groupBy · groupByMany · keyBy · take · takeUntil · takeWhile · skip · skipUntil · skipWhile · slice · forPage · nth · after · before

Conditional

when · whenEmpty · whenNotEmpty · unless · unlessEmpty · unlessNotEmpty

Conversion

all · toArray · toJson · toPrettyJson · toMap · toSet · implode · join · dump · dd

Misc

collect · clone · macro · ensure · pad · multiply · random · reduce · reduceSpread · value · isEmpty · isNotEmpty · duplicates · duplicatesStrict · put · get · replace · replaceRecursive

Lazy-only

remember · tapEach · takeUntilTimeout · throttle · withHeartbeat

Async (AsyncCollection)

map · mapAsync · filter · filterAsync · flatMap · take · skip · takeWhile · skipWhile · chunk · tap · forEach · eachAsync · reduce · first · last · every · some · count · toArray · collect

I/O

parseCsv · toCsv · parseJsonl · parseJsonlStream · toJsonl · fromReadable · lines

Laravel Compatibility

This library aims for full API parity with Laravel 13.x Collections. If you're familiar with Laravel's Collection class, you'll feel right at home — collect() is the default export.

License

MIT