Rust-powered file system watcher with native OS integration.
Uses FSEvents on macOS and inotify on Linux.
Add to your Gemfile:
gem "cruise"Or install directly:
gem install cruisePrecompiled native gems are available for macOS and Linux. If a precompiled gem isn't available for your platform, it will compile from source (requires Rust).
Watch a directory for changes:
require "cruise"
Cruise.watch("app/views") do |event|
puts "#{event.kind}: #{event.path}"
endThe callback receives a Cruise::Event with two attributes:
| Attribute | Description |
|---|---|
event.path |
Absolute path to the changed file |
event.kind |
One of: "created", "modified", "renamed", "removed", "accessed", "changed" |
Watch several paths at once:
Cruise.watch("app/views", "app/components", "lib/templates") do |event|
puts event.inspect
# => #<Cruise::Event kind="modified" path="/app/views/users/show.html.erb">
endCruise releases the GVL while waiting for filesystem events, so Ruby threads run freely:
Thread.new { do_background_work }
Cruise.watch("src") do |event|
puts event
endOnly receive events for files matching a pattern:
Cruise.watch("app/views", glob: "**/*.html.erb") do |event|
puts event
endMultiple patterns:
Cruise.watch("app", glob: ["**/*.html.erb", "**/*.html"]) do |event|
puts event
endConfigure the debounce interval (default: 100ms):
Cruise.watch("src", debounce: 0.5) do |event|
puts event
endYou can also pass a Proc via the callback: keyword:
handler = proc { |event| puts event }
Cruise.watch("app/views", callback: handler)The watcher runs in a blocking loop. Use Interrupt to stop it cleanly:
begin
Cruise.watch("app") do |event|
# process event
end
rescue Interrupt
puts "Stopped."
endCruise is a Ruby binding (via Magnus and rb-sys) around the Rust notify crate.
Cruise.watchsets up a notify watcher with event debouncing (100ms)- A background thread monitors filesystem events using the OS-native API
- The main loop calls
rb_thread_call_without_gvlto wait without blocking Ruby - When an event arrives, the GVL is re-acquired and your callback is invoked
| Platform | Backend | API |
|---|---|---|
| macOS | FSEvents | CoreServices framework |
| Linux | inotify | inotify_init1 syscall |
All backends watch recursively by default.
Requirements: Rust toolchain, Ruby 3.2+
git clone https://github.com/marcoroth/cruise
cd cruise
bundle install
bundle exec rake compile
bundle exec rake testCruise uses rake-compiler and rake-compiler-dock for building native gems:
bundle exec rake gem:nativeMIT License. See LICENSE.txt.