# serpl: a Rust terminal UI for search and replace across a whole repo

> serpl is a ratatui based terminal application that searches and replaces text across an entire folder the way VS Code does, with ripgrep as the search engine and an optional ast-grep mode. It is MIT licensed and shipped through Cargo, Homebrew, pacman and nixpkgs, but its own README asks for maintainers.

**yassinebridi/serpl** — A simple terminal UI for search and replace, ala VS Code.

- Repository: https://github.com/yassinebridi/serpl
- Stars: 862 · Forks: 14
- Language: Rust
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/yassinebridi-serpl

## Find and replace across a folder, not a single file

Most terminal grep workflows stop at printing matches. serpl goes one step further and gives you an interface for editing them: the project describes itself as a terminal user interface application that searches and replaces keywords in an entire folder, with functionality similar to what VS Code offers.

The listed features describe a real editing workflow rather than a search box. You can search across a project folder with options for case sensitivity and AST Grep. You can replace with options for preserving case, AST Grep, and regex capture groups written as `$1`. There is an interactive preview of search results, keyboard navigation, and configurable key bindings and search modes.

Two things follow from that feature list. First, this is a project wide tool, so the unit of work is a repository rather than a file, and the results pane holds matches from many files at once. Second, the replace path is designed for bulk edits, which means it is closer in spirit to a refactoring tool than to `sed`. The distinction matters for how much you trust it, since a bulk replace across a repository touches code you may not have read.

## ripgrep does the searching, ratatui draws the panes

The dependency list in `Cargo.toml` shows how the work is split. The interface is built on `ratatui` at version 0.29.0 with the `serde` and `macros` features, and `crossterm` 0.28.1 with `serde` and `event-stream` handles terminal input and the event stream. Text entry in the search and replace boxes uses `tui-input`, and the `strum` derive crate is present for enumerating states.

Searching itself is delegated. ripgrep is listed as a prerequisite that must already be installed on your system, and ast-grep is optional, needed only if you want the AST Grep functionality. On macOS, crossterm is declared again with extra features including `use-dev-tty` and `libc`, which is the kind of per platform detail that only appears when something differs. Async work runs on `tokio` with the `full` feature, and errors are surfaced through `color-eyre`, `human-panic` and `better-panic`, so a crash in a large repository produces a readable message rather than a raw abort.

State handling uses `redux-rs` pinned to `=0.3.3` with the `middleware_thunk` feature, which is how a terminal app routes key presses into actions and reducers. That is a heavier structure than a typical single file TUI, and it is the reason the application can have several panes and modes without tangling them.

The ast-grep feature is declared in `Cargo.toml` as `ast_grep = []`, an empty feature list, and is enabled at install time with the `--features ast_grep` flag. That distinction is the single most important detail for anyone installing this: the capability is compiled in, not toggled.

## Installing from Cargo, then running it against a project root

The README lists ripgrep as a prerequisite and ast-grep as optional. With ripgrep present, the standard install is a Cargo install of the crate:

```bash
cargo install serpl
```

To get the AST Grep functionality compiled in, use the feature flag:

```bash
cargo install serpl --features ast_grep
```

That flag is what separates the two builds. If you skip it and later try an AST Grep search, the option will not exist, and reinstalling with the feature is the fix.

Running the application with no arguments searches the current directory:

```bash
serpl
```

Pointing it at a specific project root is a flag:

```bash
serpl --project-root /path/to/project
```

Hidden files are skipped by default, and `.git` is always excluded. Including them is also a flag:

```bash
serpl --hidden
```

The same toggle is available at runtime with `Ctrl + g`, and it changes behaviour in a way worth knowing before you use it. While hidden files are included, searching on every key press is disabled and the search runs on `Enter` only, with a reminder shown in the search box. The reason is practical: pulling in dotfiles and build artefacts makes every keystroke expensive.

Prebuilt binaries are on the releases page, and the packaging options are broad. Homebrew and Arch Linux are covered directly:

```bash
brew install serpl
```

```bash
pacman -S serpl
```

For Nix, `serpl` has been in nixpkgs since 24.11. On a standalone Nix setup:

```bash
nix profile install nixpkgs#serpl
```

and on NixOS or Home-Manager it is a system or home package entry.

The binary is also worth wiring into an editor. The README has dedicated sections for Neovim integration through toggleterm and for Helix.

## Four panes, one results list, and a config file in any of five formats

The interface is organised as tabs: Search, Replace, Results and Preview, reachable with `Alt + 1..4` or `Ctrl + 1..4`, where the Ctrl variant needs a terminal with extended key support. `Tab` switches between tabs and `Backtab` switches to the previous one. `Esc` exits the current pane or dialog, `Enter` or `y` confirms, and `Esc` or `n` cancels, with `h`, `l` and `Tab` navigating options inside a dialog.

The replacement keys are the ones that matter for bulk edits. `Ctrl + o` processes the replace for all files. `r` replaces the selected file or line, and also processes a replace for the current file or line. `Space` selects or deselects a file in the result list, `a` selects or deselects all files, and `d` deletes the current file or line. `Ctrl + n` toggles search and replace modes, so you can flip between the two inputs without losing what you typed. `/` focuses the search results list, `g`, `Left` or `h` jumps to the top of the list, `G`, `Right` or `l` jumps to the bottom, and `j` and `k` move between items.

Key bindings are not fixed. `serpl` reads a configuration file, and the path to it is printed by `serpl --version`. The README says you can use various file formats, such as JSON, JSON5, YAML, TOML or INI, which is unusual for a small TUI and convenient if you already keep your dotfiles in one of them. A YAML example from the README:

