Skip to content

Intl-first i18n for modern JavaScript & TypeScript apps. Zero-dependency, type-safe translations with dynamic loading, smart plurals, and fast date/number/currency formatting via the platform's built-in Intl APIs. Works seamlessly with Vue, React, and any other JS framework β€” or no framework at all.

License

Notifications You must be signed in to change notification settings

RondaYummy/swift-i18n

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

14 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

swift-i18n

Blazing-fast, dependency-free i18n library for Vue 3, React and modern JS/TS apps. Uses native Intl APIs and modern features for blazing performance, dynamic locale loading, caching, and type-safe keys.

Ask DeepWiki FOSSA Status FOSSA Status


Why choose swift-i18n?

  • Higher speed β€” no unnecessary dependencies, works on pure Intl API.
  • Minimal size β€” lightweight and compact code. -** TypeScript support** β€” type-safe translation keys and autocomplete.
  • Dynamic loading and caching β€” convenient for working with large projects.
  • Easy integration β€” React plugin and Vue 3 plugin with provide/inject and hooks
  • Full support β€” For plural and formatting β€” numbers, dates, currencies, units.

Features

  • Native Intl APIs: Intl.NumberFormat, Intl.DateTimeFormat, Intl.PluralRules, Intl.RelativeTimeFormat
  • Language detection (localStorage, cookie, browser language)
  • Dynamic locale loading via ESM dynamic import
  • Local caching of translation bundles in localStorage (7-day TTL)
  • Vue 3 plugin with provide/inject and global $t function
  • TypeScript-friendly with type-safe translation keys and autocompletion

Get Started

1. Installation

npm install swift-i18n

2. Create locale files

Create a locales folder in your src directory:

src/
 β”œβ”€ locales/
 β”‚   β”œβ”€ en.json
 β”‚   └─ ua.json

Example en.json:

{
  "common": {
    "hello": "Hello!",
    "items_one": "{count} item",
    "items_other": "{count} items"
  },
  "home": {
    "title": "Welcome",
    "description": "This is the home page"
  }
}

3. Create locale-loader.ts


Vue 3 Integration with Vite

// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import { createVueI18n } from 'swift-i18n/vue-plugin';
import { SwiftI18n } from 'swift-i18n';
import { loadLocale } from './locale-loader.ts';

const app = createApp(App);

const i18n = new SwiftI18n({
  defaultLang: 'en',
  supportedLangs: ['en', 'uk'],
  loader: loadLocale,
  cacheTtlMs:  1000 * 60 * 60 * 24 * 7, // 7 days
});

app.use(createVueI18n(i18n));

app.mount('#app');

Usage in components (<script setup>)

<script setup lang="ts">
import { useI18n } from 'swift-i18n/vue-plugin';

const { t, plural, changeLanguage, lang } = useI18n();
</script>

<template>
  <h1>Current language: {{ lang }}</h1>

  <div>{{ t('common.hello') }}</div>
  <div>{{ plural('common.items', 5) }}</div>

  <button @click="changeLanguage('uk')">UK</button>
  <button @click="changeLanguage('en')">EN</button>
</template>

React Integration

import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import './index.css';
import { loadLocale } from './locale-loader.ts';
import { SwiftI18n } from 'swift-i18n';
import { createReactI18n } from 'swift-i18n/react-plugin';

const i18n = new SwiftI18n({
  defaultLang: 'en',
  supportedLangs: ['en', 'uk'],
  loader: loadLocale,
  cacheTtlMs:  1000 * 60 * 60 * 24 * 7, // 7 days
});

const I18nProvider = createReactI18n(i18n);

createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <I18nProvider>
      <App />
    </I18nProvider>
  </React.StrictMode>
);
import React from 'react';
import { useI18n } from 'swift-i18n/react-plugin';

export default function App() {
  const { i18n, lang } = useI18n();
  return (
    <>
      <div>{i18n.t('common.hello')}</div>
      <div>{i18n.plural('common.items', 3)}</div>
      <button onClick={() => i18n.changeLanguage('uk')}>πŸ‡ΊπŸ‡¦</button>
      <button onClick={() => i18n.changeLanguage('en')}>πŸ‡¬πŸ‡§</button>
      <p>Current lang: {lang}</p>
    </>
  );
}

Example locale-loader.ts for Vite

import type { LocaleBundle } from 'swift-i18n';
const localeModules = import.meta.glob('./locales/*.json');

export async function loadLocale(lang: string = 'en') {
  const importer = localeModules[`./locales/${lang}.json`];
  if (!importer) {
    throw new Error(`Locale ${lang} not found`);
  }
  const module = await importer();
  return (module as { default: LocaleBundle; }).default;
}

Format helpers

import { formatCurrency, formatDate, formatRelativeTime, formatNumber, formatUnit } from 'swift-i18n';

formatNumber(1234567.89, 'en-US'); // "1,234,567.89"
formatCurrency(1234.5, 'USD', 'en-US'); // "$1,234.50"
formatUnit(10, 'kilometer-per-hour', 'en-US'); // "10 km/h"
formatDate(new Date(), 'en-US'); // "8/11/2025"
formatRelativeTime(-2, 'day', 'en-US'); // "2 days ago"

Core Features

Pluralization

The plural(baseKey: string, count: number, vars?: Record<string, any>) method returns the correct plural form translation:

Example JSON structure:

{
  "common": {
    "items_one": "{count} item",
    "items_few": "{count} items",
    "items_many": "{count} items",
    "items_other": "{count} items"
  }
}

Usage:

plural('common.items', 1); // "1 item"
plural('common.items', 3); // "3 items"

Variable Interpolation

Pass variables into translations via the vars object:

{
  "greeting": "Hello, {name}!"
}
t('greeting', { name: 'Alice' }); // "Hello, Alice!"
plural('common.items', 5, { name: 'Alice' });

Dynamic loading & caching

  • Translations are dynamically loaded via ESM import()
  • Cached in localStorage for 7 days ( default )
  • Automatic loading when calling changeLanguage().

Advanced Usage

Type-safe Translations

Add type definitions for autocompletion:

  1. Create src/types/swift-i18n.d.ts:
import 'swift-i18n';
declare module 'swift-i18n' {
  // Merge interface β€” put YOUR key scheme here
  interface Translations {
    common: {
      hello: string;
      items_one: string;
      items_other: string;
    };
    home: {
      title: string;
      description: string;
    };
  }
}
  1. Add to tsconfig.json:
{
  "include": [
    "src/types/**/*"
  ]
}

Contribution

Welcome to contribute to swift-i18n!

  • Fork the repository.
  • Create a branch with new features or fixes.
  • Write tests for new features.
  • Send a pull request with a detailed description.
  • Sign commits according to Conventional Commits.

Contact me if you need help or ideas.

About

Intl-first i18n for modern JavaScript & TypeScript apps. Zero-dependency, type-safe translations with dynamic loading, smart plurals, and fast date/number/currency formatting via the platform's built-in Intl APIs. Works seamlessly with Vue, React, and any other JS framework β€” or no framework at all.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •