React Native

React Native "Invariant Violation" Error, Common Causes

"Invariant Violation" isn't a specific bug — it's React Native's generic way of reporting that an internal consistency check failed, which can be triggered by several completely different underlying problems. The specific message following "Invariant Violation" is what actually points to the real cause.

The Problem

The app crashes or shows a red error screen with a message starting with "Invariant Violation," followed by more specific text that varies depending on what actually went wrong:

Invariant Violation: Native module cannot be null.
Invariant Violation: "main" has not been registered.
Invariant Violation: Element type is invalid: expected a string...

Since the underlying causes are so different from each other, treating "Invariant Violation" as a single bug rather than reading the full message is the most common mistake when debugging it.

Why It Happens

Each specific variant of this error points to a different category of problem:

  • "Native module cannot be null" — a native module your JavaScript code expects isn't actually linked or available, common after adding a new native dependency without properly rebuilding the app, or when running Expo Go without a required native module it doesn't include by default
  • "'main' has not been registered" — the app's root component wasn't registered correctly with AppRegistry, often due to a typo in the app name, a missing registration call, or an error during import that prevented the registration code from ever running
  • "Element type is invalid" — a component being rendered is undefined, usually from an incorrect import (default vs. named export mismatch) or a typo in the component name
  • Various other messages — each corresponds to a specific internal check, and the exact wording after "Invariant Violation:" is the actual clue to search for or investigate, rather than the generic prefix

The Fix

For "Native module cannot be null," first confirm the native module is actually installed and properly linked, then do a full native rebuild rather than just a JavaScript reload, since native module linking requires a real build:

npx pod-install ios
npx react-native run-ios
npx react-native run-android

If using Expo, confirm whether the module requires a development build rather than Expo Go, since Expo Go only includes a fixed set of native modules and can't load arbitrary custom native code:

npx expo prebuild
npx expo run:ios

For "'main' has not been registered," check your entry file (usually index.js) to confirm the registration call matches the app name configured elsewhere in your project:

import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';

AppRegistry.registerComponent(appName, () => App);

Also check whether an error earlier in your import chain (a syntax error, a failed import) is preventing this registration code from executing at all — sometimes the actual root cause is a completely unrelated error upstream that silently prevents the app from ever reaching the registration call.

For "Element type is invalid," check the import statement of the component mentioned in the fuller error message, confirming whether it should be a default or named export:

// If MyComponent.js uses: export default MyComponent
import MyComponent from './MyComponent'; // correct

// If MyComponent.js uses: export const MyComponent = ...
import { MyComponent } from './MyComponent'; // correct - note the braces

Mixing these up (using a named import for a default export, or vice versa) results in an undefined value being passed where React expects an actual component, producing exactly this error.

Still Not Working?

If the full error message doesn't clearly point to one of the common patterns above, check whether the issue only appears in release/production builds and not development mode — some invariant violations are specifically related to code that behaves differently once minified or optimized (like relying on function names, which can be altered by minification), and reproducing the issue specifically in a release build configuration is necessary to debug it accurately, since a development-mode reproduction may not trigger the same code path at all.