CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-expo-localization

Provides an interface for native user localization information in React Native applications.

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

Expo Localization

Expo Localization provides an interface for native user localization information in React Native applications. It offers both function-based APIs and reactive React hooks to access locale-specific data including language tags, currency codes, measurement systems, calendar preferences, and formatting settings.

Package Information

  • Package Name: expo-localization
  • Package Type: npm
  • Language: TypeScript
  • Installation: npx expo install expo-localization or npm install expo-localization

Core Imports

import { 
  getLocales, 
  getCalendars, 
  useLocales, 
  useCalendars,
  addLocaleListener,
  addCalendarListener,
  removeSubscription
} from "expo-localization";
import type { 
  Locale, 
  Calendar, 
  CalendarIdentifier, 
  Weekday 
} from "expo-localization";

For CommonJS:

const { 
  getLocales, 
  getCalendars, 
  useLocales, 
  useCalendars,
  addLocaleListener,
  addCalendarListener,
  removeSubscription
} = require("expo-localization");

Basic Usage

import { getLocales, getCalendars, useLocales, useCalendars } from "expo-localization";

// Get current locales (functional API)
const locales = getLocales();
console.log(locales[0].languageTag); // e.g., "en-US"
console.log(locales[0].currencyCode); // e.g., "USD"

// Get current calendars (functional API)  
const calendars = getCalendars();
console.log(calendars[0].calendar); // e.g., "gregory"
console.log(calendars[0].uses24hourClock); // e.g., false

// React hooks for reactive updates
function MyComponent() {
  const locales = useLocales(); // Updates when OS settings change
  const calendars = useCalendars(); // Updates when OS settings change
  
  return (
    <div>
      <p>Language: {locales[0].languageCode}</p>
      <p>Currency: {locales[0].currencyCode}</p>
      <p>Time format: {calendars[0].uses24hourClock ? '24h' : '12h'}</p>
    </div>
  );
}

Architecture

Expo Localization is built around several key components:

  • Functional API: Direct function calls (getLocales, getCalendars) for one-time locale access
  • React Hooks: useLocales and useCalendars hooks that automatically update when device settings change
  • Event System: Manual subscription functions (addLocaleListener, addCalendarListener) for custom reactive updates
  • Platform Abstraction: Unified API across iOS, Android, and Web with platform-specific implementations
  • Type Safety: Comprehensive TypeScript definitions for all locale and calendar properties

Capabilities

Event System

Manual subscription system for listening to locale and calendar changes outside of React components.

/**
 * Adds a listener that is called whenever the user changes their device's locale settings.
 * Returns a subscription object that can be used to remove the listener.
 */
function addLocaleListener(listener: (event?: unknown) => void): EventSubscription;

/**
 * Adds a listener that is called whenever the user changes their device's calendar settings.
 * Returns a subscription object that can be used to remove the listener.
 */
function addCalendarListener(listener: (event?: unknown) => void): EventSubscription;

/**
 * Removes a subscription created by addLocaleListener or addCalendarListener.
 */
function removeSubscription(subscription: EventSubscription): void;

interface EventSubscription {
  remove(): void;
}

Usage Example:

import { 
  addLocaleListener, 
  addCalendarListener, 
  removeSubscription, 
  getLocales, 
  getCalendars 
} from "expo-localization";

// Listen for locale changes
const localeSubscription = addLocaleListener(() => {
  const newLocales = getLocales();
  console.log('Locale changed to:', newLocales[0].languageTag);
});

// Listen for calendar changes
const calendarSubscription = addCalendarListener(() => {
  const newCalendars = getCalendars();
  console.log('Calendar changed to:', newCalendars[0].calendar);
});

// Clean up subscriptions when no longer needed
removeSubscription(localeSubscription);
removeSubscription(calendarSubscription);

// Alternative cleanup using the subscription object directly
localeSubscription.remove();
calendarSubscription.remove();

Locale Information

Access comprehensive user locale information including language, region, currency, and formatting preferences.

