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

@hyldmo/by

v1.1.0

Published

A simple and powerful sortby implementation in TypeScript.

Downloads

33

Readme

by

A tiny, powerful sorting utility for arrays of objects in TypeScript and JavaScript. @hyldmo/by provides a flexible and intuitive way to sort complex data structures.

Features

  • Type-Safe: Written in TypeScript for robust type checking.
  • Flexible Selectors: Sort by property keys, nested paths, or custom accessor functions.
  • Multi-Criteria Sorting: Easily define multiple sorting rules with different orders.
  • Intuitive API: A single function by that is easy to learn and use.
  • Handles Complex Types: Properly sorts strings, numbers, booleans, Dates, arrays (by length), and handles null/undefined values gracefully.

Installation

yarn add @hyldmo/by

or

npm install @hyldmo/by

Usage

Import the by function and use it with Array.prototype.sort.

import { by } from '@hyldmo/by'

const users = [
	{ name: 'Alice', age: 30 },
	{ name: 'Bob', age: 25 },
	{ name: 'Charlie', age: 30 }
]

// Sort by name alphabetically
users.sort(by('name'))
// => [ { name: 'Alice', ... }, { name: 'Bob', ... }, { name: 'Charlie', ... } ]

Sorting by Different Orders

Use the Order enum for ascending or descending order.

import { by, Order } from '@hyldmo/by'

// Sort by age in descending order
users.sort(by('age', Order.Desc))
// => [ { name: 'Alice', age: 30 }, { name: 'Charlie', age: 30 }, { name: 'Bob', age: 25 } ]

Sorting by Nested Properties

Use dot-path strings to sort by nested properties. Paths are type-safe via type-fest Paths<T>.

const users = [
	{ name: 'Alice', address: { city: 'New York' } },
	{ name: 'Bob', address: { city: 'Los Angeles' } },
	{ name: 'Charlie', address: { city: 'Chicago' } }
]

users.sort(by('address.city'))
// => [ { name: 'Charlie', ... }, { name: 'Bob', ... }, { name: 'Alice', ... } ]

Sorting with a Custom Selector

Provide a function to sort by a derived value (e.g., name length, case-insensitive key, normalized text). Dates are already supported without a custom selector.

const users = [
	{ name: 'Alice' },
	{ name: 'Bob' },
	{ name: 'Charlie' }
]

// Sort by name length (shortest first)
users.sort(by(u => u.name.length))
// => [ { name: 'Bob' }, { name: 'Alice' }, { name: 'Charlie' } ]

// Case-insensitive name sort using a normalized key
users.sort(by(u => u.name.toLocaleLowerCase()))

Sorting by Multiple Criteria

Pass an array of selectors to sort by multiple properties. Earlier selectors have higher priority. Optionally pass a single Order that applies to all selectors.

import { by, Order } from '@hyldmo/by'

const users = [
	{ name: 'Alice', age: 30 },
	{ name: 'Bob', age: 25 },
	{ name: 'Charlie', age: 30 }
]

// 1) by age descending, 2) then by name descending
users.sort(by(['age', 'name'], Order.Desc))
// => [ { name: 'Charlie', age: 30 }, { name: 'Alice', age: 30 }, { name: 'Bob', age: 25 } ]

// Multiple selectors evaluated in order
users.sort(by(['age', 'name']))

Sorting Arrays by Length

Array properties are automatically sorted by their length.

const posts = [
	{ title: 'Post A', tags: ['js', 'ts', 'react'] },
	{ title: 'Post B', tags: ['python'] },
	{ title: 'Post C', tags: ['go', 'rust'] }
]

posts.sort(by('tags'))
// => [ { title: 'Post B', tags: ['python'] }, { title: 'Post C', ... }, { title: 'Post A', ... } ]

Handling null and undefined

null and undefined values are sorted to the beginning in ascending order, and to the end in descending order.

const items = [{ value: 10 }, { value: null }, { value: 5 }]

items.sort(by('value'))
// => [ { value: null }, { value: 5 }, { value: 10 } ]
import { Order } from '@hyldmo/by'
items.sort(by('value', Order.Desc))
// => [ { value: 10 }, { value: 5 }, { value: null } ]

API

Automatically handled data types

The comparator automatically handles: string, number, boolean, Date, and arrays (by length). null/undefined are sorted to the beginning in ascending order and to the end in descending order. Use a custom selector only for derived values or normalization.

by<T>(selector, order?)

  • selector: Selector<T>
    • A property path of T (supports dot-paths via Paths<T>).
    • A function that receives an object and returns a sortable value.
  • order: Order (optional, defaults to Order.Asc)

by<T>(selectors, order?)

  • selectors: Selector<T>[]
    • An array of selectors evaluated in order until a difference is found.
  • order: Order (optional, defaults to Order.Asc)

Types

import type { Paths } from 'type-fest'

export enum Order {
	Asc = 1,
	Desc = -1
}

export type Selector<T> =
	| Paths<T>
	| ((obj: T) => string | number | Date | null | undefined | boolean | unknown[])