```yaml
keybindings:
  "<Ctrl-d>": "Quit"
  "<Ctrl-c>": "Quit"
  "<Tab>": "LoopOverTabs"
  "<Backtab>": "BackLoopOverTabs"
  "<Ctrl-o>": "ProcessReplace"
  "<Ctrl-b>": "ShowHelp"
  "<Ctrl-n>": "ToggleInputMode"
```

The values are action names rather than raw keys, which is the right way round: you remap a key to an intent, and the intent keeps working if the key changes.

## Where serpl is the wrong tool

The clearest case against it is the small edit. If you need to change one identifier in one file, opening the editor and using its own find and replace is faster than launching a TUI, waiting for ripgrep to walk the tree and navigating panes. serpl earns its startup cost when the change spans many files.

There are harder constraints too. ripgrep must be installed separately, and ast-grep must be installed separately as well, so this is not a self contained binary even though the releases page offers prebuilt ones. The AST Grep mode additionally requires the crate to be compiled with the `ast_grep` feature, which means the release binaries may not be what you want if structural search is the reason you are here.

The bulk replace design carries its own risk. `Ctrl + o` processes the replace for all files at once, which is fast and irreversible. The README does not document a dry run mode or an undo across files, so the preview pane is the only review step in front of a repository wide edit. Treat it as the review surface it is.

Finally, the README opens with a warning that the project needs maintainers and gives a contact address, which tells you something about its long term upkeep without needing to speculate.

## Compared with plain ripgrep and with an editor sidebar

The alternative most teams already have is a pipeline rather than an application: `rg` to find the pattern and an editor to fix it, or `rg` piped into `sed` for a mechanical substitution. The difference in approach is interactivity. ripgrep gives you a list and exits, serpl keeps the process alive with a results pane, a preview pane and a per file selection model, so you decide which matches to act on rather than acting on all of them.

The other alternative is the editor itself, which is the reference point the project names in its description. A modern editor sidebar searches the whole project, shows matches, and lets you replace one occurrence or all of them. serpl moves that workflow into a terminal, where your hands stay on the keyboard and the same motions work over SSH or in a container where no editor is installed. For a team whose editing happens entirely in a terminal, that is the actual argument for it.

Where serpl is genuinely different is the AST Grep mode. A plain text search matches characters, so renaming a function call and its definition requires several patterns. A structural search matches code shape, which is why the project lists AST Grep as a first class option on both the search and the replace side rather than as a plugin.

## Release cadence, licensing and the cost of tracking a 0.x crate

The crate is version 0.3.11 with edition 2021 and an MIT licence, published under the name `serpl` with the description carried over from the README. Releases moved quickly in the last stretch, with 0.3.9 and 0.3.10 both published on 2026-10-02 and 0.3.11 on 2026-10-10, and the last push was on 2026-10-10. The `vergen` build dependency, configured with the `build`, `git`, `gitoxide` and `cargo` features, is what stamps version information into the binary at compile time.

A 0.x version carries an implicit warning, and this one is explicit in the README: the project needs maintainers. That does not make it unusable, and the codebase reads like a small, coherent application rather than an abandoned experiment. The `rust-toolchain.toml` file at the root pins the toolchain used for development, and `Cargo.lock` is committed, so a build is reproducible even if the crate is published loose.

The practical upgrade cost for a user is low. Configuration is a file you own, and the release binaries plus package manager channels mean you usually update with the rest of your tools rather than with a build from source. The real cost sits with the project, not with the users, which is what the README warning is about.

## Conclusion

serpl suits developers who live in a terminal and want VS Code style find and replace over a repository, especially when the edit is a structural one that ast-grep can express. It is the wrong choice for a one line substitution, where `rg` plus your editor is faster, and for anyone unwilling to install ripgrep on the system. Verify first that `cargo install serpl --features ast_grep` compiles on your toolchain, since ast-grep support is a Cargo feature rather than a runtime switch, and check the config path printed by `serpl --version` before you start remapping keys.

## FAQ

### How do I install serpl with ast-grep support?

Install it with the Cargo feature flag: `cargo install serpl --features ast_grep`. The `ast_grep` feature is declared in Cargo.toml as an empty feature, so the capability is compiled in rather than switched on at runtime. The ast-grep binary itself must also be installed on your system.

### What does serpl need on my system before it runs?

ripgrep must be installed, since it is listed as a prerequisite, and ast-grep is optional if you want the AST Grep functionality. Without ripgrep present the search side of the application has nothing to call.

### How do I change the key bindings in serpl?

serpl reads a configuration file whose path is printed by `serpl --version`. You can write it in JSON, JSON5, YAML, TOML or INI, and the `keybindings` section maps a key combination such as `<Ctrl-o>` to an action name such as `ProcessReplace`.

### How do I search hidden files in serpl?

Start with the `--hidden` flag, or toggle it at runtime with `Ctrl + g`. Hidden files are skipped by default and `.git` is always excluded. While hidden files are included, searching on every key press is disabled and the search runs on `Enter` only.

### Which platforms can install serpl from a package manager?

The README documents Homebrew with `brew install serpl`, Arch Linux with `pacman -S serpl`, and Nix, where serpl has been in nixpkgs since 24.11 and installs with `nix profile install nixpkgs#serpl` or as a system package on NixOS and a home package on Home-Manager. Prebuilt binaries are also on the releases page.

## Sources

- [Issues](https://github.com/yassinebridi/serpl/issues)
- [License: MIT](https://github.com/yassinebridi/serpl/blob/main/LICENSE)
- [README](https://github.com/yassinebridi/serpl/blob/main/README.md)
- [Releases](https://github.com/yassinebridi/serpl/releases)
- [yassinebridi/serpl on GitHub](https://github.com/yassinebridi/serpl)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/yassinebridi-serpl
