Lightweight internationalization with pluralization and lazy loading
Find a file
Ersin KOÇ d9ec6ee7b1 init
2026-01-15 10:56:26 +02:00
examples init 2026-01-15 10:56:26 +02:00
src init 2026-01-15 10:56:26 +02:00
.gitignore init 2026-01-15 10:56:26 +02:00
CHANGELOG.md init 2026-01-15 10:56:26 +02:00
i18nkit-claude-code-prompt.md init 2026-01-15 10:56:26 +02:00
IMPLEMENTATION.md init 2026-01-15 10:56:26 +02:00
LICENSE init 2026-01-15 10:56:26 +02:00
package.json init 2026-01-15 10:56:26 +02:00
README.md init 2026-01-15 10:56:26 +02:00
SPECIFICATION.md init 2026-01-15 10:56:26 +02:00
TASKS.md init 2026-01-15 10:56:26 +02:00
tsconfig.json init 2026-01-15 10:56:26 +02:00
tsup.config.ts init 2026-01-15 10:56:26 +02:00
vitest.config.ts init 2026-01-15 10:56:26 +02:00

i18nKit

Lightweight internationalization with pluralization and lazy loading

npm version bundle size license

DocumentationGetting StartedExamples


Features

  • 🌍 Translation - Simple t() function with dot-notation keys
  • 📝 Interpolation - Variable substitution with nested object support
  • 🔢 Pluralization - CLDR plural rules for 25+ languages
  • 📂 Namespaces - Organize translations into modules
  • Lazy Loading - Load translations on demand
  • 🔍 Auto Detection - Detect user locale from browser/URL/cookie
  • 🔄 Fallbacks - Graceful degradation with fallback chains
  • 💰 Currency - Locale-aware currency formatting
  • 📅 Dates - Multiple date/time formats
  • ⏱️ Relative Time - "2 hours ago", "yesterday"
  • 📋 Lists - "A, B, and C" with locale-aware conjunctions
  • ⚛️ React - Hooks & components included
  • 📦 Zero Dependencies - No runtime dependencies
  • < 3KB - Tiny bundle size (core library)

Installation

npm install @oxog/i18nkit

Quick Start

import { createI18n } from '@oxog/i18nkit'

const i18n = createI18n({
  locale: 'en',
  messages: {
    en: {
      greeting: 'Hello!',
      welcome: 'Welcome, {name}!',
      items: {
        one: 'One item',
        other: '{count} items',
      },
    },
    tr: {
      greeting: 'Merhaba!',
      welcome: 'Hoş geldin, {name}!',
      items: {
        one: 'Bir öğe',
        other: '{count} öğe',
      },
    },
  },
})

// Basic translation
i18n.t('greeting') // 'Hello!'

// With interpolation
i18n.t('welcome', { name: 'John' }) // 'Welcome, John!'

// Pluralization (auto-detected from count)
i18n.t('items', { count: 1 }) // 'One item'
i18n.t('items', { count: 5 }) // '5 items'

// Change locale
await i18n.setLocale('tr')
i18n.t('greeting') // 'Merhaba!'

React Integration

import { createI18n } from '@oxog/i18nkit'
import { I18nProvider, useTranslation } from '@oxog/i18nkit/react'

const i18n = createI18n({
  locale: 'en',
  messages: {
    en: {
      greeting: 'Hello!',
      welcome: 'Welcome, {name}!',
    },
  },
})

function App() {
  return (
    <I18nProvider i18n={i18n}>
      <Greeting />
    </I18nProvider>
  )
}

function Greeting() {
  const { t, locale, setLocale } = useTranslation()

  return (
    <div>
      <h1>{t('greeting')}</h1>
      <p>{t('welcome', { name: 'John' })}</p>
      <button onClick={() => setLocale('tr')}>Türkçe</button>
    </div>
  )
}

Key Features

Pluralization

Full CLDR plural rule support for 25+ languages:

