RBWatch
RBWatch is a Ruby process watcher inspired by nodemon.
It watches source files recursively and restarts the process automatically when changes are detected.
Goals
- Clean architecture
- Delightful terminal output
- Reliable process lifecycle management
- Works on Linux, macOS, and WSL
Installation
bundle install
If you install RBWatch globally with RubyGems, the rbwatch and rbw executables are available directly on your shell PATH:
gem install rbwatch
If you want to use RBWatch from another project while developing locally, add it to that project's Gemfile:
gem "rbwatch", path: "../../../open-source/rbwatch"
Then run:
bundle install
Usage
From this repository checkout
Run a Ruby app directly:
rbwatch app.rb
If you are working from this repository checkout:
bundle exec exe/rbwatch app.rb
Or use the alias:
rbw app.rb
If you are running from this repository checkout, use:
bundle exec exe/rbw app.rb
From another project
If RBWatch is added to another project's Gemfile, run it through Bundler:
bundle exec rbwatch app.rb
bundle exec rbw app.rb
Bundler makes the executables available to the bundle, but it does not place them on your shell PATH.
If you want a direct command without bundle exec, generate binstubs in that project:
bundle binstubs rbwatch
bin/rbw app.rb
If the first argument is a Ruby file, RBWatch expands it to ruby app.rb automatically.
You can still run explicit commands:
bundle exec exe/rbwatch ruby app.rb
Or watch a Bundler-driven command:
bundle exec exe/rbwatch bundle exec ruby app.rb
Useful flags:
bundle exec exe/rbwatch --delay 500 ruby app.rb
bundle exec exe/rbwatch --ext rb,erb,yml ruby app.rb
bundle exec exe/rbwatch --ignore tmp,log,node_modules ruby app.rb
bundle exec exe/rbwatch --clear ruby app.rb
bundle exec exe/rbwatch --no-clear ruby app.rb
bundle exec exe/rbwatch --verbose ruby app.rb
bundle exec exe/rbwatch --no-banner ruby app.rb
bundle exec exe/rbwatch --no-color ruby app.rb
bundle exec exe/rbwatch --theme neon ruby app.rb
bundle exec exe/rbwatch --watch app,config ruby app.rb
bundle exec exe/rbwatch --config rbwatch.yml ruby app.rb
Configuration File
RBWatch can load a YAML configuration file with --config or automatically discover rbwatch.yml, rbwatch.yaml, .rbwatch.yml, or .rbwatch.yaml in the current directory.
Example rbwatch.yml:
delay: 300
extensions:
- rb
- erb
- yml
ignore:
- tmp
- log
watch_paths:
- app
- config
command: ruby app.rb
clear: true
verbose: true
banner: true
color: true
theme: neon
CLI options always win over values from the config file.
Defaults
RBWatch watches these extensions by default:
rberbhamlslimrakeymlyamljson
Ignored paths by default:
logtmp.gitnode_modules
Default debounce delay: 300ms
By default, RBWatch clears the visible terminal and scrollback before each restart when it is attached to a TTY. Use --no-clear or clear: false if you want to keep previous output on screen.
The startup dashboard shows the command, watched roots, theme, and config file when available.
If you pass --stats, the status card also shows restart count and uptime.
Architecture
rbwatch/
├── bin/
│ ├── rbwatch
│ └── rbw
├── exe/
│ ├── rbwatch
│ └── rbw
├── lib/
│ └── rbwatch/
│ ├── cli.rb
│ ├── configuration.rb
│ ├── dashboard.rb
│ ├── file_scanner.rb
│ ├── process_manager.rb
│ ├── runner.rb
│ ├── theme.rb
│ ├── watcher.rb
│ ├── version.rb
│ └── rbwatch.rb
└── spec/
Notes
- Process spawning uses
spawn. - Restarting uses
Process.kill("TERM", pid)first and escalates if the process refuses to exit. - CTRL+C and
TERMare handled gracefully. - The UI uses TTY gems for boxed layouts, cursors, spinners, tables, and screen sizing.
- Fast startup failures do not restart in a tight loop; RBWatch waits for file changes before trying again.
Future-ready hooks
The configuration layer already leaves room for:
--exec--config rbwatch.yml--watch app,config--sound--desktop-notify--history--theme neon--theme minimal--theme retro--theme ruby--theme matrix