Model or dataset
ObservedObserver/chatgpt-i18n avatar
ObservedObserver/chatgpt-i18n

chatgpt-i18n: a web app for translating locale files with a model

Localize your websites with AI assistance.

805 stars98 forksTypeScriptAGPL-3.0

At a glance

What is it?
chatgpt-i18n is a self hosted web application that translates i18n locale files with a language model, with a Monaco based editor, a zip export for many locales at once, and chunking so a large JSON file does not break the model output. The backend talks to OpenRouter, the browser can hold its own key, and the chunking path is still marked as work in progress.
Who is it for?
chatgpt-i18n fits a team that has a real i18n directory, wants the translation done in a browser with structure preserved, and is willing to host the app itself rather than paste locale files into a chat window. It does not fit a team that needs a guaranteed format, since the chunking path is described as work in progress and can hit the limits of the serverless platform, and it does not fit anyone unwilling to run an AGPL licensed application.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A web app for the boring half of localisation

chatgpt-i18n is a web application for translating locale files with AI assistance, and the project description puts it plainly: localise your websites with AI assistance. The demo runs on Vercel at i18n.ing, and the repository is a TypeScript project with a Vite frontend and a small serverless backend.

The scope is narrow on purpose. It does not manage a translation workflow, it does not track which strings changed, and it does not connect to a translation management system. What it does is take the locale files you already have, let you edit the result in a browser, and hand you the translated files back in a form you can drop into your repository.

The feature list is short. Translate your locale files with a better experience, a web editor for better editing and viewing, export multiple locale files at once, and separate a large JSON file into small chunks to avoid the model breaking the JSON. That last one is the interesting feature, and the section below returns to it.

The stack underneath is visible in the manifest. React 18 with mobx and mobx-react-lite for state, Monaco for the editor, zip.js for the multi file export, js-yaml for YAML locale files alongside the JSON ones, react-router-dom for routing, Tailwind for styling with Headwind UI and Heroicons, and the openai package at version 7 for the API calls. The package is marked private, so it is an application you run rather than a library you install, and it is version 0.1.0.

The licence is AGPL-3.0, which is the one detail to weigh before you deploy it anywhere.

The reason it exists: ChatGPT keeps breaking your JSON

The README explains the motivation in the first person, and it is worth quoting the substance because it defines the problem better than any feature list would.

The author built the application because they were tired of using Google Translate on locale files and wanted something more efficient and accurate. ChatGPT, however, always broke the JSON and could not translate large content. So the application was built to solve those two problems.

Those two problems are the design brief. The first is structural integrity: a locale file is a JSON object with keys that are often interpolated, and a model that reformats or truncates the output produces a file that will not parse, and a broken locale file is a broken application, not a slightly wrong translation. The second is size, since a large application has a large locale file and a model request has a limit.

That framing also sets the bar for judging the result. This is not a translation memory system and it does not claim professional quality output. It is a way to get a machine translation that still parses, with a human able to review it in an editor before it goes back into the repository. The review step is not an optional extra in this workflow, it is the point of the editor.

The comparison to a chat window is the implicit alternative, and it is a real one: paste a locale file into a chat, ask for a translation, get JSON back, and fix whatever broke. The app exists to make that a repeatable, structured workflow rather than a manual ritual.

Chunking large files, and the serverless ceiling it hits

The chunking feature is the one the author flags as unfinished, and the note in the README is specific: separating a large JSON file into small chunks to avoid the model breaking the JSON is work in progress, because the service seems slow now and sometimes breaks the limit of the Vercel FaaS, and the author is working on it.

That single line contains three separate constraints, and they compound.

The first is that the chunking path is slower. The second is that the request can exceed the execution limit of the serverless function, which is why the deployment section of the README tells you to build the backend with a deploy command rather than run it locally, and why the development script points at the Vercel development server that contains both the frontend and the backend on port 3000.

The third is the one with the widest consequences. A tool that breaks on the files you actually have, and whose fix is in progress, is not a tool you can hand to a team with a large locale directory and expect it to work unattended. For a small project with a few hundred strings, the chunking path may never be exercised. For a project with thousands of keys across a dozen locales, it is the path that runs every time.

The same note appears in the feature list as a checkbox, which is a good sign about how the project tracks its own rough edges.

What the app does not attempt, and the README does not claim, is any kind of incremental translation across sessions. There is no record of which keys were already translated, no diff against a previous run, and no way to translate only the strings that changed since the last commit. Every run is a fresh pass over the file.

The editor and the multi file export

Two features make this usable rather than a novelty, and both are visible in the screenshots the README shows.

The first is the web editor. The project lists a web editor for better editing and viewing experience, and the manifest shows the implementation: the Monaco editor through its React wrapper, and the state layer in mobx with mobx-react-lite for reactivity. Monaco is the editor that ships with Visual Studio Code, which is the point, because a translator reviewing machine output needs the same affordances a developer has, including a real text editor rather than a textarea.

The second is export multiple locale files at once, implemented with zip.js. This is the feature that makes the tool fit a real repository, where a translation update is usually a commit that touches one file per locale. Getting a single zip with the whole set back means you can drop it into the project and open one pull request, instead of downloading and replacing files one at a time.

The README also shows the ability to enter a URL and have it translated, and the interface is built around that as the primary action, with the editor and the export as the surrounding workflow.

