Plugin runtime and troubleshooting
Configured plugins
Plugins listed in esdev.json run in a separate isolate on its own thread, under esdev's full development grant. The application's --deny-* flags and scoped permissions do not restrict that plugin isolate. A configured plugin is code you chose to run with esdev's authority.
A synchronous handler blocks the plugin isolate and delays other hooks using it. The application runs separately. Keep handlers async and wait for I/O with await so other hook calls can make progress.
Programmatic builds
Plugins passed to build() from runtime:build run in the calling program's isolate, under its grants. A plugin that reads a file needs FileRead, like anything else in that program.
The bundler works on threads of its own and posts hook calls to that isolate; several can be in flight at once. A synchronous handler blocks the calling program too, including a server it runs. An async handler awaiting I/O lets the program and other hooks continue.
esdev's CSS Modules pass uses the same contract and ordered list as your plugins. React Fast Refresh is supplied by a configured plugin; see React refresh for the template and reusable package.
See also
runtime:build— the options, theBundle, and every field of a hook's answerInternals: the bundler bridge — how a hook call gets from a parallel Rust bundler into a single-threaded isolate and back, and what it costs
runtime:watch— the other half of an incremental dev server