Skip to content

Jest Unexpected Token Error in React Native Tests

Problem Statement

When running component tests in a React Native project using Jest (@testing-library/react-native), you may encounter a syntax error like:

Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax

Details:

/HelloWorld.spec.tsx:12
        (0, react_native_1.render)(<HelloWorld_1.HelloWorld />);
                                   ^

SyntaxError: Unexpected token '<'

This error typically occurs when:

  • React Native component tests contain JSX syntax
  • Jest is not properly configured to handle JSX or React Native code
  • Dependencies in node_modules require transformation
  • Configuration conflicts exist between Jest presets

The core issue is that Jest encounters JSX syntax (<HelloWorld />) but lacks the proper configuration to transform it into valid JavaScript.

Update Jest Configuration Structure (Best Approach)

Modify your jest.config.js to use jest-expo preset only:

js
module.exports = {
  preset: "jest-expo",
  transformIgnorePatterns: [
    "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
  ],
  testPathIgnorePatterns: [
    "<rootDir>/node_modules/",
    "<rootDir>/.maestro/",
    "@react-native"
  ],
  testEnvironment: "jsdom",
  setupFiles: ["<rootDir>/test/setup.ts"],
  setupFilesAfterEnv: ["<rootDir>/jest-setup-after-env.js"]
};

Key Changes

  1. Remove conflicting presets
    Eliminate the ts-jest/presets import and usage to avoid configuration conflicts.

  2. Update transformIgnorePatterns
    Use the pattern recommended in the Expo documentation:

    js
    "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
  3. Configure transform explicitly
    Add this transform block to handle file types:

    js
    transform: {
      "^.+\\.(js|jsx|ts|tsx)$": "babel-jest"
    },

Alternative Solution: TypeScript + ts-jest

If you prefer using ts-jest with Expo:

js
module.exports = {
  preset: "jest-expo",
  transform: {
    "^.+\\.(js|jsx|ts|tsx)$": "ts-jest"
  },
  transformIgnorePatterns: [
    "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|native-base|react-native-svg)"
  ],
  // ...rest of your configuration
};

Why These Solutions Work

Conflict Resolution

  • Preset conflicts: Removes conflicts between ts-jest and jest-expo presets
  • JSX transformation: Ensures JSX syntax gets transformed correctly
  • node_modules handling: New regex matches patterns of React Native ecosystem modules that require transformation

Critical Configuration Elements

  1. transformIgnorePatterns rewrite
    The updated pattern excludes common React Native and Expo packages

    js
    // Breakdown:
    node_modules/(?! ... ) // Negate exclude for modules that need processing
    (jest-)?react-native   // Handles both react-native and jest-react-native
    |@react-native(-community)? // Covers react-native community packages
    |expo(nent)?           // Includes all Expo-related packages
    |@expo(nent)?/.*       // Covers scoped Expo packages
    ...other patterns      // Additional essential packages
  2. Transformation handling
    Explicit transform declaration ensures all JS/TS files get processed:

    js
    "^.+\\.(js|jsx|ts|tsx)$": "babel-jest"

WARNING

If you see lingering issues after configuration changes:

  1. Clear Jest cache:
    bash
    npx jest --clearCache
  2. Verify Babel configuration exists:
    js
    module.exports = {
      presets: ['babel-preset-expo'],
    };

Final Configuration Check

Your Jest setup should include:

js
// jest.config.js
module.exports = {
  preset: "jest-expo",
  
  transform: {
    "^.+\\.(js|jsx|ts|tsx)$": "babel-jest"
  },
  
  transformIgnorePatterns: [
    "node_modules/(?!(jest-)?react-native|@react-native(-community)?|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
  ],
  
  testEnvironment: "jsdom",
  
  setupFiles: ["<rootDir>/test/setup.ts"],
  
  setupFilesAfterEnv: [
    "@testing-library/jest-native/extend-expect",
    "<rootDir>/jest-setup-after-env.js"
  ]
};

This configuration resolves the "Unexpected token '<'" error by ensuring all React Native components and JSX syntax are properly transformed before Jest execution.