or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-eslint-config-expo

ESLint configuration for Expo and React Native projects with dual format support

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/eslint-config-expo@10.0.x

To install, run

npx @tessl/cli install tessl/npm-eslint-config-expo@10.0.0

index.mddocs/

ESLint Config Expo

ESLint Config Expo provides comprehensive ESLint configurations specifically designed for Expo and React Native projects. It offers dual configuration format support - both legacy ESLint configuration and modern flat configuration - with platform-specific file extensions, React Native globals, and optimized rules for Expo development.

Package Information

  • Package Name: eslint-config-expo
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install eslint-config-expo

Core Imports

Legacy Configuration Format

// .eslintrc.js
module.exports = {
  extends: ["expo"],
};

Package.json configuration:

{
  "eslintConfig": {
    "extends": ["expo"]
  }
}

Modern Flat Configuration Format

// eslint.config.js
const expoConfig = require("eslint-config-expo/flat");
const { defineConfig } = require("eslint/config");

module.exports = defineConfig([
  ...expoConfig,
  // Your additional configuration
]);

Basic Usage

Legacy Configuration Setup

// .eslintrc.js
module.exports = {
  extends: ["expo"],
  rules: {
    // Your custom rules
  },
};

Flat Configuration Setup

// eslint.config.js
const expoConfig = require("eslint-config-expo/flat");
const { defineConfig } = require("eslint/config");

module.exports = defineConfig([
  ...expoConfig,
  {
    rules: {
      // Your custom rules
    },
  },
]);

Architecture

ESLint Config Expo is structured around several key components:

  • Dual Format Support: Provides both legacy ESLint config and modern flat config formats
  • Modular Configuration: Built from composable utility modules (core, React, TypeScript, Expo)
  • Platform-Specific Extensions: Handles .android.js, .ios.js, .web.js, .native.js file patterns
  • React Native Globals: Pre-configured globals for React Native development environment
  • Plugin Integration: Integrates essential ESLint plugins for React, TypeScript, and Expo development

Capabilities

Legacy Configuration Export

Main ESLint configuration object for traditional ESLint setup.

// default.js - Main export
module.exports = {
  extends: string[];
  globals: Record<string, boolean | 'readonly'>;
  settings: {
    'import/extensions': string[];
    'import/resolver': {
      node: { extensions: string[] };
    };
  };
  overrides: Array<{
    files: string[];
    env?: Record<string, boolean>;
  }>;
};

Flat Configuration Export

Modern ESLint flat configuration array for ESLint 9+ compatibility.

// flat.js - Flat config export
const flatConfig: ESLintFlatConfig[];
module.exports = flatConfig;

interface ESLintFlatConfig {
  files?: string[];
  ignores?: string[];
  languageOptions?: {
    ecmaVersion?: number;
    sourceType?: 'script' | 'module';
    globals?: Record<string, boolean | 'readonly'>;
    parser?: any;
    parserOptions?: Record<string, any>;
  };
  plugins?: Record<string, any>;
  rules?: Record<string, any>;
  settings?: Record<string, any>;
}

Extension Utilities (Legacy)

Platform-aware file extension handling for legacy configuration.

// utils/extensions.js
const jsExtensions: string[]; // ['.js', '.jsx']
const tsExtensions: string[]; // ['.ts', '.tsx', '.d.ts']
const platformSubextensions: string[]; // ['.android', '.ios', '.web', '.native']

/**
 * Generate platform-specific file extensions from base extensions
 * @param extensions - Array of base file extensions (e.g., ['.js', '.jsx'])
 * @param platformSubextensions - Array of platform prefixes (e.g., ['.android', '.ios'])
 * @returns Array of all combinations plus base extensions
 */
function computeExpoExtensions(
  extensions: string[],
  platformSubextensions: string[]
): string[];

Extension Utilities (Flat Config)

Enhanced file extension handling for flat configuration format.

// flat/utils/extensions.js
const jsExtensions: string[]; // ['.cjs', '.mjs', '.js', '.jsx']
const tsExtensions: string[]; // ['.ts', '.tsx', '.d.ts']
const allExtensions: string[]; // Pre-computed extensions including platform variants

/**
 * Generate platform-specific file extensions from base extensions
 * @param baseExtensions - Array of base file extensions (e.g., ['.js', '.jsx'])
 * @param platformSubextensions - Array of platform prefixes (e.g., ['.android', '.ios'])
 * @returns Array of all combinations plus base extensions
 * Note: Function exists but is not exported from flat utils
 */
function computeExpoExtensions(
  baseExtensions: string[],
  platformSubextensions: string[]
): string[];

// Note: platformSubextensions array not exported from flat utils
// allExtensions includes all JS/TS extensions with platform-specific variants pre-computed

Core Configuration Modules

