Skip to content


CI Coverage pypi license

Documentation for version: v0.18.1.

Simple, modern and high performance file watching and code reload in python.

Underlying file system notifications are handled by the Notify rust library.

This package was previously named "watchgod", see Migrating from watchgod for more information.


Here are some examples of what watchfiles can do:

watch Usage
from watchfiles import watch

for changes in watch('./path/to/dir'):
See watch docs for more details.

watch (and all other methods) can watch either files or directories and can watch more than one path with a single instance.

awatch Usage
import asyncio
from watchfiles import awatch

async def main():
    async for changes in awatch('/path/to/dir'):
See awatch docs for more details.

run_process Usage
from watchfiles import run_process

def foobar(a, b, c):

if __name__ == '__main__':
    run_process('./path/to/dir', target=foobar, args=(1, 2, 3))
See run_process docs for more details.

arun_process Usage
import asyncio
from watchfiles import arun_process

def foobar(a, b, c):

async def main():
    await arun_process('./path/to/dir', target=foobar, args=(1, 2, 3))

if __name__ == '__main__':
See arun_process docs for more details.


watchfiles requires Python 3.7 to Python 3.10.

From PyPI

Using pip:

pip install watchfiles

Binaries are available for:

  • Linux: x86_64, aarch64, i686, armv7l, musl-x86_64 & musl-aarch64
  • MacOS: x86_64 & arm64 (except python 3.7)
  • Windows: amd64 & win32

From conda-forge

Using conda or mamba:

mamba install -c conda-forge watchfiles

Binaries are available for:

  • Linux: x86_64
  • MacOS: x86_64 & arm64 (except python 3.7)
  • Windows: amd64

From source

You can also install from source which requires Rust stable to be installed.

How Watchfiles Works

watchfiles is based on the Notify rust library.

All the hard work of integrating with the OS's file system events notifications and falling back to polling is palmed off onto the rust library.

"Debouncing" changes - e.g. grouping changes into batches rather than firing a yield/reload for each file changed is managed in rust.

The rust code takes care of creating a new thread to watch for file changes so in the case of the synchronous methods (watch and run_process) no threading logic is required in python. When using the asynchronous methods (awatch and arun_process) anyio.to_thread.run_sync is used to wait for changes in a thread.