onChange listens for operations your app performs, and watchExternal hands you a live feed of changes made by other processes. Both return cleanup functions so you can remove listeners precisely when they are no longer needed.
onChange(callback)
onChange registers a listener that fires whenever your application performs any write operation on this config target. The operations it covers are: create, save, patch, delete, reset, and import. It does not fire for changes made by external processes — use watchExternal for that.
The method is async and returns a Promise<() => void>. You must await it to get the unlisten function; the unlisten function itself is synchronous. Call it when you no longer need the listener.
onChange is useful for keeping derived UI state in sync — for example, marking a settings form as “saved” after a save or patch fires.
watchExternal(callback)
watchExternal registers an OS-level file-system watcher on the config file and calls your callback whenever an external process modifies it. The callback receives a ConfigChangeEvent whose operation field is always "external_change".
The method returns an async stop function. You must await it to cleanly unregister both the JS event listener and the Rust-side file watcher.
ConfigChangeEvent
BothonChange and watchExternal pass a ConfigChangeEvent to your callback:
targetId is derived from the combination of fileName, baseDir, provider kind, and path options. It lets you safely share a single global event bus and route events to the right handler when you have multiple Configurate instances.
Typical pattern: auto-reload on external change
A common use case is reloading the in-memory config automatically when an external editor modifies the file — for example, a developer tweaking settings during development, or a companion CLI tool writing a config update.ConfigChangeEvent, you can also inspect event.fileName or event.targetId before deciding whether to reload.
Cleaning up listeners
Store the cleanup function
Assign the return value of
onChange or watchExternal to a variable in the scope that owns the listener’s lifetime.Call cleanup on unmount or teardown
In a React component, call cleanup inside the
useEffect return. In a Svelte component, use onDestroy. In plain TypeScript, call them whenever the owning object is disposed.