fd
Prefer fd over find for filesystem searches. fd is faster on large trees, has saner defaults (respects .gitignore, smart case, regex by default), and a more ergonomic CLI.
Works with
Agent Skills format with YAML frontmatter. Claude Code reads it as-is.
---
name: "fd"
description: "Prefer fd over find for filesystem searches. fd is faster on large trees, has saner defaults (respects .gitignore, smart case, regex by default), and a more ergonomic CLI."
license: "MIT"
---
# fd
Prefer `fd` over `find` for filesystem searches.
`fd` is faster on large trees,
has saner defaults
(respects `.gitignore`, smart case, regex by default),
and a more ergonomic CLI.
Authoritative documentation:
https://github.com/sharkdp/fd
(README + `fd --help`).
Verify any non-trivial form against the manual before relying on it.
## Why
- Parallel directory traversal —
noticeably faster than `find` on large repos.
- Sensible defaults out of the box:
hidden entries skipped,
`.gitignore` / `.ignore` / `.fdignore` honored when inside a git
repo,
smart case
(case-insensitive unless the pattern has an uppercase letter),
patterns are regex by default.
- Pattern matches against the filename by default,
not the full path —
`fd foo` does what `find . -iname '*foo*'` does,
without the wildcards-and-quotes ritual.
- Parallel `-x` execution,
null-separated output (`-0`),
and a single set of options that compose without
`-print`/`-prune` gymnastics.
## Rule
```sh
fd PATTERN [PATH]
```
The first positional argument is the pattern;
the second is the search root
(defaults to the current directory).
A path-shaped first argument (containing `/`) is **not** a path —
use `fd . PATH` or `fd --full-path PATTERN`.
## Direct substitutions
| Don't | Do |
| ----------------------------------------------- | ------------------------------- |
| `find . -name 'foo*'` | `fd '^foo'` |
| `find . -iname '*.md'` | `fd -e md` |
| `find . -type f -name foo` | `fd -t f foo` |
| `find . -type d -name node_modules` | `fd -t d node_modules` |
| `find . -type l` | `fd -t l` |
| `find . -name '*.txt' -delete` | `fd -e txt -X rm` |
| `find . -name '*.txt' -exec rm {} \;` | `fd -e txt -x rm` |
| `find . -name node_modules -prune` | `fd -E node_modules` |
| `find . -size +100M` | `fd -S +100mi` |
| `find . -mtime -7` | `fd --changed-within 7d` |
| `find . -mtime +7` | `fd --changed-before 7d` |
| `find . -name '*.go' -print0 \| xargs -0 wc -l` | `fd -e go -0 \| xargs -0 wc -l` |
| `find /etc -name passwd` | `fd passwd /etc` |
| `find / -name foo` | `fd -u foo /` |
For an exact `find -size` match,
use the binary suffixes
(`ki`, `mi`, `gi`) —
`-S +100m` is `100 * 10^6` bytes,
`-S +100mi` is `100 * 2^20` bytes.
For `find /` searches that should also descend into hidden and
`.gitignore`-d directories,
add `-u` (alias for `--no-ignore --hidden`).
## Idioms
Match by extension (one or many):
```sh
fd -e md
fd -e h -e cpp
```
Glob mode for shell-style patterns
(`-g` so `**` and `*` mean the usual thing):
```sh
fd -g '**/*.test.ts'
fd -g 'libc.so' /usr
```
Match against the full path,
not just the filename:
```sh
fd --full-path 'src/.*\.proto$'
```
Include hidden entries
(`.git`, `.vscode`, etc.)
but keep `.gitignore` rules:
```sh
fd -H pre-commit
```
Disregard `.gitignore` rules but keep hidden entries hidden:
```sh
fd -I node_modules
```
Search everywhere — both hidden and ignored:
```sh
fd -u PATTERN
```
Exclude paths
(glob syntax, overrides every ignore rule, repeatable):
```sh
fd -E .git -E '*.bak' PATTERN
```
Limit depth:
```sh
fd -d 2 -t d
```
Combine multiple required patterns
(all must match the filename, regex by default):
```sh
fd 'foo' --and 'bar' --and 'baz'
```
Execute per result
(parallel, `{}` substitution, no `\;` terminator):
```sh
fd -e jpg -x convert {} {.}.png
```
Execute once with all results as arguments
(batch tools like `wc`, `clang-format`, `rg`):
```sh
fd -e rs -X wc -l
```
Pipe null-separated to other tools:
```sh
fd -e go -0 | xargs -0 wc -l
```
## Footguns
- **First positional argument is the pattern, not the path.**
`fd /etc/passwd` interprets `/etc/passwd` as a regex with `/` in it
and errors out
with the suggestion to use `fd . /etc/passwd`
or `--full-path`.
- **Default search excludes hidden and `.gitignore`d entries.**
When looking for something inside `node_modules` or `.git`,
add `-H -I` (or `-u`)
or the result list will be empty for the wrong reason.
- **`--exec` parallelizes by default.**
Output order is non-deterministic.
Pass `-j 1` (or `--threads 1`) when serial execution is required.
- **Patterns are regex by default.**
A bare `.` matches any character;
for a literal `.foo` anchor it (`'\.foo$'`)
or pass `-F`/`--fixed-strings`.
- **Size suffixes are decimal SI by default.**
`-S +100m` is `100 MB` (`10^6` bytes per `m`);
use `mi`/`ki`/`gi` for binary units when matching `find -size`
semantics exactly.
## Fallback to `find`
`fd` is not always available —
minimal CI images,
locked-down servers,
container base images without package extras.
Probe with `command -v` and fall back to `find`:
```sh
if command -v fd >/dev/null; then
fd -e log -t f -X rm
else
find . -type f -name '*.log' -exec rm {} +
fi
```
For a one-shot snippet in a controlled local environment,
use `fd` directly.
Switch to `find` unconditionally only when the target host is known
not to have `fd`
(e.g. a minimal Alpine container without `fd` in the image).
Do **not** install `fd` automatically just to satisfy this skill —
the fallback is the correct response when it is missing.
## Installing `fd`
- macOS: `brew install fd`
- Debian/Ubuntu: `apt install fd-find` —
the binary is named `fdfind`
to avoid a name conflict
(`alias fd=fdfind` is the standard workaround).
- Fedora: `dnf install fd-find`
- Arch: `pacman -S fd`
- Alpine: `apk add fd`
- Prebuilt binaries and other platforms:
https://github.com/sharkdp/fd/releases
When mise manages the host's tools,
the registry shortname `fd` resolves to `aqua:sharkdp/fd` —
install with `mise use -g fd@<version>`
(pinned, per the project's `mise` skill).
Do **not** use the `ubi:` backend —
the `mise` skill disables it.
## Scope
Applies anywhere a shell snippet searches the filesystem:
- `Bash` tool invocations.
- Snippets in `SKILL.md` / `README.md` / docs.
- Scripts under `scripts/`.
- Makefile recipes.
- CI configs.
- Install instructions.
If you encounter a `find` invocation while editing a file,
replace it with the equivalent `fd` form
(plus the `find` fallback when the snippet must run on a host that
may not have `fd`)
as part of the same edit.More General & Other skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
grill-with-docs
mattpocock/skills
A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.

