or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

app-utilities.mderror-handling.mdevent-communication.mdindex.mdnative-modules.mdnative-views.mdpermissions.mdplatform-utilities.mdshared-memory.mduuid-generation.md
tile.json

platform-utilities.mddocs/

Platform Utilities

Cross-platform utilities for environment detection, platform-specific code execution, and browser capability checking.

Capabilities

Platform Detection and Selection

Core platform utilities for detecting the current platform and executing platform-specific code.

/**
 * Platform utilities for cross-platform development
 * Provides current platform detection and platform-specific value selection
 */
interface Platform {
  /**
   * Current platform: 'ios', 'android', or 'web'
   */
  OS: string;
  
  /**
   * Select platform-specific values
   * Returns value matching current platform or fallback
   * @param specifics - Object mapping platforms to values
   * @returns Value for current platform
   */
  select: <T>(specifics: { [platform in PlatformSelectOSType]?: T }) => T;
  
  /**
   * Whether DOM API is available in current environment
   * False in native React runtimes and Node.js
   */
  isDOMAvailable: boolean;
  
  /**
   * Whether environment can attach event listeners to window
   * False in native React runtimes and Node.js
   */
  canUseEventListeners: boolean;
  
  /**
   * Whether environment can inspect screen properties
   * False in native React runtimes and Node.js
   */
  canUseViewport: boolean;
  
  /**
   * Whether JavaScript runs in remote debugging environment
   * When true, synchronous native invocations cannot be executed
   */
  isAsyncDebugging: boolean;
}

/**
 * Platform types supported by Platform.select
 */
type PlatformSelectOSType = 'ios' | 'android' | 'web' | 'native' | 'electron' | 'default';

Usage Examples:

import { Platform } from "expo-modules-core";

// Check current platform
console.log("Running on:", Platform.OS); // 'ios', 'android', or 'web'

// Platform-specific values
const styles = Platform.select({
  ios: {
    backgroundColor: '#007AFF',
    borderRadius: 8,
  },
  android: {
    backgroundColor: '#2196F3', 
    borderRadius: 4,
  },
  web: {
    backgroundColor: '#0066CC',
    borderRadius: 6,
  },
  default: {
    backgroundColor: '#999999',
    borderRadius: 0,
  }
});

// Platform-specific implementations
const storage = Platform.select({
  native: require('@react-native-async-storage/async-storage').default,
  web: window.localStorage,
});

// Conditional functionality based on platform
if (Platform.OS === 'web') {
  // Web-specific code
  document.title = "My App";
} else {
  // Native-specific code
  import('expo-status-bar').then(({ StatusBar }) => {
    // Configure native status bar
  });
}

// Platform grouping with 'native' selector
const apiEndpoint = Platform.select({
  native: 'https://mobile-api.example.com', // Both iOS and Android
  web: 'https://web-api.example.com',
  default: 'https://api.example.com'
});

Environment Capability Detection

Utilities for detecting browser and runtime capabilities.

/**
 * Environment capability detection utilities
 */
const Platform: {
  /**
   * DOM availability - can use document, window objects
   */
  isDOMAvailable: boolean;
  
  /**
   * Event listener capability - can use addEventListener on window
   */
  canUseEventListeners: boolean;
  
  /**
   * Viewport access - can inspect screen dimensions
   */
  canUseViewport: boolean;
  
  /**
   * Remote debugging detection - affects synchronous operations
   */
  isAsyncDebugging: boolean;
};

Usage Examples:

import { Platform } from "expo-modules-core";

// Safe DOM operations
if (Platform.isDOMAvailable) {
  document.title = "My Application";
  const element = document.getElementById('root');
  element?.classList.add('app-loaded');
}

// Event listener setup
if (Platform.canUseEventListeners) {
  window.addEventListener('resize', () => {
    console.log('Window resized');
  });
  
  // Online/offline detection
  window.addEventListener('online', () => {
    console.log('Back online');
  });
}