/**
 * List of user's locales, returned as an array of objects of type Locale.
 * Guaranteed to contain at least 1 element.
 * These are returned in the order the user defines in their device settings.
 * On the web currency and measurements systems are not provided, instead returned as null.
 */
function getLocales(): Locale[];

/**
 * A hook providing a list of user's locales, returned as an array of objects of type Locale.
 * Guaranteed to contain at least 1 element.
 * If the OS settings change, the hook will rerender with a new list of locales.
 */
function useLocales(): Locale[];

interface Locale {
  /** IETF BCP 47 language tag with region code (e.g., 'en-US', 'es-419', 'pl-PL') */
  languageTag: string;
  /** IETF BCP 47 language tag without region code (e.g., 'en', 'es', 'pl') */
  languageCode: string | null;
  /** ISO 15924 4-letter script code (e.g., 'Latn', 'Hans', 'Hebr') */
  languageScriptCode: string | null;
  /** Region code from device settings (e.g., 'US') */
  regionCode: string | null;
  /** Region code for preferred language (e.g., 'US') */
  languageRegionCode: string | null;
  /** Currency code for locale (e.g., 'USD', 'EUR', 'PLN') - null on Web */
  currencyCode: string | null;
  /** Currency symbol (e.g., '$', '€', 'zł') */
  currencySymbol: string | null;
  /** Currency code for current locale (platform-specific) - null on Web */
  languageCurrencyCode: string | null;
  /** Currency symbol for language currency */
  languageCurrencySymbol: string | null;
  /** Decimal separator for numbers (e.g., '.', ',') */
  decimalSeparator: string | null;
  /** Digit grouping separator for large numbers (e.g., '.', ',') */
  digitGroupingSeparator: string | null;
  /** Text direction for locale */
  textDirection: 'ltr' | 'rtl' | null;
  /** Measurement system used in locale - null on Web */
  measurementSystem: 'metric' | 'us' | 'uk' | null;
  /** Temperature unit based on region */
  temperatureUnit: 'celsius' | 'fahrenheit' | null;
}

Usage Example:

import { getLocales, useLocales } from "expo-localization";

// Functional approach
const currentLocale = getLocales()[0];
console.log(`Language: ${currentLocale.languageCode}`);
console.log(`Region: ${currentLocale.regionCode}`);
console.log(`Currency: ${currentLocale.currencyCode} (${currentLocale.currencySymbol})`);
console.log(`Decimal separator: ${currentLocale.decimalSeparator}`);

// React hook approach (updates automatically)
function LocaleDisplay() {
  const locales = useLocales();
  const primary = locales[0];
  
  return (
    <div>
      <h3>Current Locale: {primary.languageTag}</h3>
      <p>Direction: {primary.textDirection}</p>
      <p>Temperature: {primary.temperatureUnit}</p>
      <p>Measurement: {primary.measurementSystem}</p>
    </div>
  );
}

Calendar Information

Access user's calendar and time formatting preferences including calendar system, time zone, and week settings.

/**
 * List of user's preferred calendars, returned as an array of objects of type Calendar.
 * Guaranteed to contain at least 1 element.
 * For now always returns a single element, but may return preference list on some platforms in future.
 */
function getCalendars(): Calendar[];

/**
 * A hook providing a list of user's preferred calendars, returned as an array of objects of type Calendar.
 * Guaranteed to contain at least 1 element.
 * If the OS settings change, the hook will rerender with a new list of calendars.
 */
function useCalendars(): Calendar[];

interface Calendar {
  /** Calendar identifier (Unicode calendar type) */
  calendar: CalendarIdentifier | null;
  /** True when device uses 24-hour time format */
  uses24hourClock: boolean | null;
  /** First day of week (1=Sunday, 7=Saturday) */
  firstWeekday: Weekday | null;
  /** Time zone identifier (e.g., 'America/Los_Angeles', 'Europe/Warsaw') */
  timeZone: string | null;
}

Usage Example:

import { getCalendars, useCalendars } from "expo-localization";

// Functional approach
const currentCalendar = getCalendars()[0];
console.log(`Calendar type: ${currentCalendar.calendar}`);
console.log(`24-hour clock: ${currentCalendar.uses24hourClock}`);
console.log(`First weekday: ${currentCalendar.firstWeekday}`);
console.log(`Time zone: ${currentCalendar.timeZone}`);

