Skip to content

startvibecoding/go-ripgrep

Repository files navigation

go-ripgrep

A high-performance line-oriented search tool written in Go — a pure Go port of ripgrep. It provides both a CLI tool (rg) compatible with ripgrep's interface and a Go SDK for programmatic use.

Go Version License: MIT

Features

  • Fast recursive search — multi-threaded file walking and searching using goroutines
  • Regex & fixed-string matching — full Go regexp support plus literal string search (-F)
  • Ignore file support — respects .gitignore, .ignore, and .rgignore with nested directory support
  • Glob filtering — include/exclude files using -g/--glob patterns with negation support
  • Context lines — show lines before/after matches (-A, -B, -C)
  • Color output — ANSI color highlighting for matches, filenames, and line numbers
  • JSON output — newline-delimited JSON (NDJSON) format (--json) compatible with ripgrep's JSON spec
  • Stdin support — pipe input from other commands
  • Cross-platform — builds for Linux (amd64, arm64, loong64), macOS (amd64, arm64), and Windows (amd64, arm64)
  • NPM packages — distributable via npm for Node.js integration
  • Pure Go SDK — embed search functionality in your Go applications

Installation

From Source

git clone https://github.com/startvibecoding/go-ripgrep.git
cd go-ripgrep
make build
# Binary will be at ./bin/rg

Via go install

go install github.com/startvibecoding/go-ripgrep/cmd/rg@latest

As a Go SDK

go get github.com/startvibecoding/go-ripgrep

Via npm

npm install go-ripgrep
# Binary available at node_modules/.bin/rg

Pre-built Binaries

Download from GitHub Releases for your platform.

Usage

CLI

rg [OPTIONS] PATTERN [PATH...]
rg [OPTIONS] -F PATTERN [PATH...]
cat file | rg [OPTIONS] PATTERN

Examples

# Search for a pattern recursively
rg "hello" ./src

# Case-insensitive search
rg -i "error" /var/log

# Fixed string search (no regex)
rg -F "function(" ./src

# Show context lines
rg -C 3 "TODO" .

# Search only specific file types
rg -g "*.go" "func main" .

# Exclude file patterns
rg -g "!*.min.js" "function" ./dist

# JSON output
rg --json "pattern" .

# Pipe from stdin
cat README.md | rg "install"

# Word boundary match
rg -w "test" .

# Limit matches per file
rg -m 5 "error" /var/log

# Show column numbers
rg --column "TODO" .

# Follow symlinks
rg -L "pattern" ./links

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

# Ignore .gitignore rules
rg --no-ignore "node_modules" .

Go SDK

Use the root package as goriggrep:

package main

import (
	"context"
	"fmt"

	goriggrep "github.com/startvibecoding/go-ripgrep"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	results, err := goriggrep.Search(ctx, []string{"./src"}, goriggrep.Options{
		Pattern:         "TODO",
		CaseInsensitive: true,
		Globs:           []string{"*.go", "!vendor/**"},
		BeforeContext:   1,
		AfterContext:    1,
		MaxCount:        10,
		Threads:         4,
	})
	if err != nil {
		panic(err)
	}

	for res := range results {
		fmt.Printf("%s: %d matches\n", res.Path, res.Stats.Matches)
		for _, m := range res.Matches {
			if m.IsContext {
				fmt.Printf("  %d-%s\n", m.LineNum, m.Line)
				continue
			}
			fmt.Printf("  %d:%s\n", m.LineNum, m.Line)
		}
	}
}

Search returns a streaming <-chan printer.FileResult>. Each result includes:

  • Path: the matched file or archive entry path
  • Matches: matched lines and context lines
  • Stats: searched line count and match count
  • Elapsed: time spent searching that file

Common SDK options:

  • Pattern, IsFixed, CaseInsensitive, WordRegexp, InvertMatch
  • Globs, Types, TypesNot, NoIgnore, Hidden, FollowSymlinks
  • BeforeContext, AfterContext, MaxCount
  • SearchZip for .zip, .gz, .bz2
  • SortBy and SortReverse
  • Threads to control worker count

Use context.Context cancellation to stop a search early. For the full SDK surface, see docs/sdk-reference.md.

CLI Options Reference