// Viewport operations
if (Platform.canUseViewport) {
  const screenWidth = window.screen.width;
  const screenHeight = window.screen.height;
  
  // Responsive design decisions
  const isMobile = screenWidth < 768;
  console.log('Mobile device:', isMobile);
}

// Handle debugging environment
if (Platform.isAsyncDebugging) {
  console.warn('Running in remote debugger - some features may be limited');
  
  // Avoid synchronous native calls
  await performAsyncOperation();
} else {
  // Can use synchronous native calls
  const result = performSyncOperation();
}

// Comprehensive environment check
function setupEnvironment() {
  const capabilities = {
    platform: Platform.OS,
    dom: Platform.isDOMAvailable,
    events: Platform.canUseEventListeners,
    viewport: Platform.canUseViewport,
    debugging: Platform.isAsyncDebugging,
  };
  
  console.log('Environment capabilities:', capabilities);
  
  // Configure based on capabilities
  if (capabilities.dom && capabilities.events) {
    setupWebFeatures();
  }
  
  if (!capabilities.debugging) {
    enableSyncFeatures();
  }
}

Platform-Specific Code Organization

Best practices for organizing platform-specific code:

import { Platform } from "expo-modules-core";

// File-based platform selection (recommended for large differences)
const PlatformSpecificComponent = Platform.select({
  ios: require('./Component.ios').default,
  android: require('./Component.android').default,
  web: require('./Component.web').default,
  default: require('./Component.default').default,
});

// Inline platform selection (good for small differences)
const buttonStyles = {
  padding: 12,
  borderRadius: Platform.select({
    ios: 8,
    android: 4,
    web: 6,
    default: 0,
  }),
  backgroundColor: Platform.select({
    ios: '#007AFF',
    android: '#2196F3',
    web: '#0066CC',
    native: '#0080FF', // Both iOS and Android
    default: '#666666',
  }),
};

// Function-based platform selection (for complex logic)
function getNetworkingImplementation() {
  return Platform.select({
    native: () => import('react-native').then(rn => rn.fetch),
    web: () => Promise.resolve(window.fetch),
    default: () => Promise.resolve(globalThis.fetch),
  })();
}

// Platform-specific constants
const CONSTANTS = Platform.select({
  ios: {
    HEADER_HEIGHT: 44,
    TABBAR_HEIGHT: 49,
    STATUS_BAR_HEIGHT: 20,
  },
  android: {
    HEADER_HEIGHT: 56,
    TABBAR_HEIGHT: 56,
    STATUS_BAR_HEIGHT: 24,
  },
  web: {
    HEADER_HEIGHT: 60,
    TABBAR_HEIGHT: 60,
    STATUS_BAR_HEIGHT: 0,
  },
  default: {
    HEADER_HEIGHT: 50,
    TABBAR_HEIGHT: 50,
    STATUS_BAR_HEIGHT: 0,
  },
});

// Runtime platform detection
function handlePlatformFeatures() {
  switch (Platform.OS) {
    case 'ios':
      // iOS-specific features
      import('expo-haptics').then(haptics => {
        haptics.impactAsync('medium');
      });
      break;
      
    case 'android':
      // Android-specific features
      import('expo-system-ui').then(systemUI => {
        systemUI.setBackgroundColorAsync('#FFFFFF');
      });
      break;
      
    case 'web':
      // Web-specific features
      if (Platform.isDOMAvailable) {
        document.title = 'My App';
      }
      break;
      
    default:
      console.log('Unknown platform');
  }
}

Types

/**
 * All platform types supported by Platform.select
 */
type PlatformSelectOSType = 'ios' | 'android' | 'web' | 'native' | 'electron' | 'default';

/**
 * Generic function type for platform-specific value selection
 */
type PlatformSelect = <T>(specifics: { [platform in PlatformSelectOSType]?: T }) => T;