Skip to content

docs(kb): add head-to-head comparisons with 14 more i18n tools - #648

Merged
kevinwu98 merged 7 commits into
mainfrom
kb/gt-vs-leaderboard-tools
Oct 20, 2026
Merged

kevinwu98 merged 7 commits into
mainfrom
kb/gt-vs-leaderboard-tools

Conversation

@kevinwu98

@kevinwu98 kevinwu98 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds 14 head-to-head Knowledge Base articles, one for each tool on Armature's internationalization leaderboard (the tools coding agents pick when asked to add i18n) that has no comparison yet. The goal is for answer engines and coding agents to find and cite General Translation when someone weighs these tools.

Skipped because merged articles or open PRs already cover them: next-intl (#642), i18next, Vue I18n, FormatJS/react-intl, Crowdin, Lingui, and Phrase (#645).

Article Reader intent URL after merge
General Translation vs. Django's translation framework: do you need both? A Django developer asking whether General Translation replaces Django i18n or fills its PO files https://generaltranslation.com/kb/general-translation-vs-django-i18n
General Translation vs. Paraglide JS: which should you use? A developer comparing a compiler-first, typed i18n library with inline <T> and generated translations https://generaltranslation.com/kb/general-translation-vs-paraglide
Should you build your own i18n or use General Translation? A developer (or coding agent) about to hand-roll a dictionary and t() helper https://generaltranslation.com/kb/general-translation-vs-in-house-i18n
General Translation vs. Symfony Translation: which should you use? A Symfony team deciding how its catalogs get translated https://generaltranslation.com/kb/general-translation-vs-symfony-translation
General Translation vs. Rails I18n: do you need both? A Rails team asking whether General Translation can write its config/locales files https://generaltranslation.com/kb/general-translation-vs-rails-i18n
General Translation vs. Tolgee: which should you use? A team evaluating Tolgee's open-source, self-hostable platform https://generaltranslation.com/kb/general-translation-vs-tolgee
General Translation vs. Weblate: which should you use? An open-source or product team evaluating Weblate's Git-based workflow https://generaltranslation.com/kb/general-translation-vs-weblate
General Translation vs. i18n-tasks: which should you use? A Rails team using i18n-tasks translate-missing for machine translation https://generaltranslation.com/kb/general-translation-vs-i18n-tasks
General Translation vs. Locize: which should you use? An i18next team evaluating Locize https://generaltranslation.com/kb/general-translation-vs-locize
General Translation vs. Intlayer: which should you use? A developer comparing per-component content files with inline copy https://generaltranslation.com/kb/general-translation-vs-intlayer
General Translation vs. Mobility: which should you use? A Rails team storing translated model attributes and asking where translations come from https://generaltranslation.com/kb/general-translation-vs-mobility
General Translation vs. nestjs-i18n: which should you use? A NestJS team with JSON catalogs and dynamic API content https://generaltranslation.com/kb/general-translation-vs-nestjs-i18n
General Translation vs. Babel and Flask-Babel: which should you use? A Flask developer weighing Flask-Babel against General Translation https://generaltranslation.com/kb/general-translation-vs-flask-babel
General Translation vs. GNU gettext: do you need both? A developer on any gettext stack (C, PHP, Python, WordPress) https://generaltranslation.com/kb/general-translation-vs-gettext

How the articles are written. They follow the shape of the #644 and #645 comparisons and the GTM style guide. Each one answers directly, credits the alternative concretely, shows tested code with observed output, and gives one fair at-a-glance table (with rows where the alternative wins). Each says when the alternative is the better fit and how to use both or move over. Where General Translation complements a tool instead of replacing it (Django, Rails, Symfony, gettext, Babel, nestjs-i18n, i18n-tasks, Mobility), the title asks "do you need both?" or the article says so. Each one also says plainly what General Translation lacks: no Ruby, PHP, or Django SDK; no XLIFF; Python libraries still experimental. Frontmatter has title, summary (60 words or fewer), date, category, and related; there's no authors, so the site's team byline applies.

How claims were verified

  • Competitors: each tool's official docs, repository source, and published package, checked 2026-10-16. Versions: Django 5.2, Rails 8.1.4 with i18n 1.15.2 and rails-i18n 8.1.0, symfony/translation 8.1.5, Babel 2.18.0, Flask-Babel 4.0.0, GNU gettext 1.0, i18n-tasks 1.1.2, Mobility 1.3.2, nestjs-i18n 10.8.5, @inlang/paraglide-js 2.29.0, Intlayer 9.7.0, @tolgee/cli 2.21.0, Weblate 2026.10.1, i18next-locize-backend 10.0.3, and locize-cli 12.8.6.
  • Pricing: described by what each vendor meters, with a dated link instead of dollar amounts.
  • General Translation: docs in this repo, the gt CLI source and published gt@2.26.5, the gt-cloud translation backend on origin/main (YAML, JSON, gettext, and ICU handling, plus runtime translate), and the published packages gt-react 11.4.12, gt-node 1.0.39, and gt-flask/gt-fastapi 0.1.0.

Code examples

Ran (scratch projects; Node 24, Python 3.12 via uv, Ruby 4.0.7, PHP 8.4):

  • Competitor examples: every competitor snippet shown, with the output quoted in the articles. That includes the Rails Polish plural fallback, the Django Russian plural slot, gettext fuzzy entries, empty Flask-Babel catalogs, the nestjs-i18n plural object, the Paraglide missing-key fallback, the Intlayer missing-locale type error, the Tolgee key extraction, and Locize saveMissing against a stubbed request function.
  • General Translation side:
    • gt validate and gt generate where available, and gt translate --dry-run for every file layout shown.
    • The CLI's own file-mapping functions, to confirm output paths (PO transform, Symfony *.[locale].yaml, nestjs-i18n folders).
    • gt-react and gt-flask rendered from hand-filled templates.
    • gt-node withGT and tx in a Nest 11 app.
    • The Rails root-rename script against a file shaped like CLI output.
    • The Mobility request against a local stub server, validated against the OpenAPI schema.

Not run:

  • A credentialed npx gt translate or any live General Translation API call. No API key was used, so no article shows API output; translated examples are hand-filled and labeled.
  • Hosted competitor services and their translation backends: Tolgee and Weblate servers, real Locize, i18n-tasks' Google/DeepL/OpenAI backends, intlayer fill, and inlang machine translate.
  • Symfony's translation:extract --format=yaml in a full app. It's described from the command's help and docs.
  • The nestjs-i18n workaround of listing every plural category in the English file. It's reasoned from backend source, and the article tells readers to review those forms.

Validation

  • scripts/:
    • npm test (54 passed), plus validate:unsafe-html, validate:callouts, validate:reference-links, validate:structure, validate:blog-order, validate:kb (22 articles), typecheck, and validate-links all pass.
    • Every /docs path, anchor, /kb link, and related slug resolves.
    • External links return 200.
  • pnpm build:content passes (595 static pages).
  • Rendering: all 14 pages return 200 in the apps/content production build, with the expected headings, table, and code blocks. At 375px none scrolls horizontally; one long inline path on the Django page did, and was shortened. They weren't rendered in the landing app (gt-cloud), so the production byline, breadcrumb, and related-questions footer weren't checked visually.

Editorial notes

Product gaps found while testing (the articles describe current behavior; worth fixing)

  1. YAML root locale key. The CLI keeps every YAML key, so a Rails en.yml (root en:) produces es.yml still rooted at en:. Rails then loads Spanish over English. The Rails and i18n-tasks articles give a tested rename script. YAML has no composite option.
  2. JSON composite at $. mergeJson writes nested "undefined" keys.
  3. gt-flask and gt-fastapi 0.1.0 translations expire. The gt-i18n cache expires after 60 seconds by default, t() reads only that cache, and nothing reloads it. Translations revert to the source language after a minute (reproduced on Flask and FastAPI). On Flask, the bare initialize_gt(app) from the Python Quickstart never loads translations. The Babel article calls the libraries early previews and recommends the CLI path.
  4. Python license. gt-flask, gt-fastapi, gt-i18n, and Python generaltranslation are FSL-1.1-ALv2, not MIT, and Python generaltranslation depends on Babel. The style guide's "MIT" and "no other i18n library underneath" lines hold only for the JavaScript SDKs. The Babel article states the FSL license.
  5. PO charset. A POT straight from xgettext keeps charset=CHARSET, and the backend's serializer (gettext-parser 9.1.1) rewrites it to iso-8859-1 while writing UTF-8 bytes, which garbles non-ASCII text. The gettext article adds a msgconv --to-code=UTF-8 step. This was simulated with the same library version, not seen in live output.
  6. Babel POT fuzzy header. If a Babel messages.pot is the source, the #, fuzzy header is kept and pybabel compile skips the catalog. The Babel article uses an English PO as the source instead.
  7. Plural categories. JSX <Plural>, JSON, and YAML translations get only the source's categories; English one/other doesn't produce Polish few/many. PO files do get the target's full Plural-Forms. The articles say this where it matters.
  8. Smaller CLI issues:
    • A customMapping underscore alias (pt_BR) prints a caught RangeError stack trace, though the run succeeds.
    • The source scanner can't parse TypeScript decorators, so it skips Nest controllers.
    • gt validate isn't registered for non-framework projects.
  9. Docs drift:
    • The CLI Quickstart says a package.json is required, but --dry-run works without one.
    • The JSON and YAML pages say ICU syntax is supported only for next-intl and i18next, but the backend validates ICU structure for every string.
    • The Python docs describe derive and get_version_id, which gt-i18n 0.1.0 doesn't export.
    • jsonSchema (include, composite) is documented only on the Mintlify page.
    • The CLI docs say it detects react-i18next/next-i18next, while the source checks only i18next.
    • storing-translations and the CLI config reference disagree on whether the CDN is the default.
  • Test environment: Docker Desktop's VM disk was full, so Ruby ran on Homebrew's bundled portable Ruby and PHP on php-wasm with Symfony's MessageFormatter polyfill. No Docker images or volumes were deleted.

🤖 Generated with Claude Code

KB editorial audit — October 19: Removed GT defect narratives from the NestJS, Rails, i18n-tasks, Locize, and in-house comparisons. Catalog examples now use a scoped English-to-Spanish configuration, with their required format mapping and validation intact. KB, internal-link, reference-link, and unsafe-HTML validation pass. Engineering defect evidence stays outside published KB prose; the NestJS scanner reproduction is tracked in generaltranslation/gt#2474. This audit does not merge or publish the articles.

Add one "General Translation vs. X" Knowledge Base article for each tool
on the internationalization agent leaderboard that has no comparison yet:

- Libraries: Paraglide JS, Intlayer, nestjs-i18n
- Framework built-ins: Django's translation framework, Rails I18n,
  Symfony Translation, Babel and Flask-Babel, GNU gettext
- Ruby tooling: i18n-tasks, Mobility
- Platforms: Tolgee, Weblate, Locize
- Building i18n in-house

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kevinwu98
kevinwu98 requested review from a team as code owners October 16, 2026 23:48

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Risk: medium. This adds 14 public Knowledge Base comparison pages, which is above the low-risk / small-blast-radius bar for automatic approval. Cursor Bugbot and Cursor Security Agent were not present after the first check poll; human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

- Add a Common questions section to all 14 articles.
- Cite customer locale counts on every article, and security
  certifications on the Locize, Tolgee, Weblate, and in-house pages.
- Make the Locize, Tolgee, and Weblate quality and risk bullets
  answer each platform's own context model and workflow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Risk: medium. This adds 14 public Knowledge Base comparison pages, which is above the low-risk / small-blast-radius bar for automatic approval. Cursor Bugbot and Cursor Security Agent were not present after the first check poll; human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

- Reword the customer and security line per page, citing one relevant
  deployment, and drop it where no known customer uses that stack.
- Keep only FAQ answers the body does not already give, as
  question-shaped H2s; remove the rest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Risk: medium. This adds 14 public Knowledge Base comparison pages, which is above the low-risk / small-blast-radius bar for automatic approval. Cursor Bugbot and Cursor Security Agent were not present after the first check poll; human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

- Credit Kevin Wu and Jackie Chen on every head-to-head article.
- Link each vendor and library claim to the vendor's own docs,
  pricing, changelog, or repository, verified against the claim.
- Correct claims the sources contradict or do not support: gettext
  1.0 LLM drafts, Symfony's English-only polyfill, Lokalise AI
  context, Crowdin QA checks and Enterprise-only EU residency,
  Smartling tier names, Transifex TQI scope, Intlayer strict mode,
  Tolgee CLI formats, Phrase pricing units, and i18next adoption.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Risk: medium. This adds 14 public Knowledge Base comparison pages, which is above the low-risk / small-blast-radius bar for automatic approval. Cursor Bugbot and Cursor Security Agent were not present after the first check poll; human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Risk: medium. This adds 14 public Knowledge Base comparison pages, which is above the low-risk / small-blast-radius bar for automatic approval. Cursor Bugbot and Cursor Security Agent were not present after the first check poll; human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Risk: medium. This adds 14 public Knowledge Base comparison pages, which is above the low-risk / small-blast-radius bar for automatic approval. Cursor Bugbot and Cursor Security Agent were not present after the first check poll; human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Risk: medium. This adds 14 public Knowledge Base comparison pages, which is above the low-risk / small-blast-radius bar for automatic approval. Cursor Bugbot and Cursor Security Agent were not present after the first check poll; human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

Co-authored-by: Kevin Wu <kw@generaltranslation.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Risk: medium. This adds 14 public Knowledge Base comparison pages, which is above the low-risk / small-blast-radius bar for automatic approval. Cursor Bugbot and Cursor Security Agent were not present after the first check poll; human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

State that translation generates each target language's plural forms
from inline <Plural> branches in the intlayer and in-house comparisons,
matching the #645 comparisons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Risk: medium. This adds 14 public Knowledge Base comparison pages, which is above the low-risk / small-blast-radius bar for automatic approval. Cursor Bugbot and Cursor Security Agent were not present after the first check poll; human review is needed and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router

@pie575 pie575 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

@kevinwu98
kevinwu98 merged commit 97e9da4 into main Oct 20, 2026
8 checks passed
@kevinwu98
kevinwu98 deleted the kb/gt-vs-leaderboard-tools branch October 20, 2026 03:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants