grepts
v0.0.1
Published
A fast TypeScript grep tool — ripgrep reimagined in TypeScript
Maintainers
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 greptsCLI 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 -vAll 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 benchSee 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:
- Spawn ripgrep → ~5ms per invocation (fork + exec + pipe overhead)
- 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 testsDevelopment
# Install dependencies
pnpm install
# Type check
pnpm typecheck
# Run tests
pnpm test
# Build
pnpm build
# Run benchmarks
pnpm bench
# Lint
pnpm lintLicense
Apache-2.0
