31 releases (18 stable)

Uses new Rust 2024

1.6.1 Jul 8, 2026
1.6.0 Jul 5, 2026
1.5.0 Jun 3, 2026
1.4.2 May 29, 2026
1.3.0 Feb 28, 2026

#494 in Filesystem

Download history 1074/week @ 2026-03-25 2655/week @ 2026-04-01 2567/week @ 2026-04-08 3434/week @ 2026-04-15 1725/week @ 2026-04-22 2575/week @ 2026-04-29 3491/week @ 2026-05-06 4813/week @ 2026-05-13 4517/week @ 2026-05-20 3481/week @ 2026-05-27 3970/week @ 2026-06-03 4276/week @ 2026-06-10 2644/week @ 2026-06-17 1806/week @ 2026-06-24 2774/week @ 2026-07-01 2548/week @ 2026-07-08

10,170 downloads per month
Used in 10 crates (4 directly)

MIT license

710KB
14K SLoC

Zig 11K SLoC // 0.1% comments Rust 3K SLoC // 0.1% comments

zlob

Zlob is a very fast glob implementation that is faster than ignore crate and event glibc. It is written in zig with hot paths for everythin and also allows globbing on the file path list in memory and provides a way more flexible API and support for a way larger set of patterns.

Requirements

To compile this crate you have to install zig 0.16.0 compiler toolchain and have it in your PATH.

Misc

zlob rust's crate is maintained by the authors of zlob zig sources so this crate is officially supported and updated on every release.

Find the rust docs on docs.rs and the zig sources on github


lib.rs:

zlob

High-performance glob pattern matching and file system walker with SIMD optimizations.

zlob is a Rust binding to the zlob library, which provides:

  • POSIX-compatible glob pattern matching
  • All modern globbing features are supported: ** recursive, {braces}, and even extglob
  • SIMD-optimized pattern matching for high performance (faster than globset and glob)
  • gitignore suppor that is faster than ignore crate (cause gitignore is glob)
  • per platform optimized parallel file walker (much faster than ignore and walkdir)
use zlob::{zlob, ZlobFlags};

// RECOMMENDED enables: brace expansion, recursive **, tilde expansion, no sorting
if let Some(result) = zlob("**/*.rs", ZlobFlags::RECOMMENDED)? {
    for path in &result {
        println!("{}", path);
    }
}

Basic Usage

use zlob::{zlob, ZlobFlags};

if let Some(result) = zlob("**/*.rs", ZlobFlags::RECOMMENDED)? {
    for path in &result {
        println!("{}", path);
    }
}

// Use brace expansion
if let Some(result) = zlob("src/{lib,main}.rs", ZlobFlags::BRACE)? {
    // Index access
    if !result.is_empty() {
        println!("First match: {}", &result[0]);
    }

    // Convert to Vec<String>
    let paths: Vec<String> = result.to_strings();
}

Path String Matching (No Filesystem Access)

For filtering a list of paths without filesystem access, use zlob_match_paths:

use zlob::{zlob_match_paths, ZlobFlags};

let paths = ["src/lib.rs", "src/main.rs", "README.md"];
if let Some(matches) = zlob_match_paths("*.rs", &paths, ZlobFlags::empty())? {
    assert_eq!(matches.len(), 2);
    for path in &matches {
        println!("{}", path);
    }
}

This is a zero-copy operation - the results reference the original input strings.

Gitignore based file walking

use zlob::walk::WalkBuilder;

// Defaults: gitignore respected, hidden entries skipped, one worker per CPU.
let results = WalkBuilder::new("./src")?.collect()?;
for entry in results.iter() {
    println!("{}", entry.path().display());
}

Stream entries instead of materializing them, walkdir-style:

use zlob::walk::{WalkBuilder, WalkFlags, WalkState};

WalkBuilder::new(".")?
    .options(WalkFlags::empty()) // no gitignore, include hidden
    .run(|entry| {
        println!("{}", entry.path().display());
        WalkState::Continue
    })?;

Flags

For most use cases, use ZlobFlags::RECOMMENDED:

use zlob::{zlob, ZlobFlags};

let result = zlob("**/*.rs", ZlobFlags::RECOMMENDED)?;

// Add more flags as needed
let result = zlob("**/*.rs", ZlobFlags::RECOMMENDED | ZlobFlags::GITIGNORE)?;

Control matching behavior with individual ZlobFlags:

use zlob::ZlobFlags;

// Combine flags with bitwise OR
let flags = ZlobFlags::BRACE | ZlobFlags::DOUBLESTAR_RECURSIVE | ZlobFlags::PERIOD;

// Common flags:
// - RECOMMENDED: Best defaults for typical usage (see above)
// - BRACE: Enable {a,b,c} expansion
// - DOUBLESTAR_RECURSIVE: Enable ** recursive directory matching
// - TILDE: Enable ~ home directory expansion
// - NOSORT: Don't sort results (faster)
// - PERIOD: Allow wildcards to match leading dots
// - GITIGNORE: Filter results with .gitignore rules
// - ONLYDIR: Match only directories

Supported Patterns

We support all the varieties of glob pattern supported by rust's glob crate, posix glob(3), glibc glob() implementation and many more.

Here are some of the most common patterns:

Pattern Description
* Matches any string (including empty)
? Matches any single character
[abc] Matches one character from the set
[!abc] Matches one character NOT in the set
[a-z] Matches one character in the range
** Matches zero or more path components (requires DOUBLESTAR_RECURSIVE or RECOMMENDED)
{a,b} Matches alternatives (requires BRACE or RECOMMENDED)
~ Home directory (requires TILDE or RECOMMENDED)
~user User's home directory (requires TILDE or RECOMMENDED)

Note: By default (for glibc compatibility), ** is treated as *, and braces are not supported Use ZlobFlags::DOUBLESTAR_RECURSIVE or ZlobFlags::RECOMMENDED for recursive matching.

Error Handling

Operations return Result<Option<_>, ZlobError>:

  • Ok(Some(result)) - matches found
  • Ok(None) - no matches (not an error)
  • Err(ZlobError) - actual error (out of memory, aborted, etc.)
use zlob::{zlob, ZlobFlags, ZlobError};

match zlob("**/*.rs", ZlobFlags::RECOMMENDED) {
    Ok(Some(result)) => println!("Found {} files", result.len()),
    Ok(None) => println!("No files matched"),
    Err(ZlobError::Aborted) => println!("Operation aborted"),
    Err(ZlobError::NoSpace) => println!("Out of memory"),
    Err(e) => println!("Error: {e}"),
}

Dependencies

~0–2MB
~39K SLoC