A terminal UI for rsync β manage reusable profiles, preview a transfer as a
structured diff before running it, and watch a live run with progress and
cancellation. All from the terminal, including over SSH where a desktop GUI
can't reach.
rsync is the right tool for backups and syncs, but its flags are easy to get
wrong and a single mistake can delete data. lazyrsync keeps you in the terminal
while giving you the safety of a GUI: save your transfers once, see exactly what
a run will change before it runs, and keep destructive flags behind a gate.
Save a Source β Destination pair once and rerun it with a keystroke.
Press p and watch the transfer resolve into a +/~/- diff with stats.
Nothing is written until you say so.
r runs it β a progress bar fills with byte and file counts. Press c to
stop mid-transfer.
Toggle rsync's options as checkboxes. Flip on --delete and it makes you
confirm before anything can be removed.
Put a user@host:/path on either side of a task and it runs over SSH β remote
source downloads, remote destination uploads.
Keep numbered, hardlinked versions with --link-dest β each run writes the
next directory (1/, 2/, β¦).
rsync must be on your $PATH.
cargo install lazyrsync # crates.io
cargo binstall lazyrsync # prebuilt release binary
brew install westpoint-io/lazyrsync/lazyrsync # Homebrew
yay -S lazyrsync # AUR (Arch)Or build from source:
cargo install --path .lazyrsync # launch the TUI- Press
]to switch to the Profiles sub-tab, thenato add a profile. - Back on Tasks (
]), pressato add a task: an ID, an Action (Sync β Snapshot withβ/β), a Source, and a Destination. Either path may be local or a remoteuser@host:/path. - Press
pto preview (dry-run) β you'll see the exact+/~/-changes and stats, and nothing is written. - Press
rto run it. Watch progress in the Runs panel; presscto cancel.
A task is just Source β Destination, exactly like the rsync command line β
no push/pull, no separate "remote" field. A trailing / on the Source copies
its contents; without it, the folder itself is copied.
lazyrsync can print the exact rsync command a profile resolves to β handy for review or dropping into a script. Running transfers headlessly isn't wired up yet; use the TUI to actually run them.
lazyrsync list # list profiles and their resolved rsync commands
lazyrsync run NAME # print the resolved command(s) for a profile
lazyrsync run NAME -n # print the dry-run form (with -n)Press ? in the app for the full, context-aware list. The essentials:
| Key | Action |
|---|---|
1β4, Tab |
Focus a rail panel (Runs / Tasks Β· Profiles / Flags / Filters) |
] |
Toggle the Tasks / Profiles sub-tab |
j/k, β/β |
Move the cursor |
space / enter |
Select the task (or toggle the highlighted flag) |
a |
Add a task (or profile, on the Profiles sub-tab) |
p |
Preview (dry-run) the selected task |
r / R |
Run the selected task / run every task in the profile |
e / s / i / x |
Edit Basics / SSH / Filters / Advanced |
d |
Delete (confirm first) |
V |
Visual range (multi-select), then r/d acts on the block |
c |
Cancel the running job |
/ |
Filter the list, or search the run output |
q / Esc |
Quit |
Profiles and settings live under $XDG_CONFIG_HOME/lazyrsync/ (typically
~/.config/lazyrsync/):
profiles.tomlβ your profiles and taskssettings.tomlβ preferences (theme, hints,skip_delete_warning)
See CONTRIBUTING.md for the build/test/lint commands, the module map, and the code + UI conventions.
- lazygit β the TUI whose keyboard-driven, panel-based workflow inspired this one.
- ratatui β the Rust TUI library lazyrsync is built on.
MIT.