// React hook approach (updates automatically)
function CalendarDisplay() {
  const calendars = useCalendars();
  const primary = calendars[0];
  
  return (
    <div>
      <h3>Calendar Settings</h3>
      <p>System: {primary.calendar}</p>
      <p>Time Format: {primary.uses24hourClock ? '24-hour' : '12-hour'}</p>
      <p>Week starts: {primary.firstWeekday === 1 ? 'Sunday' : 'Monday'}</p>
      <p>Time Zone: {primary.timeZone}</p>
    </div>
  );
}

Types

Event Subscription Interface

interface EventSubscription {
  /** Removes the listener subscription */
  remove(): void;
}

Calendar Identifier Enum

enum CalendarIdentifier {
  /** Thai Buddhist calendar */
  BUDDHIST = 'buddhist',
  /** Traditional Chinese calendar */
  CHINESE = 'chinese',
  /** Coptic calendar */
  COPTIC = 'coptic',
  /** Traditional Korean calendar */
  DANGI = 'dangi',
  /** Ethiopic calendar, Amete Alem (epoch approx. 5493 B.C.E) */
  ETHIOAA = 'ethioaa',
  /** Ethiopic calendar, Amete Mihret (epoch approx, 8 C.E.) */
  ETHIOPIC = 'ethiopic',
  /** Gregorian calendar */
  GREGORY = 'gregory',
  /** Gregorian calendar (alias) */
  GREGORIAN = 'gregory',
  /** Traditional Hebrew calendar */
  HEBREW = 'hebrew',
  /** Indian calendar */
  INDIAN = 'indian',
  /** Islamic calendar */
  ISLAMIC = 'islamic',
  /** Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - civil epoch) */
  ISLAMIC_CIVIL = 'islamic-civil',
  /** Islamic calendar, Saudi Arabia sighting */
  ISLAMIC_RGSA = 'islamic-rgsa',
  /** Islamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - astronomical epoch) */
  ISLAMIC_TBLA = 'islamic-tbla',
  /** Islamic calendar, Umm al-Qura */
  ISLAMIC_UMALQURA = 'islamic-umalqura',
  /** ISO calendar (Gregorian calendar using the ISO 8601 calendar week rules) */
  ISO8601 = 'iso8601',
  /** Japanese imperial calendar */
  JAPANESE = 'japanese',
  /** Persian calendar */
  PERSIAN = 'persian',
  /** Civil (algorithmic) Arabic calendar */
  ROC = 'roc',
}

Weekday Enum

/**
 * An enum mapping days of the week in Gregorian calendar to their index 
 * as returned by the firstWeekday property.
 */
enum Weekday {
  SUNDAY = 1,
  MONDAY = 2,
  TUESDAY = 3,
  WEDNESDAY = 4,
  THURSDAY = 5,
  FRIDAY = 6,
  SATURDAY = 7,
}

Platform-Specific Behavior

Web Platform

  • Currency and measurement system properties return null
  • Text direction may be null on browsers without textInfo API support
  • Clock format and first weekday may be null on browsers without weekInfo API support
  • Uses browser navigator.languages and Intl APIs for locale detection

Native Platform (iOS/Android)

  • Provides full locale data including currency and measurement systems
  • iOS: Currency from Region setting, not current locale
  • Android: Currency specific to locale in list
  • Native module integration via expo-modules-core

Integration with i18n Libraries

Expo Localization works seamlessly with internationalization libraries:

import i18n from 'i18n-js';
import { getLocales } from 'expo-localization';

// Configure i18n-js with device locale
i18n.locale = getLocales()[0].languageCode || 'en';
i18n.translations = {
  en: { welcome: 'Welcome' },
  es: { welcome: 'Bienvenido' },
  fr: { welcome: 'Bienvenue' },
};

// Use in your app
const greeting = i18n.t('welcome');
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/expo-localization@17.0.x
Publish Source
CLI
Badge
tessl/npm-expo-localization badge