CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-eslint-plugin-react-native

React Native specific linting rules for ESLint providing comprehensive code quality enforcement for React Native development

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

component-rules.mddocs/

Component Rules

Rules that manage React Native component usage patterns and platform-specific requirements, ensuring proper text wrapping and platform separation.

Capabilities

Split Platform Components Rule

Enforces using platform-specific filenames when components contain Android or iOS specific code, promoting proper code organization and platform separation.

/**
 * ESLint rule that enforces platform-specific components in appropriate files
 * Ensures Android and iOS components are placed in correctly named files
 */
module.exports = {
  meta: {
    fixable: "code", // Supports auto-fixing in some scenarios
    schema: [{
      type: "object",
      properties: {
        androidPathRegex: {
          type: "string" // Custom regex pattern for Android file paths
        },
        iosPathRegex: {
          type: "string" // Custom regex pattern for iOS file paths
        }
      },
      additionalProperties: false
    }]
  },
  create: function(context) {
    // Returns ESLint visitors object with:
    // - VariableDeclarator: Tracks React component destructuring
    // - ImportDeclaration: Tracks react-native imports with platform components
    // - 'Program:exit': Reports platform-specific components in wrong files
  }
};

Configuration Examples:

// Default configuration (built-in patterns)
"react-native/split-platform-components": "error"

// Custom file patterns
"react-native/split-platform-components": ["error", {
  "androidPathRegex": "\\.android\\.(js|ts|jsx|tsx)$",
  "iosPathRegex": "\\.ios\\.(js|ts|jsx|tsx)$"
}]

// Custom patterns for different naming conventions
"react-native/split-platform-components": ["error", {
  "androidPathRegex": "_android\\.(js|ts)$",
  "iosPathRegex": "_ios\\.(js|ts)$"
}]

Usage Examples:

// File: Button.js (would trigger the rule)
import { Platform, TouchableOpacityIOS, TouchableNativeFeedbackAndroid } from 'react-native';

// This should be split into platform-specific files

// File: Button.ios.js (correct)
import { TouchableOpacityIOS } from 'react-native';
export const PlatformButton = TouchableOpacityIOS;

// File: Button.android.js (correct)  
import { TouchableNativeFeedbackAndroid } from 'react-native';
export const PlatformButton = TouchableNativeFeedbackAndroid;

// File: Button.js (shared code - acceptable)
import { View, Text } from 'react-native';

No Raw Text Rule

Detects raw text outside of Text components, ensuring all text content is properly wrapped for React Native compatibility.

/**
 * ESLint rule that detects raw text outside of Text components
 * Ensures all text content is properly wrapped in React Native Text components
 */
module.exports = {
  meta: {
    schema: [{
      type: "object",
      properties: {
        skip: {
          type: "array",
          items: {
            type: "string" // Array of component names to skip validation for
          }
        }
      },
      additionalProperties: false
    }]
  },
  create: function(context) {
    // Returns ESLint visitors object with:
    // - Literal: Analyzes string literals in JSX for raw text
    // - JSXText: Analyzes JSX text nodes for raw text
    // - TemplateLiteral: Analyzes template literals in JSX for raw text
  }
};

Configuration Examples:

// Default configuration
"react-native/no-raw-text": "error"

// Skip validation for custom text components
"react-native/no-raw-text": ["error", {
  "skip": ["CustomText", "StyledText", "FormattedText"]
}]

Usage Examples:

// These would trigger the rule
function BadComponent() {
  return (
    <View>
      Hello World {/* Raw text - not allowed */}
      <Text>Good text</Text>
      {someCondition && "Conditional text"} {/* Raw string - not allowed */}
      <View>
        Some text here {/* Raw text in View - not allowed */}
      </View>
    </View>
  );
}

// Correct usage
function GoodComponent() {
  return (
    <View>
      <Text>Hello World</Text> {/* Properly wrapped */}
      <Text>Good text</Text>
      {someCondition && <Text>Conditional text</Text>} {/* Properly wrapped */}
      <View>
        <Text>Some text here</Text> {/* Properly wrapped */}
      </View>
    </View>
  );
}

// With custom skip components
function ComponentWithCustomText() {
  return (
    <View>
      <CustomText>
        This text is allowed {/* Skipped due to configuration */}
      </CustomText>
      <StyledText>
        This is also allowed {/* Skipped due to configuration */}
      </StyledText>
    </View>
  );
}

Default Allowed Components

The no-raw-text rule includes several components that are allowed to contain raw text by default:

const defaultAllowedElements = [
  'Text',           // Standard React Native Text component
  'TSpan',          // SVG text element
  'StyledText',     // Common styled-components pattern
  'Animated.Text'   // Animated Text component
];

Error Messages

Split Platform Components Messages

// Error messages
"Android components should be placed in android files"
"IOS components should be placed in ios files"
"IOS and Android components can't be mixed" // When both are found in same file

No Raw Text Messages

// Error format: "Raw text ({text}) cannot be used outside of a <Text> tag"
"Raw text (Hello World) cannot be used outside of a <Text> tag"
"Raw text (Click here) cannot be used outside of a <Text> tag"

// For whitespace-only content
"Whitespace(s) cannot be used outside of a <Text> tag"

// For template literals
"TemplateLiteral: ${variableName} cannot be used outside of a <Text> tag"

Platform-Specific Development Patterns

File Organization

// Recommended file structure
components/
├── Button/
│   ├── index.js          // Platform selector or shared logic
│   ├── Button.ios.js     // iOS-specific implementation
│   ├── Button.android.js // Android-specific implementation
│   └── Button.shared.js  // Shared utilities and styles

// Platform selector pattern (index.js)
import { Platform } from 'react-native';
import ButtonIOS from './Button.ios';
import ButtonAndroid from './Button.android';

export default Platform.select({
  ios: ButtonIOS,
  android: ButtonAndroid,
});

Component Detection

The rules automatically detect platform-specific components from common imports:

// Automatically detected as iOS-specific
import { 
  TouchableOpacityIOS,
  ActionSheetIOS,
  DatePickerIOS,
  PickerIOS,
  TabBarIOS,
  NavigatorIOS
} from 'react-native';

// Automatically detected as Android-specific
import {
  TouchableNativeFeedbackAndroid,
  DrawerLayoutAndroid,
  ProgressBarAndroid,
  ToolbarAndroid,
  ViewPagerAndroid
} from 'react-native';

Text Component Patterns

The no-raw-text rule supports various text component patterns:

// Standard patterns (all supported)
import { Text } from 'react-native';
import { Text as RNText } from 'react-native';
import { Animated } from 'react-native';

<Text>Standard text</Text>
<RNText>Aliased text</RNText>
<Animated.Text>Animated text</Animated.Text>

// Custom components via configuration
<CustomText>Custom wrapped text</CustomText>
<StyledText>Styled component text</StyledText>

Best Practices

Platform Separation

  1. Keep shared logic in base files: Common functionality should remain in non-platform-specific files
  2. Use Platform.select for runtime decisions: When platform differences are minor
  3. Use separate files for major differences: When implementations differ significantly
  4. Document platform-specific behavior: Comment why platform separation is needed

Text Wrapping

  1. Always wrap text content: Even single words should be in Text components
  2. Handle conditional text properly: Use Text components inside conditionals
  3. Consider accessibility: Text components provide better accessibility support
  4. Use semantic text components: Create custom text components for different text types (headings, body, etc.)

docs

component-rules.md

index.md

plugin-configuration.md

style-quality-rules.md

stylesheet-rules.md

tile.json