JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 283
  • Score
    100M100P100Q95180F
  • License MIT

Framework-agnostic core utilities for Better i18n

Package Exports

  • @better-i18n/core
  • @better-i18n/core/package.json
  • @better-i18n/core/react

Readme

@better-i18n/core

Framework-agnostic core utilities for fetching translations from Better i18n CDN.

Features

  • Framework Agnostic - Works with any JavaScript runtime
  • Edge-Ready - Optimized for edge environments (Cloudflare, Vercel, etc.)
  • Type-Safe - Full TypeScript support
  • Cached - Built-in manifest caching with configurable TTL
  • Offline Fallback - 5-layer fallback chain: TtlCache → CDN (with ETag 304) → persistent storage → static data
  • Resilient - Configurable fetch timeout and retry with exponential backoff

Installation

npm install @better-i18n/core
# or
bun add @better-i18n/core

Usage

import { createI18nCore } from "@better-i18n/core";

const i18n = createI18nCore({
  project: "your-org/your-project",
  defaultLocale: "en",
});

// Fetch messages for a locale
const messages = await i18n.getMessages("en");

// Get available locales
const locales = await i18n.getLocales();
// ["en", "tr", "de", ...]

// Get language options with metadata (for UI)
const languages = await i18n.getLanguages();
// [{ code: "en", name: "English", nativeName: "English", flagUrl: "..." }, ...]

// Get manifest
const manifest = await i18n.getManifest();

Configuration

interface I18nCoreConfig {
  // Required
  project: string;        // "org/project" format
  defaultLocale: string;  // e.g., "en"

  // Optional
  cdnBaseUrl?: string;           // default: "https://cdn.better-i18n.com"
  manifestCacheTtlMs?: number;   // default: 300000 (5 minutes)
  debug?: boolean;               // default: false
  logLevel?: LogLevel;           // default: "warn"
  fetch?: typeof fetch;          // custom fetch function

  // Fallback & Resilience
  storage?: TranslationStorage;  // persistent cache (localStorage, AsyncStorage, etc.)
  staticData?: Record<string, Messages> | (() => Promise<Record<string, Messages>>);
  fetchTimeout?: number;         // default: 10000 (10s) — abort if CDN doesn't respond
  retryCount?: number;           // default: 1 — retry attempts on CDN failure
}

Offline Fallback

Translations are resolved through a 5-layer fallback chain:

TtlCache (in-memory) → CDN fetch → CDN 304 (ETag) → Storage (persistent cache) → Static Data (bundled) → throw
  1. TtlCache — In-memory cache with configurable TTL (default: 5 minutes). Instant, no I/O.
  2. CDN fetch — Fresh translation data from Better i18n CDN.
  3. CDN 304 (ETag) — If CDN returns "not modified", reuse cached version.
  4. Storage — Persistent cache (localStorage, AsyncStorage, etc.) survives app restarts.
  5. Static Data — Bundled translations as absolute last resort.

Storage Adapter

Persist translations locally so they survive CDN outages and app restarts:

import { createI18nCore, createLocalStorage } from "@better-i18n/core";

const i18n = createI18nCore({
  project: "your-org/your-project",
  defaultLocale: "en",
  storage: createLocalStorage(), // browser localStorage
});

Built-in adapters:

Adapter Environment Import
createLocalStorage() Browser @better-i18n/core
createMemoryStorage() Any (non-persistent) @better-i18n/core
createAutoStorage() Auto-detect (localStorage or memory) @better-i18n/core

You can also provide any object implementing { get, set, remove? } for custom stores (e.g., AsyncStorage, MMKV).

Static Data

Bundle translations as a last-resort fallback:

const i18n = createI18nCore({
  project: "your-org/your-project",
  defaultLocale: "en",
  // Static import
  staticData: {
    en: { common: { hello: "Hello" } },
    tr: { common: { hello: "Merhaba" } },
  },
  // Or lazy import (code-split)
  // staticData: () => import('./fallback-translations.json'),
});

Framework Integrations

This package is the foundation for all Better i18n SDKs:

Package Framework Built On
@better-i18n/next Next.js next-intl
@better-i18n/use-intl React, Vite, TanStack Start use-intl
@better-i18n/expo Expo / React Native i18next

If you're using one of these frameworks, install the framework SDK instead — @better-i18n/core is included automatically as a dependency.

Documentation

Full documentation available at docs.better-i18n.com/core

License

MIT © Better i18n