mirror of
https://github.com/ersinkoc/i18nKit.git
synced 2026-04-27 06:25:58 +03:00
Lightweight internationalization with pluralization and lazy loading
| examples | ||
| src | ||
| .gitignore | ||
| CHANGELOG.md | ||
| i18nkit-claude-code-prompt.md | ||
| IMPLEMENTATION.md | ||
| LICENSE | ||
| package.json | ||
| README.md | ||
| SPECIFICATION.md | ||
| TASKS.md | ||
| tsconfig.json | ||
| tsup.config.ts | ||
| vitest.config.ts | ||
i18nKit
Lightweight internationalization with pluralization and lazy loading
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Ç