const i18n = createI18n({
  locale: 'en',
  messages: {
    en: {
      apples: {
        zero: 'No apples',
        one: 'One apple',
        other: '{count} apples',
      },
      // Pipe notation shorthand
      messages: 'No messages | One message | {count} messages',
    },
    // Russian (4 forms)
    ru: {
      items: {
        one: '{count} элемент',
        few: '{count} элемента',
        many: '{count} элементов',
        other: '{count} элементов',
      },
    },
    // Arabic (6 forms)
    ar: {
      books: {
        zero: 'لا كتب',
        one: 'كتاب واحد',
        two: 'كتابان',
        few: '{count} كتب',
        many: '{count} كتابًا',
        other: '{count} كتاب',
      },
    },
  },
})

i18n.plural('apples', 0) // 'No apples'
i18n.plural('apples', 1) // 'One apple'
i18n.plural('apples', 5) // '5 apples'

Formatting

// Numbers
i18n.formatNumber(1234567.89) // '1,234,567.89'

// Currency
i18n.formatCurrency(99.99, 'USD') // '$99.99'
i18n.formatCurrency(99.99, 'EUR') // '€99.99'

// Dates
i18n.formatDate(new Date()) // 'December 30, 2025'
i18n.formatTime(new Date()) // '2:30 PM'

// Relative time
i18n.formatRelativeTime(-1, 'day') // 'yesterday'
i18n.formatRelativeTime(2, 'hour') // 'in 2 hours'

// Auto unit selection
i18n.formatRelativeTimeAuto(pastDate) // '3 days ago'

// Lists
i18n.formatList(['Apple', 'Banana', 'Orange']) // 'Apple, Banana, and Orange'

Lazy Loading

const i18n = createI18n({
  locale: 'en',
  loadMessages: async (locale, namespace) => {
    const response = await fetch(`/locales/${locale}/${namespace}.json`)
    return response.json()
  },
})

// Load namespace on demand
await i18n.loadNamespace('dashboard')

Auto Detection

const i18n = createI18n({
  locale: 'en', // fallback
  detection: {
    order: ['querystring', 'cookie', 'localStorage', 'navigator'],
    supportedLocales: ['en', 'tr', 'de', 'fr'],
    cacheLocale: true,
  },
})

React Components

import {
  T,
  Trans,
  Plural,
  FormatNumber,
  FormatCurrency,
  FormatDate,
  FormatRelativeTime,
} from '@oxog/i18nkit/react'

// Simple translation
<T k="greeting" />
<T k="welcome" name="John" />

// Rich text with JSX
<Trans
  i18nKey="terms"
  components={{
    link: <a href="/terms" />,
    bold: <strong />,
  }}
/>

// Pluralization
<Plural i18nKey="items" count={5} />

// Formatting
<FormatNumber value={1234.56} />
<FormatCurrency value={99.99} currency="USD" />
<FormatDate value={new Date()} />
<FormatRelativeTime value={pastDate} auto />

Supported Plural Rules

Built-in CLDR plural rules for:

  • English (en) - 2 forms
  • Turkish (tr) - 2 forms
  • German (de) - 2 forms
  • French (fr) - 2 forms
  • Spanish (es) - 2 forms
  • Russian (ru) - 4 forms
  • Polish (pl) - 4 forms
  • Czech (cs) - 4 forms
  • Arabic (ar) - 6 forms (most complex)
  • Welsh (cy) - 6 forms
  • Irish (ga) - 5 forms
  • Hebrew (he) - 4 forms
  • Japanese (ja) - 1 form
  • Korean (ko) - 1 form
  • Chinese (zh) - 1 form
  • And 10+ more languages

Bundle Size

  • Core: < 3KB minified + gzipped
  • With React: < 5KB minified + gzipped
  • Tree-shakeable exports

Browser Support

  • Modern browsers with ES2020+ support
  • Node.js 14+
  • Requires Intl API (available in all modern browsers)

Documentation

Visit i18nkit.oxog.dev for full documentation:

License

MIT © Ersin KOÇ