Skip to content
/ nimbus Public

A 100% type-safe internationalization library for TypeScript with zero runtime overhead. ✨

License

lealtt/nimbus

Repository files navigation

Nimbus 🌐

A 100% type-safe internationalization library for TypeScript with zero runtime overhead.

✨ Features

  • 🔒 Fully Type-Safe: Autocomplete for keys AND parameters.
  • Zero Runtime Cost: All type checking at compile time.
  • 🎯 Parameter Types: Define types directly in templates: {{name:string}}, {{count:number}}.
  • 🪶 Lightweight: No dependencies (~2KB minified).
  • 🎨 Simple API: Just t() and done.

📚 Table of Contents

Installation

npm install @lealt/nimbus

Quick Start

import { createNimbus } from "@lealt/nimbus";

// Define your translations
const translations = {
  "en-US": {
    welcome: "Welcome!",
    greeting: "Hello, {{name:string}}!",
    stats: "You have {{count:number}} items",
  },
  "pt-BR": {
    welcome: "Bem-vindo!",
    greeting: "Olá, {{name:string}}!",
    stats: "Você tem {{count:number}} itens",
  },
} as const; // ⚠️ Don't forget 'as const'

// Create instance
const nimbus = createNimbus(translations, {
  defaultLocale: "en-US",
});

// Use it!
nimbus.t("welcome"); // "Welcome!"
nimbus.t("greeting", { name: "John" }); // "Hello, John!"
nimbus.t("stats", { count: 42 }); // "You have 42 items"

// Change locale
nimbus.setLocale("pt-BR");
nimbus.t("greeting", { name: "João" }); // "Olá, João!"

Core Concepts

Type-Safe Parameters

Define parameter types directly in your translation strings. Nimbus will enforce them at compile time.

const translations = {
  "en-US": {
    // String parameters
    user: "Welcome, {{username:string}}!",
    // Number parameters
    score: "Your score: {{points:number}}",
    // Multiple parameters
    info: "{{name:string}} has {{count:number}} items.",
  },
} as const;

const nimbus = createNimbus(translations);

// TypeScript enforces correct types!
nimbus.t("user", { username: "alice" }); // ✅
nimbus.t("score", { points: 100 }); // ✅

// These will show errors in your IDE:
nimbus.t("user"); // ❌ Error: missing params
nimbus.t("user", { wrong: "param" }); // ❌ Error: wrong param name

Nested Translations

Organize your translations hierarchically and access them with dot notation.

const translations = {
  "en-US": {
    auth: {
      login: {
        title: "Login",
        welcome: "Welcome back, {{username:string}}!",
      },
      register: {
        title: "Register",
      },
    },
  },
} as const;

const nimbus = createNimbus(translations);

// Access nested keys
nimbus.t("auth.login.title"); // "Login"
nimbus.t("auth.login.welcome", { username: "john" }); // "Welcome back, john!"

Essential API

These are the core functions you'll use most often.

createNimbus(locales, config?)

Creates a new Nimbus instance.

const nimbus = createNimbus(translations, {
  defaultLocale: "en-US", // Optional: first locale if not specified
});

t(key, params?)

Translates a key with type-safe parameters.

nimbus.t("simple.key"); // No params
nimbus.t("with.param", { name: "value" }); // With params

setLocale(locale)

Changes the current locale.

nimbus.setLocale("pt-BR");

Explore More Features (Examples)

This library includes many other powerful features. The best way to learn about them is to see them in action.

Check out the examples/ folder to see fully functional code for:

  • Pluralization: Handling one vs. other rules.
  • Custom Formatters: Formatting {{date:date}} or {{amount:currency}}.
  • Event Listeners: Reacting to locale changes or missing keys.
  • Lazy Loading: Using importx() to load locales on demand.
  • Fallback Locales: Automatically using a default locale for missing keys.
  • Adapters: Syncing locale with an external source.
  • Utility Functions: Using getSchema(), hasKey(), tLocale(), and more.

Best Practices

1. Always use as const

This is required for proper type inference:

// ❌ Bad - loses type information
const translations = { "en-US": { key: "value" } };

// ✅ Good - preserves literal types
const translations = { "en-US": { key: "value" } } as const;

2. Keep translations in separate files

// locales/en-US.ts
export const enUS = {
  auth: { login: "Login" },
} as const;

// i18n.ts
import { enUS } from "./locales/en-US";
/* ... */
export const nimbus = createNimbus({
  "en-US": enUS,
  /* ... */
});

3. Use TypeScript strict mode

Enable strict mode in tsconfig.json for maximum type safety:

{
  "compilerOptions": {
    "strict": true
  }
}

Supported Parameter Types

  • {{name:string}} - String values
  • {{count:number}} - Numeric values
  • {{active:boolean}} - Boolean values
  • {{timestamp:date}} - Date values (requires a date formatter)
  • {{amount:currency}} - Number values (requires a currency formatter)
  • {{value:bigint}} - BigInt values (requires a bigint formatter)
  • {{misc:any}} - Any other value

License

MIT


Made with ❤️ for type-safe i18n

About

A 100% type-safe internationalization library for TypeScript with zero runtime overhead. ✨

Topics

Resources

License

Stars

Watchers

Forks