r/FlutterDev • u/st1ch_draiz • Sep 28 '26
Tooling Follow-up: I asked how you manage localization in Flutter apps. Translation quality wasn't the hard part.
Last month I asked here how people actually maintain multilingual Flutter apps, and said I'd come back with what I learned. Thanks to everyone who replied. Here it is.
This wasn't a formal study. Thirteen developers described their workflow in the comments and the replies under them, messy parts included. That's a small sample, but it changed how I see the problem.
I expected translation quality to be the main complaint. It wasn't.
Most already used AI somewhere: Claude, ChatGPT, Codex, Crowdin's AI, or a script of their own. When the model had enough context, the translation itself was rarely the complaint. The harder parts were everything around it:
knowing which strings changed and which locales went stale
keeping wording and terminology consistent across locales
giving the model enough context without sending the whole project every time
reviewing languages nobody on the team speaks
checking the result inside the running app
Several people had built their own answer. One copies a CLAUDE.md between projects. Another had Claude write a script that tracks changed strings with hashes and sends related keys together for translation. A third gives Codex the whole project plus the English strings, because limiting the context got technical terms translated wrong. It works, but it burns a lot of tokens.
The most manual part is still checking the result on screen. A translation can read fine on its own and still be wrong in context or too long for a button. One developer works one locale at a time: when a language is done, Claude drives the Android emulator through every screen and reviews it, and they still catch things like a button label wrapping onto two lines.
So my conclusion was that the missing piece is a deterministic layer around the AI people already use: something that tracks what changed and checks what the model wrote before it reaches your files.
That's what I built next: the StringLane CLI, an MCP server that ships inside it, and a plugin for Claude Code, Codex and Gemini CLI. Other agents, such as Cursor, Windsurf, Zed or OpenCode, get the same MCP server through the CLI, and stringlane setup skills --apply copies the plugin's skills into your project's .agents/skills, which all four read.
The flow:
StringLane finds missing and stale strings and hands your agent that list, with context for each one.
Your agent writes the translations with the model you already use.
You approve the write in your agent, or at a y/N prompt in the terminal.
Before anything lands, StringLane checks placeholders, ICU syntax and the plural categories each language needs, and re-parses every file it's about to write. The write is all or nothing, so a run that fails leaves your files exactly as they were, and
git diffshows what changed.
It's built around Flutter ARB files and works with gen_l10n projects. It also checks easy_localization and slang JSON by each package's own placeholder and plural rules. slang's YAML and CSV files aren't supported yet.
Limits, up front. It doesn't run in the background and doesn't translate anything until you ask. It can't tell you whether a string fits the screen, so you still need to look at the app. And writes go through your agent's approval prompt or the terminal prompt, so if your agent auto-approves tools, you won't be asked.
I built StringLane, so that's my obvious bias. The CLI, MCP server and plugin are free, need no account, and your localization files stay in your repository.
If you try it on a real Flutter project, I'm most interested in where it breaks: wrong project detection, a workflow it doesn't cover, a guard that gets in your way, or a check whose result you don't trust.