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

grepts

v0.0.1

Published

A fast TypeScript grep tool — ripgrep reimagined in TypeScript

Readme

grepts

A fast TypeScript grep — ripgrep reimagined for the Node.js ecosystem.

  ██████  ██████  ███████ ██████  ████████ ███████
 ██       ██   ██ ██      ██   ██    ██    ██
 ██   ███ ██████  █████   ██████     ██    ███████
 ██    ██ ██   ██ ██      ██         ██         ██
  ██████  ██   ██ ███████ ██         ██    ███████

grepts is a TypeScript-native grep tool with full ripgrep feature parity. Use it as a CLI or as an in-process Node.js module — no subprocess spawn overhead.

Install

pnpm add grepts

CLI Usage

# Basic search
grepts "TODO" ./src

# Case insensitive
grepts -i "fixme" ./src

# Regex pattern
grepts "(import|export).*from" ./src

# Word boundary matching
grepts -w "error" ./src

# Only show file names with matches
grepts -l "TODO" .

# Count matches per file
grepts -c "function" ./src

# Glob filter — only search .ts files
grepts -g "*.ts" "interface" ./src

# Max matches per file
grepts -m 5 "TODO" ./src

# Invert match — show lines NOT matching
grepts --invert-match "test" ./src

# Context lines (like grep -C)
grepts -C 3 "error" ./src
grepts -B 2 -A 5 "error" ./src

# Fixed strings (no regex)
grepts -F "array[0]" ./src

# Multiline mode
grepts -U "function.*\n.*return" ./src

# Search hidden files
grepts --hidden "secret" .

# Limit directory depth
grepts --max-depth 2 "TODO" .

# Quiet mode — exit 0 if match found, 1 otherwise
grepts -q "TODO" ./src

# Show version
grepts -v

All CLI Flags

| Flag | Description | |------|-------------| | -i, --ignore-case | Case insensitive search | | -n, --line-number | Show line numbers (default: on) | | -c, --count | Show count of matches per file | | -l, --files-with-matches | Show only file names with matches | | --files-without-match | Show only file names without matches | | -w, --word-regexp | Match whole words only | | -F, --fixed-strings | Treat pattern as literal string | | -g, --glob <pattern> | Filter files by glob (e.g., *.ts) | | --hidden | Search hidden files and directories | | --max-depth <n> | Max directory recursion depth | | -m, --max-count <n> | Max matches per file | | --invert-match | Select non-matching lines | | -U, --multiline | Multiline matching | | -C, --context <n> | Lines of context around matches | | -B, --before-context <n> | Lines before match | | -A, --after-context <n> | Lines after match | | --no-ignore | Don't respect .gitignore | | --no-color | Disable color output | | -q, --quiet | Suppress output, exit code only | | -v, --version | Show version |

Module Usage

Use grepts as an in-process Node.js library — zero subprocess overhead.

import { search, searchAsync, searchOptionsSchema } from 'grepts';

// Validate and search
const options = searchOptionsSchema.parse({
  pattern: 'TODO',
  paths: ['./src'],
  ignoreCase: true,
});

// Synchronous search
const results = search(options);

for (const result of results) {
  console.log(`${result.filePath}: ${result.matchCount} matches`);
  for (const match of result.matches) {
    console.log(`  L${match.lineNumber}: ${match.line}`);
  }
}

// Async search (concurrent file I/O)
const asyncResults = await searchAsync(options);

API

search(options: SearchOptions): readonly SearchResult[]

Synchronous recursive grep. Reads files with readFileSync.

searchAsync(options: SearchOptions): Promise<readonly SearchResult[]>

Async recursive grep. Reads files concurrently with 32-way parallelism.

searchOptionsSchema

Zod schema for validating search options. Use .parse() or .safeParse().

SearchOptions

