Skip to content
Cross platform file notification with built-in task execution and a client/server feature to overcome virtual folders without relying on polling.
Go PowerShell
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
go.mod add readme and prepare for release May 3, 2019


Cross platform file notification with built-in task execution and a client/server feature to overcome virtual folders without relying on polling.


  • Works on virtual folders/shared folders like those in VirtualBox, VMWare and Docker.
  • Works on Windows, Linux, OSX without polling.
  • Single binary, no dependency.
  • Advanced task running feature to run build commands.
  • HTTP client/server can be integrated into other apps/libraries.


Download the precompiled binaries at the release page.

Or if you have Go installed you can run: go get


   xnotify [options] [-- <command> [args...]...]


   --include value, -i value  Include path to watch recursively.
   --exclude value, -e value  Exclude files from the search using Regular Expression. This only applies to files that were passed as arguments.
   --shallow                  Disable recursive file globbing. If the path is a directory, the contents will not be included.
   --listen value             Listen on address for file changes e.g. localhost:8080 or just :8080. See --client on how to send file changes.
   --base value               Use this base path instead of the working directory. This will affect where --include finds the files. If using --listen, it will replace the original base path that was used at the sender. (default: "./")
   --client value             Send file changes to the address e.g. localhost:8080 or just :8080. See --listen on how to receive events.
   --batch milliseconds       Send the events together if they occur within given milliseconds. The program will only execute given milliseconds after the last event was fired. Only valid with -- argument. (default: 0)
   --trigger                  Run the given command immediately even if there is no file change. Only valid with -- argument.
   --verbose                  Print verbose logs.
   --help, -h                 Print this help.
   --version, -v              print the version

Basic Use

Watch all files under some_dir and another_dir/*.js recursively and exclude .git folder. Send all events to using xargs.

./xnotify --exclude "^\.git$" --include some_dir --include another_dir/*.js | xargs -L 1 ./
# or a shorter form
./xnotify -e "^\.git$" -i some_dir -i another_dir/*.js | xargs -L 1 ./

Disable recursive file matching. Only watch everything under current directory only.

./xnotify --shallow -i *

Advanced file matching using external program.

find *.css | ./xnotify | xargs -L 1 ./


To use file notification on a virtual file system such as VirtualBox shared folder, you need to run the app on the host machine and VM. Both must point to the same port. Ensure the firewall is not blocking.

Watch all files in the current directory on the host machine and send events to port 8090:

./xnotify --client ":8090" -i .

On the VM:

./xnotify --listen "" --base "/opt/wwww/project" | xargs -L 1 ./

You need to set --base if the working directory path is different on the host and VM. Remember to use because the traffic is coming from outside the system.

Task Runner

Run multiple commands when a file changes. Kills and runs the commands again if a new event comes before the commands finish. Use --batch 100 to run the command only 100ms after the last event happened. This will batch multiple events together and execute the command only once instead of restarting it for every single event. Commands will run in order as if the && operator is used. Be careful not to run commands that spawn child processes as the child processes might not terminate with the parent processes.

./xnotify -i . -e "\.git$" --batch 100 -- my_lint arg1 arg2 -- ./ --flag value -- ./

This will run the commands in the same manner as:

my_lint arg1 arg2 && ./ --flag value && ./

You can also set the --trigger option if you want your command to run immediately before any file changes:

./xnotify -i . --trigger -- 8080

Real World Examples

How to Get File Notification Working on Docker, VirtualBox, VMWare or Vagrant

Go: Automatically Run Tests or Reload Web Server on File Changes

How to Compile Go Code 40% Faster With RAM Disk

Similar Tools

  • inotify
  • fswatch
  • nodemon
  • entr

Related Project

Thanks to for the cross platform notification library.

You can’t perform that action at this time.