Skip to content

Types and production

Petar Liovic edited this page Sep 9, 2026 · 1 revision

Dev: instrumented wrappers.
Production: thin calls through to React.
Types: same as React, plus an optional label the plugin injects.

Not a fake react

Basis used to try to stand in for the whole React namespace. That broke on real apps (legacy CJS exports such as forwardRef / unstable_batchedUpdates vs ESM).

Since 0.3.2 the Babel plugin only rewrites the hook and context imports it cares about. Everything else still comes from react.

Types

Wrappers match React’s call shape and add label?: string at the end:

function useState<S>(
  initialState: S | (() => S),
  label?: string
): [S, Dispatch<SetStateAction<S>>];

You do not pass label yourself. Autocomplete stays React’s.

Production shims

The plugin still emits the extra argument in builds that run it. Production files accept that argument and ignore it:

export const useEffect = (
  effect: EffectCallback,
  deps?: DependencyList,
  _label?: string
) => React.useEffect(effect, deps);

The shim must not forward label into React (useReducer init, context default, etc.).

Which file you get

package.json exports:

".": {
  "types": "./dist/index.d.ts",
  "development": "./dist/index.mjs",
  "production": "./dist/production.mjs",
  "default": "./dist/production.mjs"
}

Dev bundlers that honor the development condition get the engine. Production gets the shims. The engine, HUD, and rings are not imported from the production entry.

That is “small,” not “zero bytes.” A few wrapper functions still exist. Default without a condition is production on purpose.

Clone this wiki locally