IntlPull
Guide
14 min read

Browser Intl API vs Translation Management: When to Use Each (2026 Guide)

Should you use the native JavaScript Intl API or a translation management system? Learn when browser-native internationalization is enough and when you need a full TMS.

IntlPull Team
IntlPull Team
03 Feb 2026, 11:44 AM [PST]
On this page
Summary

Should you use the native JavaScript Intl API or a translation management system? Learn when browser-native internationalization is enough and when you need a full TMS.

The Question Every Developer Asks

You're adding internationalization to your app. Your first Google search lands you on MDN's Intl API documentation. It looks promising: date formatting, number formatting, even relative time formatting, all built into the browser.

Why would you need anything else?

Here's the thing: the Intl API is fantastic for formatting, but internationalization isn't just formatting. It's content management, translation workflows, context for translators, version control, and automation.

This guide breaks down exactly what the browser can (and can't) do, and when you actually need a translation management system.

What the Browser Intl API Actually Does

The JavaScript Intl object provides locale-aware formatting. That's it. Not translations, not content management: formatting.

Intl API Capabilities

Number Formatting:

JavaScript
1// US format
2new Intl.NumberFormat('en-US').format(1234567.89);
3// "1,234,567.89"
4
5// German format
6new Intl.NumberFormat('de-DE').format(1234567.89);
7// "1.234.567,89"
8
9// Currency
10new Intl.NumberFormat('ja-JP', {
11  style: 'currency',
12  currency: 'JPY'
13}).format(99000);
14// "¥99,000"

Date/Time Formatting:

JavaScript
1const date = new Date('2026-01-15');
2
3// US format
4new Intl.DateTimeFormat('en-US').format(date);
5// "1/15/2026"
6
7// UK format
8new Intl.DateTimeFormat('en-GB').format(date);
9// "15/01/2026"
10
11// Long format with time
12new Intl.DateTimeFormat('fr-FR', {
13  dateStyle: 'full',
14  timeStyle: 'short'
15}).format(date);
16// "mercredi 15 janvier 2026 à 00:00"

Relative Time Formatting:

JavaScript
1const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
2
3rtf.format(-1, 'day');   // "yesterday"
4rtf.format(2, 'week');   // "in 2 weeks"
5rtf.format(-3, 'month'); // "3 months ago"

Pluralization Rules:

JavaScript
1const rules = new Intl.PluralRules('en-US');
2rules.select(0);  // "other"
3rules.select(1);  // "one"
4rules.select(2);  // "other"
5
6const rulesArabic = new Intl.PluralRules('ar-EG');
7rulesArabic.select(0);  // "zero"
8rulesArabic.select(1);  // "one"
9rulesArabic.select(2);  // "two"
10rulesArabic.select(5);  // "few"
11rulesArabic.select(11); // "many"

List Formatting:

JavaScript
1const list = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
2list.format(['apples', 'oranges', 'bananas']);
3// "apples, oranges, and bananas"
4
5const listFr = new Intl.ListFormat('fr', { style: 'long', type: 'conjunction' });
6listFr.format(['pommes', 'oranges', 'bananes']);
7// "pommes, oranges et bananes"

That's powerful stuff. So what's missing?

What the Intl API Can't Do

Here's where developers get stuck. The Intl API doesn't handle:

1. Translation Content

The Intl API doesn't store or manage translated strings. You still need:

JavaScript
1// ❌ This doesn't exist
2const t = Intl.translate('welcome.title', 'fr');
3
4// ✅ You build this yourself
5const translations = {
6  en: { "welcome.title": "Welcome" },
7  fr: { "welcome.title": "Bienvenue" },
8  es: { "welcome.title": "Bienvenido" }
9};

You're responsible for:

  • Loading translation files
  • Organizing key structure
  • Managing fallbacks
  • Detecting user locale
  • Switching languages dynamically

2. Complex Message Formatting

The Intl API can't handle variables in translations:

JavaScript
1// What you need
2"Hello {name}, you have {count} new messages"
3
4// What Intl.MessageFormat can do (newer API)
5const msg = new Intl.MessageFormat(
6  "Hello {name}, you have {count, plural, one {# message} other {# messages}}",
7  "en"
8);
9msg.format({ name: "Sarah", count: 3 });
10// "Hello Sarah, you have 3 messages"

But Intl.MessageFormat is:

  • Still in Stage 1 proposal (not standardized)
  • Only available in Chrome 117+ with a flag
  • Not production-ready as of 2026

Most developers use ICU Message Format via libraries like @formatjs/intl or messageformat.

3. Translation Workflow

Zero support for:

  • Sending strings to translators
  • Tracking translation status
  • Managing review cycles
  • Version control for translations
  • Collaboration between developers and linguists

4. Context for Translators

Translators need to see:

  • Where the text appears in the UI
  • Character limits
  • Screenshots
  • Usage notes

The Intl API has no concept of this.

5. Automation

No built-in support for:

  • Extracting strings from code
  • Auto-detecting missing translations
  • CI/CD integration
  • Pushing updates over-the-air

The Hybrid Approach: Best of Both Worlds

Most production apps use the Intl API for formatting and a library/TMS for translation management.

Example: React App with next-intl

TSX
1import { useTranslations } from 'next-intl';
2import { useFormatter } from 'next-intl';
3
4function ProductCard({ product }) {
5  const t = useTranslations('products');
6  const format = useFormatter();
7
8  return (
9    <div>
10      {/* Translation from TMS/files */}
11      <h2>{t('title', { name: product.name })}</h2>
12
13      {/* Formatting from Intl API */}
14      <p>{format.number(product.price, { style: 'currency', currency: 'USD' })}</p>
15      <time>{format.dateTime(product.releaseDate, { dateStyle: 'medium' })}</time>
16    </div>
17  );
18}

The library (next-intl) handles:

  • Loading translation files
  • Managing the current locale
  • Providing t() function
  • Fallback logic

The Intl API (via format) handles:

  • Number formatting
  • Date formatting
  • Currency symbols
  • Locale-specific conventions

When Browser-Native is Enough

Use just the Intl API when:

1. Simple Formatting Needs

You only need dates, numbers, currencies formatted correctly:

JavaScript
1// A dashboard showing metrics
2const dashboard = {
3  users: Intl.NumberFormat(locale).format(1543298),
4  revenue: Intl.NumberFormat(locale, { style: 'currency', currency }).format(42000),
5  lastUpdated: Intl.DateTimeFormat(locale, { dateStyle: 'medium' }).format(new Date())
6};

2. No User-Facing Text

Your app has minimal UI text (e.g., a data visualization tool, internal admin panel).

3. Single Market Focus

You're building for one region and just want proper number/date formatting.

4. Learning/Prototyping

You're building a demo or learning internationalization concepts.

When You Need a Translation Management System

Use a TMS (like IntlPull, Lokalise, or Phrase) when:

1. Multiple Languages

You're targeting 3+ languages. Managing translation files manually becomes painful fast.

Pain points without TMS:

  • Translators editing JSON/YAML files directly (breaks syntax)
  • No visibility into what's translated vs missing
  • No way to track "who translated what when"
  • Merge conflicts in Git when multiple translators work
  • No review workflow

With TMS:

  • Web UI for translators (no code access needed)
  • Automatic tracking of translation status
  • Built-in review/approval workflow
  • No merge conflicts (TMS handles sync)

2. Frequent Content Updates

You're adding features weekly. New strings appear constantly.

Manual workflow:

  • Developer adds English strings
  • Export strings to spreadsheet
  • Email translators
  • Wait for response
  • Copy-paste back into JSON
  • Deploy

TMS workflow:

  • Developer pushes code with new strings
  • TMS auto-detects missing translations
  • Translators get notified
  • Translations auto-sync back to code
  • Deploy

IntlPull's CLI does this in one command:

Terminal
1npx @intlpullhq/cli upload
2# Extracts new strings, uploads to platform
3# Translators see them immediately
4
5npx @intlpullhq/cli download
6# Downloads latest translations

3. Non-Technical Translators

Your translators aren't developers. They can't work with JSON files or Git.

What translators need:

  • Visual context (where does this text appear?)
  • Character limits
  • Usage notes ("This appears on buttons, keep it short")
  • Ability to see placeholders: {name}, {count}
  • Preview of their translations in the actual UI

TMSs provide translator-friendly interfaces. IntlPull shows live previews so translators see their changes in context.

4. Machine Translation + Human Review

You want to use AI for initial translations but have humans review.

Typical workflow:

  • Auto-translate with ChatGPT/DeepL for all strings
  • Humans review and fix errors
  • Track what's been reviewed vs auto-generated

TMSs integrate with MT engines and track translation source (human vs machine).

5. Over-the-Air Updates

You want to update translations without redeploying your app.

Use case: You launch in Spanish, but users report a translation error. Without OTA:

  • Fix translation in code
  • Commit to Git
  • CI/CD build
  • Deploy to production
  • Users get update (maybe days later)

With OTA (IntlPull's approach):

  • Fix translation in web UI
  • Click "Publish"
  • Apps fetch new translations instantly
  • No deployment needed

This is critical for mobile apps where app store review takes days.

6. Collaboration at Scale

Multiple people working on translations:

  • Developers adding source content
  • Translators translating
  • Reviewers approving
  • Marketing editing copy

Without a TMS, this is chaos. Everyone's overwriting each other in Git.

Decision Framework

ScenarioSolutionWhy
Internal tool, 1 language, date/number formattingIntl API onlySimple, no translation management needed
Marketing site, 3-5 languages, static contentIntl API + JSON filesTranslation files are manageable without TMS
SaaS product, 10+ languages, frequent updatesIntl API + TMSNeed workflow automation, collaboration, OTA
Mobile app, 5+ languages, app store delaysIntl API + TMS with OTACan't wait for app store approval for translation fixes
E-commerce, 20+ languages, product descriptionsIntl API + TMSHigh volume of content, need MT + human review

Common Misconceptions

"I can build my own TMS"

You can, but it'll take 6+ months to match what existing TMSs do.

What you'll build:

  • Web UI for translators
  • String extraction script
  • Sync logic (code ↔ platform)
  • Access control (who can edit what)
  • Translation memory
  • Search/filtering
  • Version history
  • API
  • CLI

That's a product, not a weekend project. Unless translation management is your core competency, use an existing solution.

"TMSs are expensive"

Some are (Lokalise, Phrase charge $500+/month).

But indie-friendly options exist:

  • IntlPull: Free tier, $29/month for small teams, OTA updates included
  • Tolgee: Open-source option
  • Crowdin: Free for open-source projects

"TMSs lock you in"

Most support standard formats (JSON, YAML, XLIFF). You can export and migrate.

IntlPull stores translations in your Git repo by default. You own your data.

The IntlPull Approach

IntlPull combines the best of both:

Uses Intl API for formatting:

JavaScript
1// IntlPull SDKs wrap Intl API for formatting
2const { t, format } = useIntlPull();
3
4// Translation management
5t('welcome.title');
6
7// Formatting via Intl API
8format.number(1234.56, { style: 'currency', currency: 'USD' });

Adds what's missing:

  • CLI for syncing translations: npx @intlpullhq/cli sync --watch
  • Web UI for translators (visual context, screenshots)
  • Git integration (bi-directional sync)
  • OTA updates (instant translation pushes)
  • Built-in machine translation (ChatGPT, DeepL)
  • Translation memory (reuse past translations)

Developer experience:

Terminal
1# Day 1: Setup
2npx @intlpullhq/cli init
3
4# Daily workflow
5npx @intlpullhq/cli upload  # Upload new strings
6npx @intlpullhq/cli download  # Download translations
7
8# Deploy
9npm run build  # Translations bundled automatically

Translators work in the web UI. Developers never leave their terminal.

Migration Path

If you're currently using just the Intl API and JSON files, here's how to add a TMS:

Step 1: Audit Current Setup

Terminal
1# Count your translation files
2find . -name "*.json" -path "*/locales/*" | wc -l
3
4# Count your translation keys
5cat locales/en.json | jq 'keys | length'

If you have <100 keys and 1-2 languages, you might be fine without a TMS.

If you have 500+ keys and 3+ languages, a TMS will save you hours weekly.

Step 2: Choose a TMS

Evaluate based on:

  • Pricing (check enterprise features vs your needs)
  • Git integration (do you want translations in Git?)
  • OTA support (mobile app? You'll want this)
  • Frameworks (React, Vue, React Native SDKs?)
  • API quality (good docs, rate limits)

Step 3: Import Existing Translations

Most TMSs support JSON import:

Terminal
# IntlPull example
npx @intlpullhq/cli import --format json --file locales/en.json --language en
npx @intlpullhq/cli import --format json --file locales/fr.json --language fr

Step 4: Set Up CI/CD

Add translation sync to your pipeline:

YAML
1# GitHub Actions example
2- name: Pull latest translations
3  run: npx @intlpullhq/cli download
4  env:
5    INTLPULL_API_KEY: ${{ secrets.INTLPULL_API_KEY }}
6
7- name: Build app
8  run: npm run build

Step 5: Invite Translators

Give translators access to the TMS. They'll never touch your code again.

Real-World Examples

Company A: Stuck with Browser API Only

  • SaaS app, 12 languages
  • Translations in JSON files in Git
  • Translators submit PRs (!)
  • 40% of PRs are translation updates
  • Developers spend 5 hours/week reviewing translation PRs
  • Translation errors make it to production regularly

Annual cost: ~260 developer hours = $26,000 (assuming $100/hour)

Company B: Using IntlPull

  • SaaS app, 15 languages
  • Translations managed in IntlPull
  • Translators use web UI, zero PRs
  • Developers run npx @intlpullhq/cli download before deploys
  • OTA updates fix errors instantly
  • Developers spend 0 hours on translation management

Annual cost: $348 (IntlPull: $29/month) Savings: $25,652/year

The Bottom Line

The browser Intl API is excellent at what it does: formatting. Use it for dates, numbers, currencies, and locale-aware display logic.

But internationalization is more than formatting. It's:

  • Managing translated content
  • Collaborating with translators
  • Automating workflows
  • Deploying updates quickly

For anything beyond a simple app with 1-2 languages, you'll want a translation management system.

Start with the Intl API for formatting. Add a TMS when you have more than 2 languages or more than 100 translation keys. Your future self will thank you.


Ready to stop managing translations manually?

Try IntlPull free. CLI-first TMS with Git integration, OTA updates, and visual context for translators. No credit card required.

Or stick with DIY if you're still in the "100 keys, 2 languages" zone. We'll be here when you outgrow it.

Tags
intl-api
browser-api
javascript
i18n
translation-management
comparison
IntlPull Team
IntlPull Team
Engineering

Building tools to help teams ship products globally. Follow us for more insights on localization and i18n.