Flag Short Description
--ignore-case -i Case-insensitive search
--case-sensitive -s Force case-sensitive search (overrides -i)
--word-regexp -w Match whole words only
--fixed-strings -F Treat pattern as a literal string
--invert-match -v Select non-matching lines
--glob GLOB -g Include/exclude files by glob pattern
--after-context NUM -A Show NUM lines after each match
--before-context NUM -B Show NUM lines before each match
--context NUM -C Show NUM lines before and after each match
--max-count NUM -m Limit matches per file
--threads NUM -j Number of worker threads
--hidden Search hidden files and directories
--no-ignore Don't respect ignore files
--follow -L Follow symbolic links
--max-depth NUM Maximum directory depth
--json Output newline-delimited JSON
--color WHEN Color output: always, never, auto
--heading Group matches under file headings
--no-heading Don't print file headings
--line-number -n Show line numbers (default: on)
--no-line-number -N Suppress line numbers
--with-filename -H Print file path for each match
--no-filename -I Suppress file path
--column Show column number of first match
--help -h Print help message
--version -V Print version

Architecture

go-ripgrep/
├── cmd/rg/           # CLI entry point
│   └── main.go       # Argument parsing, search orchestration, output
├── pkg/
│   ├── matcher/      # Pattern matching engine
│   │   ├── matcher.go    # RegexMatcher, FixedMatcher, BuildMatcher
│   │   └── matcher_test.go
│   ├── searcher/     # File reading & line-by-line search
│   │   ├── searcher.go   # Searcher with context support
│   │   └── searcher_test.go
│   ├── printer/      # Output formatting
│   │   ├── printer.go    # CLI text & NDJSON output
│   │   └── printer_test.go
│   ├── globset/      # Glob pattern compilation & matching
│   │   ├── globset.go    # GlobToRegex, GlobSet, MatchGlobFilter
│   │   └── globset_test.go
│   └── ignore/       # Ignore file parsing & stack management
│       ├── ignore.go     # .gitignore, .ignore, .rgignore support
│       └── ignore_test.go
├── sdk.go            # Public Go SDK (Search, Options)
├── sdk_test.go       # SDK unit tests
├── tests/
│   └── integration_test.go  # End-to-end CLI tests
├── npm/              # NPM package distribution
├── scripts/          # Build & packaging scripts
└── Makefile          # Build system

Data Flow

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│  CLI / SDK   │────▶│   Walker     │────▶│  Searcher    │
│  (options)   │     │  (dirs/files)│     │  (per file)  │
└──────────────┘     └──────────────┘     └──────────────┘
                           │                     │
                     ┌─────▼─────┐         ┌─────▼─────┐
                     │  Ignore   │         │  Matcher  │
                     │  Stack    │         │  (regex/  │
                     │(.gitignore│         │   fixed)  │
                     │ .ignore)  │         └───────────┘
                     └───────────┘
  1. CLI parses arguments and creates Options
  2. Walker recursively traverses directories, consulting the Ignore Stack to respect .gitignore rules
  3. Files are sent to worker goroutines via a channel
  4. Searcher reads each file line-by-line, using Matcher to find matches
  5. Results flow back through a channel to Printer for formatted output

Building

# Current platform
make build

# All platforms
make build-all

# Specific platforms
make build-linux
make build-darwin
make build-windows

# Static binary (musl)
make build-linux-musl

# Run tests
make test

# Format code
make fmt

# Clean build artifacts
make clean

NPM Distribution

# Sync version across npm packages
make npm-version

# Build platform-specific npm packages
make npm-packages

# Pack all npm packages
make npm-pack

# Publish all npm packages
make npm-publish-all

Exit Codes

Code Meaning
0 Matches found
1 No matches found
2 Error (invalid arguments, pattern error, etc.)

Comparison with ripgrep

Feature ripgrep (Rust) go-ripgrep (Go)
Language Rust Go
Regex engine Rust regex crate Go regexp stdlib
SIMD optimization Yes Yes (AVX2 for amd64, NEON for arm64)
PCRE2 support Yes No
.gitignore support Yes Yes
JSON output Yes Yes
Go SDK No Yes
npm distribution Via community Built-in
Cross-compilation Rust toolchain GOOS/GOARCH

Note: This project aims for CLI compatibility with ripgrep but may differ in performance and edge-case behavior. For maximum performance on large codebases, consider using the original ripgrep.

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License — see the LICENSE file for details.

Acknowledgments

About

A high-performance line-oriented search tool written in Go — a pure Go port of ripgrep. It provides both a CLI tool (rg) compatible with ripgrep's interface and a Go SDK for programmatic use.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors