# Jump scores directories by how often you visit them, and pins are per-jump not per-key

> Jump is an MIT-licensed Go shell helper that learns your directory habits and lets you cd with a few fuzzy characters, integrating with bash, zsh, fish, PowerShell, Nushell and Murex. It beats a plain fuzzy finder when you have deep hierarchies, and its database is a scoring table you can inspect, pin, import from and clean.

**gsamokovarov/jump** — Jump helps you navigate faster by learning your habits. ✌️

- Repository: https://github.com/gsamokovarov/jump
- Website: http://gsamokovarov.com/jump
- Stars: 1,950 · Forks: 65
- Language: Go
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/gsamokovarov-jump

## Install options, including a curl|bash path and per-distribution packages

Jump is a single Go binary, and the README lists installs for four package managers plus four Linux distributions.

On macOS:

```bash
brew install jump
```

or `port install jump`. On Linux, `sudo snap install jump`. Under Nix, `nix-env -iA nixpkgs.jump`. Or straight from the Go toolchain:

```bash
go install github.com/gsamokovarov/jump@latest
```

The per-distribution entries are Arch `sudo yay -S jump`, Void `xbps-install -S jump`, and wget plus dpkg or rpm for Ubuntu, Debian and Fedora. Note that the README's wget URLs pin v0.67.0 while the current release is v0.69.0, so following the distribution package instructions literally gets you the older build.

There is also a user-local install into `~/.local/bin`:

```bash
curl -fsSL https://raw.githubusercontent.com/gsamokovarov/jump/main/install.sh | bash
```

That is the convenient option and also the one with the least review, since it pipes a script from a branch into your shell. Read install.sh first if you care what you are running.

The Makefile builds with `CGO_ENABLED=0 go build -o jump`, which is why a static binary is possible, and there are separate targets for linux, linux arm64, windows amd64, osx amd64 and osx arm64. Packaging goes through nfpm against nfpm.yaml, with snapcraft.yaml for Snap.

Go 1.21 is the declared minimum in go.mod, and the module has one dependency, gsamokovarov/assert.

## Shell integration is a different command per shell

Jump works through a helper function, `j` by default, and the way you install that function differs per shell.

For bash and zsh:

```bash
eval "$(jump shell)"
```

For fish:

```
jump shell fish | source
```

For PowerShell:

```
Invoke-Expression (&jump shell pwsh | Out-String)
```

For Nushell:

```
jump shell nushell | save --append $nu.config-path
```

And for Murex there is no `jump shell` line at all, because Murex uses a module system and the README points at a separate repository, `murex-package install https://github.com/lmorg/murex-module-jump.git`.

The Nushell case is the one to note: it writes the output into the config file rather than evaluating it, so it persists across sessions. The bash form is the opposite, an eval that you place in your rc file yourself.

Tracking starts on its own. The README states that Jump begins tracking directories automatically once integrated, so there is no separate activation step and no hook to install.

The binding is configurable, and can be set to anything:

```bash
eval "$(jump shell --bind=z)"
```

The most interesting option is binding directly to `cd` with `eval "$(jump shell --bind=cd)"`, after which typing `cd project` performs a fuzzy jump instead of a literal one.

## Fuzzy matching is multi-part, and spaces and slashes are interchangeable

The quick examples in the README cover the range in a compact list:

```bash
j wc               # Fuzzy Jump
j web-console      # Exact Match
j dev/soc/web      # Deep Jump
j ch site          # Multi-Part Match
j app/             # Relative Jump
j .                # Repo Root
j . cable          # Based Mode
j -                # cd -
j ..               # cd ..
j ../..            # cd ../..
j                  # Reverse Jump
j Dev              # Case-Sensitive
```

The deep jump is the core idea. `j dev/soc/web` resolving to `/Users/genadi/Development/society/website` means each slash-separated fragment is matched independently against path components, and the README says explicitly that spaces and slashes work interchangeably, so `j ch site` finds the same place.

Matching is tolerant but not blind. `j wc`, `j console` and `j b-c` all reach web-console, while `j web-console` is labelled exact. And `j Dev` is documented as case-sensitive, reaching `/Users/genadi/Development` when an exact case match exists.

On a case-insensitive filesystem, the behaviour of `j dev` may depend on how the scoring index compares cases.

`j` on its own with no argument is a reverse jump, which is the mechanism that gets you back to a directory you have just left.

## Based mode and the priority order that decides the base

Based mode prefixes a jump with `.` and resolves it relative to a base directory. The README frames it as useful for monorepos with many repeated directory names, and the examples are Rails-shaped:

```bash
j . cable          # -> /Users/genadi/Development/rails/rails/actioncable
j . actionview/app # -> /Users/genadi/Development/rails/rails/actionview/app
j .                # -> /Users/genadi/Development/rails/rails
```

The interesting part is how the base is chosen, because the priority order is explicit:

1. The `$JUMP_BASED_PATH` environment variable
2. The git repository root, detected via `git rev-parse --show-toplevel`
3. The current directory, as a fallback

That means `j .` outside a git repository still works, it just uses your current directory. And it means setting `JUMP_BASED_PATH` overrides everything, which is how you would make based mode behave the same way across a set of unrelated repositories.

The git root default is a deliberate choice rather than a convenience. In a monorepo the root is a stable landmark that the scoring database is unlikely to have polluted with similarly named directories, so `j .` becomes a reliable way home.

Relative jumps are a separate mechanism with their own trigger: if your input contains or ends with a slash, Jump treats it as a relative directory, so `j actioncable/` goes to `./actioncable`. If that relative path does not exist, the README states that it falls back to fuzzy search rather than failing.

## Pins, and why jump top is a diagnostic rather than the interface

Pins are the escape hatch for a directory the scoring database keeps getting wrong.

```bash
cd /Users/genadi/development/rails
jump pin r
```

After that, `j r` goes there. Managing them:

```bash
jump pins
jump unpin r
```

The design detail worth knowing is that a pin is bound to the name you type, not to the path. Pinning `r` for one directory means `j r` goes there, and if your habits later make another directory the more frequent match for `r`, the pin still wins. That is the correct behaviour for a manual override, and it also means a pin is a decision you have to revisit if you reorganise.

The database tools are:

```bash
jump clean         # remove stale entries
jump forget        # forget current directory
jump top           # ranked directories
jump top --score   # ranked directories with numeric scores
jump top dev       # fuzzy filtered list
```

`jump top --score` is the one to run first when the tool feels wrong. It shows the ranking with the numeric scores behind it, which tells you whether a bad jump is a scoring problem, an entry that should be cleaned, or a pin that is overriding what you expected.

`jump clean` removing stale entries and `jump forget` dropping the current directory are the maintenance operations, and they suggest the database accumulates directories that no longer exist or that you no longer want.

## Importing from autojump, z and zoxide merges rather than replaces

Jump accepts an import argument with no value, or one naming a source:

```bash
jump import
jump import autojump
jump import z
jump import zoxide
```

The README states that imports merge into your existing database without overwriting scores. That is the right choice and it is worth trusting, since it means adopting Jump does not start your ranking from zero on day one.

Imports can seed Jump's ranking from an existing directory history without replacing its current scores.

The repository has an `importer/` package, so the sources are implemented in-tree rather than by shelling out and parsing another tool's output format.

The `config/` directory in the repository root and the Makefile's test target, which clears `config/testdata/.tmp*` before running tests, suggest the database is a file under a config directory, but the path is something you confirm from the source or `jump top` output rather than from the documentation.

## Where Jump is the wrong choice

The main alternative in this space is a ranked-menu directory jumper, and the difference is the interaction model. A ranked tool shows you a numbered list and you pick a number. Jump is a free-form fuzzy match where you type characters and press enter, with no list to read.

Free-form is faster once your habits are trained, and much faster for a deep jump with several path fragments, because `j dev/soc/web` is one keystroke sequence. It is worse when several directories match similarly, because there is no list to disambiguate from. If your filesystem has many near-duplicate names and you are not sure which one you want, a menu is the better instrument.