The application is a client side application in a meaningful sense. The translation itself can run from the browser with a key you enter in the settings, which is covered in the next section, and the server side exists to handle the cases where a request is too large or too slow for the browser path.

Two independent key paths, and the provider juggling behind them

The deployment model has more moving parts than a simple web app, and the README is specific about them.

The backend requires Node.js 22 and uses the OpenAI SDK 7 with OpenRouter. Step one of the deployment is to create an env file with the key for the backend APIs.

bash
OPENROUTER_API_KEY=<your OpenRouter key>
OPENROUTER_MODEL=openai/gpt-5.4-mini

The dependencies are then installed with a frozen lockfile, and the app is built in two parts, a frontend build and a backend build.

bash
yarn install --frozen-lockfile
bash
# forntend
npm run build
# backend
npm run server:build

The backend build is a deploy to Vercel, and the development script runs the Vercel development server, which contains both the frontend and the backend, on port 3000.

bash
npm run server
# vercel dev (this contains both frontend and backend)
# localhost:3000

Then there is the second key path, and it is independent of the backend. Browser translations use the key saved in Settings, independently of the backend environment. In the interface you select OpenRouter, enter your OpenRouter API key, and save it. The default model is openai/gpt-5.4-mini, and you can enter another OpenRouter OpenAI model ID in the Model field. The default model runs with reasoning disabled for translation, which is a sensible default since reasoning tokens on a translation task cost more than they add.

The migration rules are also documented, and they are the kind of detail that saves an afternoon. Existing OpenAI settings are migrated to OpenRouter with the old key cleared. Saved GPT-3.5 OpenRouter settings upgrade automatically, and custom model IDs are preserved. Azure settings remain supported. Switching providers clears the key, so you re-enter it for the new provider.

The practical consequence is that the key lives in two places with different rules, and a deployment where the backend is shared by several users has to decide which path each user takes.

Tests that mock the model, and a repository with no releases

The validation commands are short, and the note about what the tests do is the important part.

bash
yarn test
yarn build

Tests mock OpenRouter responses and do not make paid model calls. That is the right design for a project whose core dependency is a paid API, and it means the suite can run in continuous integration without an account or a budget. The test script runs the Node test runner through tsx against the files in the tests directory, and the build script runs tsc and then vite build, so a type error fails the build rather than shipping.

There is a circular dependency check in the scripts too, and a prettier configuration with a print width of 140 and a tab width of 4.

On the repository itself, the top level has the Vite frontend in src, the serverless functions in api, shared code in lib, the tests, the static assets in public, an index.html, the Vite, Tailwind, and PostCSS configuration files, two TypeScript configurations, an AGENTS.md, and a yarn.lock.

The project is not archived and the last push was on 2026-10-16, so it is being worked on, but there are no GitHub releases at all and the package is private with the version at 0.1.0. There is no changelog and no version history to consult, which is a meaningful difference from the released packages in this space: you are adopting a moving application rather than a versioned one, and you should expect to pull updates rather than to upgrade to a specific release.

The AGPL-3.0 licence is the other thing to settle before you host it. It is a strong copyleft licence, and for an internal tool you run yourself the obligations are limited, but the README does not discuss licensing and the file in the repository is the authority.

Editorial conclusion

chatgpt-i18n fits a team that has a real i18n directory, wants the translation done in a browser with structure preserved, and is willing to host the app itself rather than paste locale files into a chat window. It does not fit a team that needs a guaranteed format, since the chunking path is described as work in progress and can hit the limits of the serverless platform, and it does not fit anyone unwilling to run an AGPL licensed application. Verify first that the model you select on OpenRouter handles the file size you have, that the backend environment variables are set if you intend to use the server side path, and that the browser side key you save in Settings is stored where you intend it to be, since the two key paths are independent of each other.

Frequently asked questions

What does chatgpt-i18n do?

It is a web application for translating your locale files with AI assistance, with a Monaco based web editor for reviewing the result and an export that produces multiple locale files at once. Large JSON files are split into small chunks so the model does not break the JSON.

How do I deploy chatgpt-i18n?

The backend requires Node.js 22. You create a .env file with OPENROUTER_API_KEY and OPENROUTER_MODEL, install dependencies with yarn install --frozen-lockfile, then build the frontend with npm run build and the backend with npm run server:build, which deploys it to Vercel.

Can I use my own API key in the browser instead of the backend?

Yes, and the two paths are independent. Browser translations use the key saved in Settings: you select OpenRouter, enter your OpenRouter API key, and save it. The default model is openai/gpt-5.4-mini, and switching providers clears the stored key.

Does chatgpt-i18n make paid model calls during testing?

No. The tests mock OpenRouter responses and do not make paid model calls, so yarn test and yarn build can run in continuous integration without an account or any model spend.

What are the limits of the large file handling in chatgpt-i18n?

The feature that splits large JSON files into chunks is marked as work in progress: the service seems slow and sometimes breaks the limit of the Vercel FaaS, and the author is working on it. The README also documents no incremental translation, so each run translates the file again.

Official sources

  1. Issues
  2. License: AGPL-3.0
  3. ObservedObserver/chatgpt-i18n on GitHub
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/observedobserver-chatgpt-i18n.svg)](https://hysenlabs.com/projects/observedobserver-chatgpt-i18n)

Was this useful?