java.evolved - Translating a Website into 8 Languages with AI Agents in One Night with Bruno Borges - JVM Weekly vol. 165
This month: AI-powered i18n at scale, 25 years of IntelliJ IDEA, Java on RISC-V, developer branding, MongoDB driver optimizations, unikernels, and Java in education.
Year ago I announced that JVM Weekly had joined the Friends of OpenJDK (Foojay.io) family. Foojay.io is a dynamic, community-driven platform for OpenJDK users, primarily Java and Kotlin enthusiasts. As a hub for the “Friends of OpenJDK,” Foojay.io gathers a rich collection of articles written by industry experts and active community members, offering valuable insights into the latest trends, tools, and practices within the OpenJDK ecosystem.
This month’s main feature is a piece that is a follow up to what I was already men. Bruno Borges from the Developer Relations team at Microsoft/GitHub published a fantastic writeup on Foojay about how he internationalized his java.evolved website - 112 patterns across 11 categories - into 9 languages in a single night.
Translating a Website into 8 Languages with AI Agents in One Night
How I used Claude Sonnet 4.6 and fleets of GitHub Copilot Coding Agents to internationalize java.evolved - from spec to deployment
java.evolved is a static site I built to showcase modern Java patterns side-by-side with their legacy equivalents. 112 patterns across 11 categories -- language, collections, streams, concurrency, and more - each with code comparisons, explanations, and curated documentation links. All generated from YAML content files by a JBang-powered Java build script.
By the end of February 25, the entire site was English-only. By the morning of February 26, it was available in 9 languages - English, German, Spanish, Portuguese (Brazil), Simplified Chinese, Arabic, French, Japanese, and Korean -- with full RTL support for Arabic. The total human effort was a few hours of prompting, reviewing PRs, and filing one bug.
This is the story of that experiment.
The Architecture Decision: Let the AI Draft the Spec
The first step wasn’t writing code. It was writing a specification.
I opened issue #74 - “Plan architectural change for i18n” - and assigned it to a Copilot Coding Agent. The prompt was simple: propose an architectural plan for internationalizing the website, considering the existing static-site structure.
The agent (PR #75) came back with a comprehensive i18n specification that addressed:
Two-layer translation model: UI strings (labels, nav, footer) separated from content translations (pattern titles, explanations, summaries)
Partial translation files: Translation files contain only translatable fields. Structural data (code snippets, navigation links, metadata) always comes from the English source of truth
Graceful fallback: Missing translations fall back to English with a build-time warning -- no page is ever blank
Locale registry: A simple
locales.propertiesfile drives the entire build pipeline and language selectorAI-friendly design: The architecture was explicitly designed so that an AI receives the full English content and returns a partial translation file -- no field-filtering logic needed in the prompt
This last point proved prescient. The clean separation between “what changes per locale” and “what stays constant” meant each translation task was self-contained and parallelizable.
After iterating through review comments over 5 days (the original PR had 12 comments of back-and-forth), the spec was merged on February 25.
Phase 1: Building the Infrastructure
With the spec in hand, I coordinated an agent locally with Copilot CLI to implement the core i18n infrastructure in PR #83 - the generator changes that made everything locale-aware:
The
generate.javabuild script learned to iterate all locales fromlocales.propertiesTemplate tokens like
{{sections.codeComparison}}replaced hard-coded English stringshreflangmeta tags, a locale picker dropdown, and client-side locale detection were addedThe
resolveSnippetfunction loads translated content overlaid onto the English base, falling back gracefully when a translation doesn’t exist
This was the only PR that required significant intervention. Everything after it was delegation.
Phase 2: The First Translations (Spanish + Portuguese)
The first real translation - Spanish - came in PR #84. This PR also migrated the English content files from JSON to YAML for improved readability -- a format change that the AI handled naturally since the generator already supported multiple formats.
Brazilian Portuguese followed immediately in PR #85, completing all 112 pattern files. These first two translations validated the architecture and surfaced a CI issue: the deploy workflow’s path triggers didn’t match YAML files or the translations/ directory. A quick fix in PR #86 resolved that.
Phase 3: The Fleet - 6 Languages in Parallel
This is where things got interesting. With the architecture proven and two complete translations validated, I launched a fleet of Copilot Coding Agents -- multiple agents working in parallel, each assigned a single language. I used the Copilot CLI /delegate command to dispatch them asynchronously, all with the same prompt:
Each agent independently:
Read the i18n spec and understood the file structure
Created a UI strings YAML file with 60+ translated keys
Generated 112 content translation YAML files -- one per pattern, across all 11 categories
Registered the locale in
locales.propertiesOpened a PR with a detailed description of what was translated
All six PRs were opened within a span of about 12 minutes (2:33 AM to 2:45 AM) and were all merged within the next hour. No translation conflicts, no merge issues, no structural errors.
The Numbers
By the time the fleet finished:
8 locales fully supported (besides English)
112 patterns x 8 translated locales = 896 content translation files
8 UI string files with 60+ keys each
~1,008 generated HTML pages (112 pages x 8 locales)
8 localized search indexes (
snippets.jsonper locale)
The Arabic Surprise: RTL Support
The most impressive moment was the Arabic translation (PR #91). The agent not only translated, it also noted that Arabic is a right-to-left language and proactively added RTL infrastructure:
Added
dir="{{htmlDir}}"to the<html>tag in both templatesModified the generator to resolve
htmlDirto"rtl"for Arabic and"ltr"for all other localesUpdated the Python benchmark generator to pass the new token
This was a genuinely thoughtful architectural change that I hadn’t explicitly requested. The agent understood that Arabic support implies RTL layout and acted on it.
The One Bug
Of course, it wasn’t perfect. When dir="rtl" is applied globally, the browser flips everything -- including Java source code blocks and the navigation bar, which should always be LTR regardless of locale. I spotted this when reviewing the deployed site and filed issue #96.
A Copilot Coding Agent fixed it in PR #97 within minutes, adding targeted CSS overrides. Arabic prose continues to render RTL. Java code stays LTR. One bug, one issue, one PR, fixed in minutes.
[dir="rtl"] nav,
[dir="rtl"] .nav-inner {
direction: ltr;
}
[dir="rtl"] pre,
[dir="rtl"] code,
[dir="rtl"] .code-text,
[dir="rtl"] .card-code,
[dir="rtl"] .compare-code {
direction: ltr;
text-align: left;
unicode-bidi: embed;
}Why It Worked: Architecture as Force Multiplier
This experiment succeeded because of deliberate architectural decisions, not just because of a magic AI prompt:
Source of Truth Separation -- Content files contain both translatable text and structural data. But translation files contain only the translatable fields. The generator overlays translations onto the English base at build time. AI agents can’t accidentally modify code snippets or break navigation.
Partial File Fallback -- If a pattern has no translation file for a locale, the site shows the English content with an “untranslated” banner. Partial translations are always valid. New patterns added in English are immediately visible in all locales.
Convention Over Configuration -- Each locale follows the same directory structure. Adding a new language is a checklist: add a line to locales.properties, create the strings file, create content files. No code changes needed in the generator.
Lessons Learned
What Went Well:
Spec-first approach: Having the AI draft the specification before any implementation meant the architecture was explicitly designed for AI-driven translation from day one
Fleet parallelism: Six language translations running simultaneously with zero conflicts demonstrates that well-isolated task boundaries enable effortless parallelization
Proactive problem-solving: The Arabic agent identifying and implementing RTL support without being explicitly asked shows that LLMs can reason about downstream implications
Technical term preservation: Across all 9 languages, Java API names, annotations, JDK versions, and code examples were correctly left in English
What Required Human Intervention:
One bug: The RTL global flip affecting code blocks
CI pipeline fixes: The deploy workflow needed path trigger updates
Review and merge: Each PR needed a human to review and merge
The java.evolved project is open source at github.com/javaevolved/javaevolved.github.io. The i18n specification lives at specs/i18n/i18n-spec.md.
The Timeline
Conclusion
The experiment proved a simple thesis: if you design your architecture for AI-driven workflows, AI agents can do remarkable things.
I didn’t build a custom translation pipeline or prompt-engineering framework. I wrote a specification. An AI agent drafted it, I refined it through code review, and then a fleet of agents executed against it. The architecture - partial files, fallback behavior, source-of-truth separation - did all the heavy lifting.
The result is a Java patterns reference site available in 8 languages, with 1,008 generated pages, serving developers who speak English, German, Spanish, Portuguese, Chinese, Arabic, French, and Korean. It handles right-to-left layouts. It has localized search. Every page has proper hreflang tags for SEO.
And the only bug was a CSS rule that took 13 minutes from report to fix.
The future isn’t AI replacing developers. It’s developers designing systems that let AI do what it’s good at - repetitive, structured, parallelizable work - while humans focus on architecture, review, and the occasional RTL bug.
java.evolved is open source at github.com/javaevolved/javaevolved.github.io. The i18n specification lives at specs/i18n/i18n-spec.md.
My take: This article is a nice example of what I keep calling “engineering-first AI usage.” Bruno didn’t just throw prompts at a wall -- he made the AI draft an architecture that was explicitly designed for parallelized, agent-driven work. The spec-first approach, the partial-file design, the convention-over-configuration pattern - all of this is what separates “vibe coding” from what I’d call “vibe engineering.” The architecture is the prompt, in a sense.
What’s particularly interesting from the JVM perspective is that the entire build pipeline is powered by JBang - a single
generate.javascript that handles locale iteration, template resolution, and content overlay. No Maven, no Gradle, just JBang doing what it does best: making Java scripts feel as natural as shell scripts. Between this and the java.evolved project itself (which is a fantastic community resource for showcasing modern Java), Bruno keeps proving that Java’s developer experience has come a long way.Also - 896 translation files, zero merge conflicts, in one night. The “fleet” pattern of dispatching multiple agents in parallel is something I expect we’ll see a lot more of.
Oh, and one more thing - inspired by Bruno’s work, I went ahead and did the Polish translation myself. It’s live at javaevolved.github.io/pl/. Poland Strong.
Also on Foojay This Month
Foojay Podcast #91: 25 Years of IntelliJ IDEA: The IDE That Grew Up With Java - Frank Delporte celebrates a quarter century of IntelliJ IDEA with guests from the JetBrains team - Marit van Dijk and Anton Arhipov. From the early days of revolutionary code completion to AI-powered features and the recent unified Community/Ultimate release - a great retrospective.
As someone deeply embedded in the JetBrains/Kotlin ecosystem (which probably surprises no one at this point), I always have a soft spot for the 'behind the scenes' stories - how IntelliJ evolved alongside Java itself. Highly recommend watching this one, as I've been following this story through pretty much my entire career, and I have to say, it's one of those tales that never gets old 😁
I Got Java 25 Running on the RISC-V BeagleBoard BeagleV-Fire
Frank continues his 2026 single-board computer testing plan and successfully gets Java 25 running on RISC-V hardware. The key was updating the OS via BeagleBoard Imaging Utility (the BeagleV-Fire uses eMMC, not SD cards like Raspberry Pi). Once on Ubuntu 24, Java 25 installed via standard apt. Even SDKMAN and JBang work. Exciting times for Java on RISC-V - after experimenting with Arm last year, I need to play with this a bit.
Watch the Recording: DIY Technical Marketing for Java Developers
by Dominika Tasarz-Sochacka from Payara
A Jfokus 2026 talk about personal branding for developers. I was at the session and loved it. Great stuff! The core message - that small, intentional actions make a real difference for your career visibility without turning it into a full-time job - really resonated. Highly recommended for anyone who writes code for a living but hasn’t started writing about code yet.
Optimizing the MongoDB Java Driver: How Minor Optimizations Led to Macro Gains
by Nasir Qureshi and Slab Babanin
The MongoDB Java team shares how they achieved throughput improvements between 20% and over 90% in specific workloads. Techniques include JVM intrinsics, SWAR (SIMD Within A Register) for null-terminator detection in BSON, caching BSON array indexes, and eliminating redundant invariant checks. The guiding principle: “never guess, always measure.”
The largest improvement - +96.46% in Large doc Collection BulkWrite insert - is jaw-dropping. A truly excellent deep-dive into low-level Java performance.
Unikernel: Profiling and Troubleshooting JVM on Nanos Unikernel
Can you profile a Java application running inside a unikernel with standard JVM tools? The answer is yes. Angelo walks through profiling a Quarkus application on Nanos unikernel using JProfiler and IBM Semeru JRE 25 (OpenJ9).
No special hacks - just standard JVMTI agent loading. Unikernels continue to be one of the most underexplored deployment targets for Java, and this article does a lot to demystify the operational side.
Bringing Java Closer to Education: A Community-Driven Initiative
A heartfelt piece about the Java Education Catalog on GitHub - a community-driven effort to gather, organize, and curate Java educational materials in one accessible place, especially for Raspberry Pi and physical computing contexts. The initiative grew out of conversations in the Code Club Slack, and Igor recently discussed it on Foojay Podcast #85. A wonderful example of community organizing that goes beyond code.
And it’s all, folks.