Individual configuration modules that compose the complete ESLint setup.

// Legacy format modules
require('./utils/core.js'): ESLintConfig;      // Core JS/ESLint rules
require('./utils/react.js'): ESLintConfig;     // React-specific rules  
require('./utils/typescript.js'): ESLintConfig; // TypeScript rules
require('./utils/expo.js'): ESLintConfig;      // Expo-specific rules

// Flat format modules
require('./flat/utils/core.js'): ESLintFlatConfig[];
require('./flat/utils/react.js'): ESLintFlatConfig[];
require('./flat/utils/typescript.js'): ESLintFlatConfig[];
require('./flat/utils/expo.js'): ESLintFlatConfig[];

interface ESLintConfig {
  extends?: string[];
  plugins?: string[];
  rules?: Record<string, any>;
  settings?: Record<string, any>;
  env?: Record<string, boolean>;
  globals?: Record<string, boolean | 'readonly'>;
  parser?: string;
  parserOptions?: Record<string, any>;
  ignorePatterns?: string[];
  overrides?: Array<{
    files: string[];
    [key: string]: any;
  }>;
}

Global Variables

Both configuration formats define React Native and Expo-specific global variables:

const globals = {
  __DEV__: 'readonly',           // Development flag
  ErrorUtils: false,             // React Native error utilities
  FormData: false,               // Form data API
  XMLHttpRequest: false,         // HTTP request API
  alert: false,                  // Alert dialog
  cancelAnimationFrame: false,   // Animation frame API
  cancelIdleCallback: false,     // Idle callback API
  clearImmediate: false,         // Immediate API
  fetch: false,                  // Fetch API
  navigator: false,              // Navigator API
  process: false,                // Node.js process
  requestAnimationFrame: false,  // Animation frame API
  requestIdleCallback: false,    // Idle callback API
  setImmediate: false,          // Immediate API
  window: false,                // Browser window
  'shared-node-browser': true,   // Shared globals flag
};

Platform-Specific File Support

Both configurations automatically handle platform-specific file extensions:

  • Android: .android.js, .android.ts, .android.jsx, .android.tsx
  • iOS: .ios.js, .ios.ts, .ios.jsx, .ios.tsx
  • Web: .web.js, .web.ts, .web.jsx, .web.tsx
  • Native: .native.js, .native.ts, .native.jsx, .native.tsx

Web files automatically enable browser environment globals.

Plugin Integration

The configuration integrates these essential ESLint plugins:

  • eslint-plugin-expo: Expo-specific linting rules
  • eslint-plugin-react: React JSX and component rules
  • eslint-plugin-react-hooks: React hooks rules validation
  • eslint-plugin-import: Import/export statement validation
  • @typescript-eslint/eslint-plugin: TypeScript-specific rules
  • @typescript-eslint/parser: TypeScript parsing support

Expo-Specific Rules

The configuration enforces these Expo-specific ESLint rules:

  • expo/use-dom-exports: Ensures proper usage of DOM exports in Expo projects
  • expo/no-env-var-destructuring: Prevents destructuring of environment variables that may not be available at build time
  • expo/no-dynamic-env-var: Prevents dynamic access to environment variables that should be statically analyzable

Special File Handling

TypeScript Declaration Files

.d.ts files have import ordering rules disabled for better compatibility.

Metro Configuration

metro.config.js files are configured with Node.js environment for proper Metro bundler integration.

Build Directory Ignoring

Android build intermediates in android/app/build directories are automatically ignored.

Advanced Usage Examples

Extending with Custom Rules

// .eslintrc.js (Legacy)
module.exports = {
  extends: ["expo"],
  rules: {
    "no-console": "warn",
    "prefer-const": "error",
  },
};
// eslint.config.js (Flat)
const expoConfig = require("eslint-config-expo/flat");

module.exports = [
  ...expoConfig,
  {
    rules: {
      "no-console": "warn",
      "prefer-const": "error",
    },
  },
];

Platform-Specific Overrides

// .eslintrc.js (Legacy)
module.exports = {
  extends: ["expo"],
  overrides: [
    {
      files: ["*.ios.*"],
      rules: {
        "no-restricted-imports": ["error", { patterns: ["**/android/**"] }],
      },
    },
    {
      files: ["*.android.*"],
      rules: {
        "no-restricted-imports": ["error", { patterns: ["**/ios/**"] }],
      },
    },
  ],
};

TypeScript Project Configuration

// .eslintrc.js (Legacy)
module.exports = {
  extends: ["expo"],
  overrides: [
    {
      files: ["*.ts", "*.tsx"],
      rules: {
        "@typescript-eslint/no-unused-vars": "error",
        "@typescript-eslint/explicit-function-return-type": "warn",
      },
    },
  ],
};