RepoPilotOpen in app →

fnando/i18n-js

It's a small library to provide the I18n translations on the Javascript. It comes with Rails support.

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 6mo ago
  • 8 active contributors
  • MIT licensed
Show 4 more →
  • CI configured
  • Tests present
  • Slowing — last commit 6mo ago
  • Single-maintainer risk — top contributor 86% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/fnando/i18n-js)](https://repopilot.app/r/fnando/i18n-js)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/fnando/i18n-js on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: fnando/i18n-js

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/fnando/i18n-js shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 6mo ago
  • 8 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Slowing — last commit 6mo ago
  • ⚠ Single-maintainer risk — top contributor 86% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live fnando/i18n-js repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/fnando/i18n-js.

What it runs against: a local clone of fnando/i18n-js — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in fnando/i18n-js | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | Last commit ≤ 220 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>fnando/i18n-js</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of fnando/i18n-js. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/fnando/i18n-js.git
#   cd i18n-js
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of fnando/i18n-js and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "fnando/i18n-js(\\.git)?\\b" \\
  && ok "origin remote is fnando/i18n-js" \\
  || miss "origin remote is not fnando/i18n-js (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 220 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~190d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/fnando/i18n-js"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

i18n-js is a Ruby gem and JavaScript companion package that exports i18n YAML translation files to JSON for use in JavaScript/frontend applications. It bridges Rails backend translations (via the i18n gem) with frontend code by generating locale-specific JSON files with pattern-based filtering, optional MD5 digests, and ERB templating in config files. Hybrid Ruby+TypeScript monorepo: lib/i18n-js/ contains the core Ruby engine (lib/i18n-js/cli/ for command-line interface, lib/i18n-js/plugin.rb for the plugin system), lib/guard/i18n-js/ wraps it for Guard integration, and lib/i18n-js/lint.ts is a standalone TypeScript linter compiled to JavaScript via esbuild. Configuration is file-based (config/i18n.yml) using ERB templating.

👥Who it's for

Rails developers building applications with significant JavaScript/frontend code who need to share i18n translations between server and client without duplicating translation files or manually converting YAML to JSON.

🌱Maturity & risk

This is production-ready, actively maintained software. The codebase shows maturity with a v4 migration guide (MIGRATING_FROM_V3_TO_V4.md), comprehensive CLI tools, GitHub Actions CI (ruby-tests.yml), and plugin architecture. Substantial Ruby codebase (~87KB) indicates real-world usage.

Low risk overall—the project has a single maintainer (fnando) which creates some bus-factor risk, but the gem is widely used in Rails ecosystems. Dependencies are minimal and modern (glob, esbuild, TypeScript) with no evidence of stale packages. The codebase lacks visible test files in the structure provided, which is a gap for a library of this criticality.

Active areas of work

The project recently completed a v3-to-v4 migration (evidenced by MIGRATING_FROM_V3_TO_V4.md), suggesting API stabilization work. The CHANGELOG.md indicates ongoing maintenance. CLI tools are being actively organized (multiple command classes: check_command.rb, export_command.rb, init_command.rb, lint_translations_command.rb, plugins_command.rb).

🚀Get running

Clone and install: git clone https://github.com/fnando/i18n-js.git && cd i18n-js && bundle install. Initialize config: bundle exec i18n init. Then run: bundle exec i18n export to generate JSON translations. For development: npm install && npm run compile to rebuild the TypeScript linter.

Daily commands: Development: bundle exec rake to run tests. Export translations: bundle exec i18n export. Initialize a new config: bundle exec i18n init. Check configuration: bundle exec i18n check. Lint scripts: bundle exec i18n lint:scripts. For TypeScript linter: npm run compile.

🗺️Map of the codebase

  • lib/i18n-js.rb: Entry point for the gem; sets up Rails integration and exposes the public API
  • lib/i18n-js/cli/export_command.rb: Core export logic that reads i18n config and generates JSON translation files
  • lib/i18n-js/schema.rb: Validates i18n.yml configuration file structure before export
  • lib/i18n-js/plugin.rb: Plugin system architecture that allows export_files_plugin.rb and embed_fallback_translations_plugin.rb to extend functionality
  • lib/i18n-js/lint.ts: TypeScript-based linter for translation keys; compiled to JavaScript for Node.js execution
  • config/i18n.yml: User-facing configuration file (ERB template) that controls which translations get exported and where

🛠️How to make changes

For translation export logic, modify lib/i18n-js/export_files_plugin.rb. For new CLI commands, add a class in lib/i18n-js/cli/ following the pattern of check_command.rb or export_command.rb. For configuration schema, edit lib/i18n-js/schema.rb. For Rails integration, edit lib/i18n-js.rb. For linting rules, modify lib/i18n-js/lint.ts and recompile.

🪤Traps & gotchas

The i18n.yml config file is processed as ERB (see README snippet), so string interpolation happens before export—mind variable scope. The :digest placeholder in file paths uses MD5 hex (non-cryptographic); regenerating exports with identical content yields identical digests. TypeScript linter requires compilation step (npm run compile) before use; changes to lint.ts won't take effect without recompilation. Guard integration (lib/guard/i18n-js) is separate from core and requires Guard gem to be installed. No explicit test directory is visible in the file structure, suggesting tests may be in a test/ folder not shown in the top-60 list.

💡Concepts to learn

  • Glob pattern matching with wildcards and negation — i18n-js uses glob patterns (*, !prefix, {a,b} groups) to filter which i18n keys get exported; understanding this is essential for writing correct config patterns
  • ERB template processing in configuration files — i18n.yml is processed as an ERB template before parsing; you can inject dynamic Ruby into config (e.g., environment variables, conditional patterns)
  • Rails engine and Railtie pattern — i18n-js integrates into Rails via a Railtie (lib/i18n-js.rb); knowing how Rails loads gems and engines helps modify initialization behavior
  • MD5 digest-based cache busting — Exported filenames can include :digest (MD5 hex of content), allowing CDNs and browsers to cache and bust translations automatically without version numbers
  • CLI command pattern (Thor style) — lib/i18n-js/cli/ uses a command pattern with base class (command.rb) and subclasses (export_command.rb, etc.); extending the CLI requires adding new command classes
  • Plugin architecture with registry — lib/i18n-js/plugin.rb defines a plugin system; export_files_plugin.rb and embed_fallback_translations_plugin.rb extend behavior without modifying core
  • YAML-to-JSON hierarchical translation structure — i18n YAML files use nested keys (e.g., en.messages.greeting) that must flatten or nest correctly in JSON output; lib/i18n-js/clean_hash.rb and sort_hash.rb handle this transformation
  • ruby-i18n/i18n — The upstream i18n gem that i18n-js exports from; fundamental dependency
  • svenfuchs/rails-i18n — Companion gem providing locale data and translations for Rails; commonly used alongside i18n-js
  • galetahub/localeapp — Alternative Rails translation management tool; competes in the same space for exporting translations to frontend
  • airbnb/polyglot.js — JavaScript i18n library (frontend-only); often used as the runtime paired with i18n-js exports
  • fnando/i18n-js-npm — The companion JavaScript/npm package for i18n-js mentioned in README; handles client-side translation lookups

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add TypeScript unit tests for lib/i18n-js/lint.ts

The lint.ts file is compiled to JavaScript but there are no dedicated unit tests visible in the test directory for the linting logic. The repo has test configs for lint_scripts and lint_translations, but no actual test cases exercising the TypeScript lint module. This is critical since linting is a core feature and TypeScript compilation (via esbuild) should have corresponding test coverage.

  • [ ] Create test/lint.test.ts or test/unit/lint.test.ts with test cases for lint.ts exports
  • [ ] Add test cases for validation of translation keys, missing translations, and invalid YAML/JSON
  • [ ] Reference test/config/lint_translations.yml and test/config/lint_scripts.yml fixtures in tests
  • [ ] Add npm script 'test:ts' or extend existing test suite to run TypeScript tests
  • [ ] Verify tests pass with 'npm run compile' to ensure TypeScript builds correctly

Add GitHub Actions workflow for Node.js/npm package testing

The repo has .github/workflows/ruby-tests.yml for Ruby tests, but there's no CI workflow for the JavaScript/TypeScript side despite having package.json with esbuild and TypeScript dependencies. The lint.ts compilation step and npm scripts should be tested in CI to catch build/compilation errors early.

  • [ ] Create .github/workflows/node-tests.yml with Node.js matrix (16.x, 18.x, 20.x)
  • [ ] Add steps to run 'npm install', 'npm run compile', and any npm test scripts
  • [ ] Ensure the workflow validates that lib/i18n-js/lint.js is properly generated from lint.ts
  • [ ] Add badge to README.md linking to the new Node workflow status
  • [ ] Consider running on pull_request and push events to main/develop branches

Create CLI integration tests for lib/i18n-js/cli commands

The lib/i18n-js/cli directory has multiple command classes (check_command.rb, export_command.rb, init_command.rb, etc.) but test/config contains only configuration files, not actual integration tests exercising these CLI commands. Adding tests ensures CLI behavior doesn't regress and validates the complete export/check/lint workflows.

  • [ ] Create test/integration/cli_test.rb with tests for each CLI command in lib/i18n-js/cli/
  • [ ] Add test cases for: 'i18n export', 'i18n check', 'i18n lint-translations', 'i18n init' using test/config/*.yml files
  • [ ] Verify error handling for invalid config files (test/config/require_error.rb already exists)
  • [ ] Test locale placeholder substitution using test/config/locale_placeholder.yml
  • [ ] Validate digest/fingerprinting behavior from test/config/digest.yml

🌿Good first issues

  • Add test coverage for lib/i18n-js/clean_hash.rb and lib/i18n-js/sort_hash.rb—these are utility functions responsible for JSON shape correctness and are likely undertested given no visible test files in the top 60.
  • Document the plugin system: create examples/ folder showing how to write a custom plugin (using lib/i18n-js/embed_fallback_translations_plugin.rb as a model) with inline code comments.
  • Implement a --dry-run flag for lib/i18n-js/cli/export_command.rb that prints what would be exported without writing files—useful for debugging configurations.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • f8fb0dc — Bump up version (4.2.4). (fnando)
  • 2cbea21 — Remove benchmark gem (#737) (fnando)
  • 9f99172 — Update matrix. (fnando)
  • 9096c6e — Fix rubocop warnings. (fnando)
  • 237b69b — Update --quiet param description (#730) (zcag)
  • 1f3305f — Update action. (fnando)
  • 674cb07 — Fix rubocop warning. (fnando)
  • 877e6f1 — Update actions. (fnando)
  • 7e27159 — Require ruby 3.2+. (fnando)
  • 58c32fd — Disable rubocop rule. (fnando)

🔒Security observations

The i18n-js codebase has a moderate security posture. The primary concerns are outdated npm dependencies (esbuild, TypeScript, glob) which may contain known vulnerabilities. Secondary concerns include potential code injection risks through ERB templates, CLI argument validation, and file path traversal risks in export operations. No hardcoded secrets were detected, and there are no obvious SQL injection risks. The codebase lacks infrastructure/Docker security issues. Immediate action should focus on updating npm dependencies to their latest versions and implementing stricter input validation in CLI and file operation handlers.

  • Medium · Outdated TypeScript Dependency — package.json - dependencies.typescript. TypeScript version ^4.9.4 is used, which is significantly outdated. Current stable versions are in the 5.x range. Outdated TypeScript versions may contain known security vulnerabilities and lack important type safety improvements. Fix: Update TypeScript to the latest stable version (^5.3.3 or newer) to receive security patches and improvements.
  • Medium · Outdated esbuild Dependency — package.json - dependencies.esbuild. esbuild version ^0.16.2 is significantly outdated. Current versions are in the 0.19+ range. Outdated build tools may contain security vulnerabilities or lack important fixes. Fix: Update esbuild to the latest stable version (^0.19.x or newer) to receive security patches and bug fixes.
  • Medium · Outdated glob Dependency — package.json - dependencies.glob. glob version ^8.0.3 is outdated. Current versions are in the 10.x range. File globbing libraries may contain vulnerabilities related to path traversal or ReDoS attacks. Fix: Update glob to the latest stable version (^10.x or newer) to address security vulnerabilities and performance improvements.
  • Low · Potential Code Injection via Configuration Files — test/config/config.yml.erb, test/fixtures/export_files.erb. The codebase uses ERB templates (config.yml.erb, export_files.erb) which allow Ruby code execution. If configuration files can be user-controlled or loaded from untrusted sources, this could lead to code injection attacks. Fix: Ensure that ERB template files are only loaded from trusted sources. Implement strict validation and sanitization of any user-supplied configuration data. Consider using safer configuration formats (YAML/JSON only) without template processing when possible.
  • Low · CLI Command Execution Risk — lib/i18n-js/cli/, lib/i18n-js/cli.rb. The CLI module (lib/i18n-js/cli/) exposes multiple commands including export, check, and lint operations. If user input is not properly validated, it could lead to argument injection or command execution vulnerabilities. Fix: Implement strict input validation for all CLI arguments. Use allowlists for file paths and command arguments. Avoid passing unsanitized user input to system calls or file operations.
  • Low · File I/O Without Path Validation — lib/i18n-js/export_files_plugin.rb, lib/i18n-js/clean_hash.rb. The export functionality (lib/i18n-js/export_files_plugin.rb) and other file operations may be vulnerable to path traversal attacks if file paths are not properly validated before being read or written. Fix: Implement path canonicalization and validation. Use File.expand_path and verify that resolved paths are within expected directories. Reject any paths containing '..', '~', or absolute paths if not explicitly allowed.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · fnando/i18n-js — RepoPilot