npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ngx-multi-lingual

v1.0.2

Published

Zero-pipe auto-translation for Angular — built-in dictionary, IndexedDB cache, shared hosted backend, and AI fallback. No JSON files. No pipes. Just HTML.

Readme

ngx-multi-lingual

Zero-pipe auto-translation for Angular.
Drop it in, add one config line, and every text node in your app translates automatically — no | t pipe, no directive, no per-language JSON files.

npm install ngx-multi-lingual

Why this library exists

Every i18n solution for Angular requires developers to:

  • Wrap every string in a pipe: {{ 'Save' | translate }}
  • Maintain JSON files for each language
  • Remember to mark every new string

ngx-multi-lingual eliminates all three. It scans the live DOM after render, translates everything it finds using a five-tier chain, and reacts to language changes automatically — including full RTL layout switching for Arabic, Urdu, Hebrew, and others.


Quick start

// app.config.ts
import { provideSmartI18n } from 'ngx-multi-lingual';

export const appConfig: ApplicationConfig = {
  providers: [
    provideSmartI18n({
      projectId: 'my-app',
      defaultLang: 'en',
      autoTranslate: true,
    }),
  ],
};
<!-- app.html — plain HTML, no pipes needed -->
<button>Save</button>
<button>Cancel</button>
<h1>Welcome to the ERP System</h1>
<label>Customer Name</label>

Switch language anywhere:

import { LanguageService } from 'ngx-multi-lingual';

@Component({ ... })
export class AppComponent {
  lang = inject(LanguageService);
}
<button (click)="lang.setLanguage('ar')">عربي</button>
<button (click)="lang.setLanguage('fr')">Français</button>

The DOM updates instantly. RTL (dir="rtl") is applied automatically for Arabic and Urdu.


Five-tier translation chain

Every text node passes through these tiers in order — fastest first:

Tier 1 — Static config overrides   (sync, ~0 ms)
          Exact phrase → translation from your provideSmartI18n() config.
          Use for domain-critical wording (e.g. "Invoice" → "Facture client").

Tier 2 — Built-in dictionary       (sync, ~0 ms, offline)
          160+ common ERP / UI terms across 7 languages.
          Save, Cancel, Delete, Customer, Invoice, Total Revenue …

Tier 3 — IndexedDB word cache      (async, ~1 ms)
          Results from previous backend / AI calls stored locally.
          Survives page refresh — no repeat network calls.

Tier 4 — Shared hosted backend     (async, ~50 ms)
          Millions of pre-translated phrases shared across all projects.
          Activated by adding apiKey: 'si18n-...' to your config.

Tier 5 — AI fallback               (async, ~800 ms, once-ever)
          Unknown phrases go to Anthropic or OpenAI exactly once.
          Result stored in IndexedDB + backend — never charged again.

Supported languages

| Code | Language | RTL | |------|-------------|-----| | ar | Arabic | ✓ | | ur | Urdu | ✓ | | fr | French | | | es | Spanish | | | pt | Portuguese | | | hi | Hindi | | | de | German | |

RTL layout (document.documentElement.dir = 'rtl') is applied automatically when switching to ar or ur.


Hosted backend (Tier 4)

Register at https://smart-i18n.io, create a project, and get an API key.
Add one field — that's all:

provideSmartI18n({
  projectId: 'my-app',
  defaultLang: 'en',
  autoTranslate: true,
  apiKey: 'si18n-xxxxxxxxxxxx',   // ← the only change
})
  • Every phrase your AI translates is contributed back to the shared database instantly
  • Every future project that looks up the same phrase gets it free from the database — zero AI cost after the first occurrence globally
  • No apiUrl, no bundle server, no extra config needed

Self-hosted backend

Run the open-source Express.js + MySQL backend on your own infrastructure:

provideSmartI18n({
  backendUrl: 'https://your-server.com/v1',
  apiKey: 'your-key',
  ...
})

AI fallback (Tier 5)

provideSmartI18n({
  projectId: 'my-app',
  defaultLang: 'en',
  autoTranslate: true,
  ai: {
    provider: 'anthropic',
    apiKey: 'sk-ant-YOUR_KEY',
    model: 'claude-haiku-4-5-20251001',   // fast & cheap
  },
})

OpenAI alternative:

ai: {
  provider: 'openai',
  apiKey: 'sk-YOUR_KEY',
  model: 'gpt-4o-mini',
}

Skip auto-translation

Use data-i18n-skip or translate="no" on any element to exclude its subtree:

<!-- Language switcher labels must not be translated -->
<div class="lang-switcher" data-i18n-skip>
  <button (click)="lang.setLanguage('ar')">عربي</button>
  <button (click)="lang.setLanguage('fr')">Français</button>
</div>

<!-- Code samples, terminal output, etc. -->
<code translate="no">npm install ngx-multi-lingual</code>

Or configure selectors globally:

provideSmartI18n({
  skipSelectors: ['.lang-switcher', '[data-i18n-skip]', 'code', 'pre'],
})

Static overrides

Override specific phrases — useful for domain-specific terminology where exact wording matters:

provideSmartI18n({
  staticTranslations: {
    ar: {
      default: {
        'Save': 'حفظ',
        'Welcome to the ERP System': 'مرحباً بك في نظام ERP',
      },
      crm: {
        'Invoice': 'فاتورة مبيعات',   // sales invoice
        'Balance': 'الرصيد المحاسبي',
      },
      finance: {
        'Invoice': 'فاتورة مالية',    // financial invoice — different term
      },
    },
  },
})

The namespace (default, crm, finance) lets you use different translations for the same source word in different contexts.


Translation loading state

@Component({ ... })
export class AppComponent {
  domTranslator = inject(DomTranslatorService);
}
@if (domTranslator.isTranslating()) {
  <div class="loading-bar">Translating…</div>
}

Explicit pipe (optional)

For cases where you need translation in component logic rather than the DOM:

import { TranslatePipe } from 'ngx-multi-lingual';

@Component({
  imports: [TranslatePipe],
  template: `<title>{{ 'Dashboard' | t }}</title>`,
})

With interpolation:

{{ 'Hello {{name}}, you have {{count}} messages' | t:{ params: { name: user.name, count: 5 } } }}

Inline edit mode

Enable live translation editing with Ctrl+Alt+Click:

provideSmartI18n({
  editMode: true,   // enable in dev / staging only
})

Clicking any translated text opens an inline editor for translators to fix strings without a code deploy.


Full config reference

provideSmartI18n({
  // Required
  projectId:    'my-app',        // identifies your project in the backend
  defaultLang:  'en',            // source language of your HTML

  // Auto-translation (zero-pipe mode)
  autoTranslate:  true,
  skipSelectors:  ['.lang-switcher', 'code', 'pre'],
  minTextLength:  2,             // ignore nodes shorter than this

  // Hosted backend (Tier 4)
  apiKey:         'si18n-...',   // from https://smart-i18n.io
  backendUrl:     'https://...',  // only for self-hosted deployments

  // AI fallback (Tier 5)
  ai: {
    provider:   'anthropic',     // 'anthropic' | 'openai' | 'custom'
    apiKey:     'sk-ant-...',
    model:      'claude-haiku-4-5-20251001',
    batchSize:  50,              // texts per AI request
    endpoint:   '...',           // custom endpoint / proxy
  },

  // Static overrides (Tier 1)
  staticTranslations: {
    ar: { default: { 'Save': 'حفظ' } }
  },
  eagerNamespaces: ['default', 'crm', 'finance'],

  // Misc
  editMode:     true,            // Ctrl+Alt+Click inline editor
  cacheTtlMs:   604800000,       // IndexedDB TTL — 7 days default
  fallbackLang: 'en',
})

How DOM auto-translation works

  1. APP_BOOTSTRAP_LISTENER fires after the root component renders
  2. DomTranslatorService.start() walks the DOM with TreeWalker, collecting all text nodes and translatable attributes (placeholder, title, aria-label, alt)
  3. The five-tier chain resolves each phrase; DOM nodes are updated via requestAnimationFrame to avoid layout thrashing
  4. A MutationObserver watches for new nodes (routing, dynamic content) and translates them automatically with a 16 ms debounce

Built-in dictionary — 160+ terms, offline, zero config

Covers:

| Category | Examples | |----------|---------| | Actions | Save, Cancel, Delete, Edit, Add, Search, Export, Import, Reset … | | Navigation | Dashboard, Settings, Profile, Reports, Notifications … | | Auth | Login, Logout, Register, Password, Username, Email … | | Status | Active, Pending, Approved, Rejected, Completed, Paid, Overdue … | | Form fields | Name, Phone, Address, Date, Amount, Price, Quantity, Required … | | ERP core | Customer, Invoice, Order, Payment, Product, Vendor, Employee … | | Finance | Total Revenue, Profit & Loss, Tax, Discount, Fiscal Year, Due Date … |


Requirements

  • Angular 17+
  • Modern browser with IndexedDB support

License

MIT © Bilal Raza