Leaving it in production
Shipping the code is safe. Two switches decide whether anything runs.
Shipping the code is safe. Until .init() runs, nothing is patched and nothing is recorded, so the
cost of leaving the package in a production bundle is the bundle size and nothing else.
There are two switches, and they do different jobs:
- Capture —
if (DEVTOOLS_ENABLED) devtools.init();patchesfetch,XMLHttpRequestandconsole. Skip it and nothing is ever recorded. - Access —
{DEVTOOLS_ENABLED && <DevtoolsOverlay />}draws the floating button. Skip it and there is no way into the panel.
DEVTOOLS_ENABLED is whatever condition you want, evaluated at runtime.
process.env.EXPO_PUBLIC_APP_ENV !== 'prod' from the Quick start and
__DEV__ are the two usual choices; anything else works too, including a value you fetch for a
specific user.
Guarding the overlay is belt and braces
It hides itself until init() has brought the panel up, so skipping the init() call alone is
enough. Guarding both is still worth doing — it keeps the component out of the render tree entirely.
That also settles the Debug tab, whose buttons call straight into the native
module and are not restricted to development builds. They live behind the panel, and the panel is
unreachable without init().
The two things that do run in production
- Crash reporting, if you asked for it.
crash: { enableWhileDevtoolsDisabled: true }installs the handlers when the client is constructed rather than atinit(). It is the one subsystem meant to survive into a release build — see Crash reporting. - The
>prompt, if you calledinit().console.repldefaults totrueand is not gated on__DEV__, so a build that callsinit()gets a prompt that runs whatever is typed into it. Setconsole: { repl: false }for any build where that is not what you want.