interface SearchOptions {
  pattern: string;          // Regex pattern or literal string
  paths: string[];          // Files or directories to search
  ignoreCase?: boolean;     // Default: false
  lineNumber?: boolean;     // Default: true
  count?: boolean;          // Default: false
  filesWithMatches?: boolean;
  filesWithoutMatch?: boolean;
  wordRegexp?: boolean;     // Default: false
  fixedStrings?: boolean;   // Default: false
  glob?: string;            // e.g., "*.ts"
  hidden?: boolean;         // Default: false
  maxDepth?: number;
  maxCount?: number;
  context?: number;         // Default: 0
  beforeContext?: number;
  afterContext?: number;
  invertMatch?: boolean;    // Default: false
  multiline?: boolean;      // Default: false
  respectGitignore?: boolean; // Default: true
  color?: boolean;          // Default: true
  quiet?: boolean;          // Default: false
}

SearchResult

interface SearchResult {
  filePath: string;
  matches: MatchInfo[];
  matchCount: number;
}

interface MatchInfo {
  line: string;
  lineNumber: number;
  columnStart: number;
  columnEnd: number;
}

Feature Parity with ripgrep

| Feature | grepts | ripgrep | |---------|--------|---------| | Regex search | ✅ | ✅ | | Recursive directory walk | ✅ | ✅ | | .gitignore support | ✅ | ✅ | | Case insensitive (-i) | ✅ | ✅ | | Line numbers (-n) | ✅ | ✅ | | Match count (-c) | ✅ | ✅ | | Files with matches (-l) | ✅ | ✅ | | Files without match | ✅ | ✅ | | Word boundary (-w) | ✅ | ✅ | | Fixed strings (-F) | ✅ | ✅ | | Glob filtering (-g) | ✅ | ✅ | | Hidden files (--hidden) | ✅ | ✅ | | Max depth (--max-depth) | ✅ | ✅ | | Max count (-m) | ✅ | ✅ | | Invert match | ✅ | ✅ | | Multiline (-U) | ✅ | ✅ | | Color output | ✅ | ✅ | | Quiet mode (-q) | ✅ | ✅ | | Context lines (-C/-A/-B) | ✅ | ✅ | | Binary file detection | ✅ | ✅ | | In-process Node.js API | ✅ | ❌ | | Async concurrent I/O | ✅ | ❌ | | Zero-overhead integration | ✅ | ❌ |

Benchmarks

grepts is 323x faster than ripgrep per invocation when used in-process (no subprocess spawn overhead). Run benchmarks yourself:

pnpm build && pnpm bench

See BENCHMARKS.md for full results.

Why grepts is faster

When integrating search into Node.js tools (IDEs, build systems, linters, watch mode), you have two options:

  1. Spawn ripgrep → ~5ms per invocation (fork + exec + pipe overhead)
  2. Call grepts → ~16μs per invocation (in-process function call)

For a single search, 5ms is fine. But IDEs and build tools search hundreds of times per second. That 323x advantage compounds:

| Scenario | ripgrep (subprocess) | grepts (in-process) | |----------|---------------------|---------------------| | 1 search | 5ms | 16μs | | 100 searches | 500ms | 1.6ms | | 1000 searches | 5s | 16ms |

Project Structure

src/
  core/           # Node module (importable library)
    index.ts      # Public API exports
    search.ts     # Search engine (regex, matching)
    search-async.ts # Async parallel search
    walker.ts     # Directory traversal, gitignore, glob
    output.ts     # Color formatting
    schemas.ts    # Zod validation schemas
    types.ts      # TypeScript types
  cli/            # CLI application
    cli.ts        # Commander.js CLI entry point
  bench/          # Benchmark suite
    bench.ts      # grepts vs ripgrep vs grep benchmarks
  __tests__/      # Vitest tests

Development

# Install dependencies
pnpm install

# Type check
pnpm typecheck

# Run tests
pnpm test

# Build
pnpm build

# Run benchmarks
pnpm bench

# Lint
pnpm lint

License

Apache-2.0