Second, the learning curve is real and the payoff is delayed. Before the database knows your directories, a fuzzy guess can land somewhere you did not intend. `jump top` is how you inspect that state.

Third, this is a shell integration tool and only that. It does not help in a terminal multiplexer's file browser, an editor, or a script. If the friction you have is inside an editor's file picker, this is the wrong category.

Fourth, the fallback behaviour can surprise. A relative jump whose path does not exist silently falls back to fuzzy search, so a typo in a relative path becomes a fuzzy guess rather than an error.

## Maintenance, licence and the versioning gap

The repository is not archived and the last push was on 2026-10-13. v0.69.0 was released on 2026-09-21, with v0.67.0 from 2025-12-12 before it and v0.51.0 from 2022-08-07 before that.

That history shows the project at a mature 0.x with uneven gaps, and it is worth noting that the distribution package URLs in the README still reference v0.67.0 rather than v0.69.0.

The Makefile carries the project metadata directly: name `jump`, the description "Jump helps you navigate faster by learning your habits.", homepage, author Genadi Samokovarov, licence MIT, version 0.69.0. There is also a `man/` directory and a `mise.toml` for tool version management, so there is a manual page and a mise-based path to installing it.

The licence is MIT, with LICENSE.txt at the repository root. That permits commercial use and modification, which is a licensing note and not legal advice.

The Makefile's test and lint targets show how the project checks itself: `go test./... -cover` after clearing test data, and `go vet./...` plus `golint./...`. There is a `.travis.yml` continuous-integration configuration at the repository root.

The repository layout maps directly onto the features described in the README: `fuzzy/` for matching, `scoring/` for the ranking, `shell/` for the per-shell integrations, `importer/` for the migrations, and `cli/` and `cmd/` for the commands.

## Conclusion

Adopt Jump if your shell time is spent in a deep, stable directory tree and you want a free-form fuzzy jump rather than a ranked list, since that is what `j wc` and `j dev/soc/web` give you. Do not adopt it if you need a ranked menu, because that is a different tool's design and `jump top` here is a diagnostic rather than the main interaction. Verify first that your shell is covered, since integration is a per-shell command and Nushell and Murex each need their own syntax rather than the bash eval form.

## FAQ

### How do I install Jump?

On macOS run brew install jump, on Linux sudo snap install jump, under Nix nix-env -iA nixpkgs.jump, or with go install github.com/gsamokovarov/jump@latest. There is also a user-local install into ~/.local/bin using the install.sh script in the repository.

### How do I set up Jump in my shell?

For bash and zsh use eval "$(jump shell)". Fish uses jump shell fish | source, PowerShell uses Invoke-Expression (&jump shell pwsh | Out-String), and Nushell uses jump shell nushell | save --append $nu.config-path. Murex installs a module from lmorg/murex-module-jump instead.

### What does based mode do in Jump?

Prefixing a jump with a dot resolves it against a base directory, which the README finds useful in monorepos. The base is chosen from $JUMP_BASED_PATH first, then the git repository root via git rev-parse --show-toplevel, then the current directory as a fallback.

### Can Jump import my autojump or zoxide history?

Yes. Run jump import, or name a source with jump import autojump, jump import z or jump import zoxide. The README states that imports merge into your existing database without overwriting scores.

### How do I inspect why Jump picked the wrong directory?

Run jump top --score to see ranked directories with their numeric scores, jump top dev to filter the list fuzzily, and jump pins to list manual overrides. jump clean removes stale entries and jump forget drops the current directory.

### What licence is Jump released under?

Jump is released under the MIT licence, declared as LICENSE = MIT in the Makefile with LICENSE.txt at the repository root. This is a licensing note and not legal advice.

## Sources

- [gsamokovarov/jump on GitHub](https://github.com/gsamokovarov/jump)
- [License: MIT](https://github.com/gsamokovarov/jump/blob/main/LICENSE)
- [Project website](http://gsamokovarov.com/jump)
- [README](https://github.com/gsamokovarov/jump/blob/main/README.md)
- [Releases](https://github.com/gsamokovarov/jump/releases)

---

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