<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joul</title>
    <description>The latest articles on DEV Community by Joul (@joul_dev).</description>
    <link>https://dev.to/joul_dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4063924%2Fcc1cc157-ff85-430e-96ab-627aaccc5c93.png</url>
      <title>DEV Community: Joul</title>
      <link>https://dev.to/joul_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joul_dev"/>
    <language>en</language>
    <item>
      <title>I translated my app into Chinese. I don't speak Chinese.</title>
      <dc:creator>Joul</dc:creator>
      <pubDate>Wed, 05 Aug 2026 09:55:19 +0000</pubDate>
      <link>https://dev.to/joul_dev/i-translated-my-app-into-chinese-i-dont-speak-chinese-4g60</link>
      <guid>https://dev.to/joul_dev/i-translated-my-app-into-chinese-i-dont-speak-chinese-4g60</guid>
      <description>&lt;p&gt;The translation itself took minutes. Verifying it found a bug that had been sitting in my app all along — in English too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why bother
&lt;/h2&gt;

&lt;p&gt;While researching where local AI inference is actually popular, I kept running into the same answer: China. It makes sense — capable consumer GPUs, a strong self-hosting culture, a healthy distrust of cloud services. It's also a market that's structurally out of reach for Western cloud SaaS... but not for an open-source desktop app. Nothing to host, nothing to bill, nothing to block.&lt;/p&gt;

&lt;p&gt;So the math looked like this: potential upside — access to one of the largest local-inference communities in the world; cost — an afternoon. I don't speak a word of Chinese. I did it anyway.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Publikey/imference-desktop" rel="noopener noreferrer"&gt;Imference Desktop&lt;/a&gt; is a local-first image generation app. There isn't that much text in it — buttons, labels, settings, error messages. I asked Claude to translate the locale file. That's the part everyone imagines is hard. It isn't.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foh2hypiwlumrqcp6bmuf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foh2hypiwlumrqcp6bmuf.png" alt="Imference Desktop — the same main screen in English (top) and Chinese (bottom)" width="800" height="835"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Same screen, two audiences — English on top, Chinese below.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The parts that actually needed thought
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Some strings don't live where you think they do.&lt;/strong&gt; My format labels ("Portrait Large", "Landscape Ultra-Wide"...) come from the server's model catalog, not from the app's locale files. Result: the format bar showed up half-translated — three Chinese labels followed by six English ones — because only the strings that existed as i18n keys got translated. Localization coverage is an architecture question before it's a language question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some things must NOT be translated.&lt;/strong&gt; Model names stay in English — even Chinese users say "Flux" and "SDXL". Translating them would have made the app &lt;em&gt;harder&lt;/em&gt; to use. Knowing what to leave alone matters as much as translating the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Localization is adaptation, not conversion.&lt;/strong&gt; The Chinese prompt placeholder doesn't say what the English one says. It adds a piece of advice the English version doesn't need: "describe the image you want (English recommended), e.g. ...". Most image models are trained predominantly on English captions; a Chinese user typing a Chinese prompt gets worse results through no fault of their own. The translation that serves the user diverges from the source on purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying what you can't read
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable part. When the translation came back, I was looking at strings I could not evaluate at all. For all I knew, my "Cancel" button said something embarrassing.&lt;/p&gt;

&lt;p&gt;My review pipeline, fully honest version:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I took paired screenshots of every screen — English and Chinese side by side.&lt;/li&gt;
&lt;li&gt;I fed them to a &lt;em&gt;fresh&lt;/em&gt; Claude session, in incognito mode, with no memory of my app and no stake in defending its own translation, and asked for an element-by-element comparison.&lt;/li&gt;
&lt;li&gt;It came back with a structured review: most of the translation judged idiomatic and faithful, the half-translated format bar flagged, two wording refinements suggested (a clearer per-generation credits label, a VRAM-vs-memory inconsistency in a settings subtitle), and one question — "your Chinese placeholder diverges from the English one, is that intentional?"&lt;/li&gt;
&lt;li&gt;I fed that review to Claude Code, which traced each finding to the actual cause in the codebase and implemented the fixes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My job in all this was arbitration, not translation: keep the divergent placeholder (intentional), pick the Chinese naming scheme for the extended formats, decide where to fix what. The pipeline was AI end to end — translator, reviewer, implementer — with a human making the three or four judgment calls that actually required one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The review found a bug in my app
&lt;/h2&gt;

&lt;p&gt;This is the part I didn't see coming. Comparing the two languages element by element, the reviewer noticed something off that had nothing to do with Chinese: my aspect ratios were backwards. A 896×1152 portrait format was labeled "9:7" — a landscape ratio. Checked against the API: systematic, every image format in the catalog ships its ratio string inverted. In production. In both languages. Nobody had ever reported it — including me, who had looked at that format bar hundreds of times.&lt;/p&gt;

&lt;p&gt;The fix was a ten-line client-side normalization (trust the dimensions, flip the string when its orientation disagrees). The lesson is bigger: &lt;strong&gt;a careful localization review is a free QA pass.&lt;/strong&gt; Fresh eyes — even artificial ones — forced to compare two renderings of the same UI element by element will catch things you've stopped seeing. The Chinese translation improved my English app.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell other indie devs
&lt;/h2&gt;

&lt;p&gt;AI has collapsed the cost of localization. What used to require an agency, a budget and weeks now takes an afternoon — &lt;em&gt;for the right kind of product&lt;/em&gt;. Two honest caveats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This works because my app has little text and low stakes. I would not ship an AI-only translation for legal copy, medical content, or marketing where tone is everything.&lt;/li&gt;
&lt;li&gt;The translation is the cheap part. The verification pipeline and the public honesty are what make it shippable. My Chinese README says it plainly: translated with AI assistance by a dev who doesn't speak Chinese — corrections welcome via PR. That one line turns my biggest weakness into a contribution funnel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The asymmetry is what matters: an afternoon of work for access to a market I couldn't otherwise touch. Even if it only ever brings a handful of users and a few translation-fixing PRs, it already paid for itself — it found a bug my own eyes never would have.&lt;/p&gt;

</description>
      <category>i18n</category>
      <category>ai</category>
      <category>indiedev</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
