Skip to main content

Turning it off in a production build

The main entry ships a production export condition. Under it the package resolves to a module that exports the same three names with the same types and does nothing. Everything else gets the real module.

bundler behaviour
Vite automatic. resolve.conditions carries development|production by default
webpack, Rspack automatic. conditionNames follows mode
esbuild needs --conditions=production
Rollup needs exportConditions: ["production"] on the node-resolve plugin
plain Node gets the real module. Importing it in Node is safe and does nothing

The plugin and the runtime need no such condition. The runtime is reached only through code the plugin injects, and no production build ever sees that code: under Vite the plugin is not loaded outside the dev server, and under webpack and Rspack it is loaded but refuses to transform anything.

The three bundlers in the top half need nothing from you. For esbuild and Rollup, set the condition once in your build config and the rest works the same way.

The explicit pattern stays supported for anyone who wants control instead of automation. It also drops the two calls from the bundle, instead of leaving them pointing at empty functions. Use your own bundler’s dev flag: import.meta.env.DEV is Vite’s, and esbuild, Rollup and Node each spell it differently.

if (import.meta.env.DEV) {
  const { connectDevtools } = await import("nanostores-devtools");

  connectDevtools();
}