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

@rust-gear/glob

v1.2.1

Published

A fast glob alternative for Node.js powered by Rust.

Downloads

3,203

Readme

@rust-gear/glob

A fast glob alternative for Node.js powered by Rust.

Performance

Measured against fast-glob on a synthetic tree of ~50k files (Apple Silicon, node bench/bench.mjs, medians):

| pattern (~50k file tree) | globSync | fast-glob sync | fast-glob async | | :----------------------- | ---------: | ---------------: | ----------------: | | **/*.js (10k matches) | 26 ms | 74 ms | 41 ms | | **/*.{js,ts} (18k) | 27 ms | 78 ms | 40 ms | | **/* + exclude (37.8k) | 30 ms | 78 ms | 41 ms | | mod1/**/*.rs (400) | 1.4 ms | 3.4 ms | 1.8 ms |

  • ~3x faster than the synchronous APIs of fast-glob and glob. The directory walk is parallelized on a Rust thread pool, so globSync runs at full speed without blocking on single-threaded I/O.
  • ~1.6x faster than their async APIs, with ~0.04 ms fixed overhead per call.

Thread pool size

How wide the walk runs is a property of the filesystem, not of the CPU, so it is decided per platform.

On Windows and Linux the pool is every logical CPU the process may use. NTFS takes a per-directory lock and Linux takes inode->i_rwsem per inode, so enumerating different directories in parallel does not collide, and the walk keeps scaling to the full width of the machine:

$ node bench/threads.mjs      # Windows 11, 16 logical CPUs, NTFS
threads   1    237.81 ms
threads   8     43.71 ms
threads  16     28.24 ms   <- fastest
threads  32     28.43 ms

$ node bench/threads.mjs      # Ubuntu, 8 logical CPUs, ext4
threads   1     37.08 ms
threads   4     11.57 ms
threads   8     10.75 ms
threads  16     10.79 ms

On macOS it is capped to the machine's fastest core class, read from hw.perflevel0. APFS serializes enumeration on volume-wide state in the vnode layer, so wall time bottoms out long before the CPU does — past the knee the extra threads are queueing in the kernel, not working:

$ node bench/threads.mjs      # macOS, Apple Silicon 4P+4E, APFS
threads   1     64.13 ms
threads   4     24.16 ms   <- fastest
threads   8     35.16 ms
threads  16     34.76 ms

The knee tracks syscall rate rather than core count, so on a Mac with many more performance cores the optimum may sit below their count. On an Intel Mac, where every core is one class, nothing is capped.

Set RUST_GEAR_GLOB_THREADS to override the choice on any platform; run node bench/threads.mjs to see your own machine's curve. The count is always clamped to the process's CPU allowance, so a cgroup quota or affinity mask still wins.

Installation

pnpm add -D @rust-gear/glob

Usage

import * as rs from "@rust-gear/glob";

const filesAsync = await rs.glob("src/**/*.rs");

const files = rs.globSync("**/*.rs", {
  cwd: "src",
  exclude: ["**/test/**", "**/target/**"],
});

Return paths:
Absolute patterns → absolute paths
Relative patterns → paths relative to cwd

Absolute patterns are resolved inside cwd. Pass cwd whenever the pattern points outside the current working directory; a pattern that resolves elsewhere throws rather than returning an empty array.

Options

| Option | Type | Default | Description | | :-------- | :------- | :-------------- | :--------------------------------------------------- | | cwd | string | process.cwd() | Current working directory for searching | | exclude | string[] | [] | Glob patterns to exclude | | dot | boolean | false | Include dot files and directories | | sort | boolean | false | Return sorted results | | gitignore | boolean | true | Respect .gitignore files inside git (.git) repos |

Note: Set gitignore: false for results that depend only on the patterns and the filesystem, matching the behavior of fast-glob, which never reads .gitignore.

What gitignore reads

The enclosing repository is found by walking up from the directory the search starts in, and every .gitignore between that repository root and the search root is applied. The result therefore does not depend on how deep cwd sits, nor on how much of the path the pattern pins down:

// all three honour the repository's ignore rules, and agree
rs.globSync("**/*.js", { cwd: repo });
rs.globSync("sub/**/*.js", { cwd: repo });
rs.globSync("**/*.js", { cwd: `${repo}/sub` });

The one thing not tested against those rules is the search root itself. A search that starts inside an ignored directory still returns what it finds there, so pointing cwd at dist or node_modules works as asked. Use gitignore: false when you want the rules out of the way entirely.

License

Apache-2.0