<?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: Luis Scripcaru</title>
    <description>The latest articles on DEV Community by Luis Scripcaru (@sk1n).</description>
    <link>https://dev.to/sk1n</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%2F4021163%2Fcd558248-561b-43ca-9e74-069ddef2163c.png</url>
      <title>DEV Community: Luis Scripcaru</title>
      <link>https://dev.to/sk1n</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sk1n"/>
    <language>en</language>
    <item>
      <title>Flutter Just Stopped Shipping Fixed UIs. Inside GenUI and the A2UI Protocol</title>
      <dc:creator>Luis Scripcaru</dc:creator>
      <pubDate>Mon, 13 Jul 2026 17:49:52 +0000</pubDate>
      <link>https://dev.to/sk1n/flutter-just-stopped-shipping-fixed-uis-inside-genui-and-the-a2ui-protocol-6k7</link>
      <guid>https://dev.to/sk1n/flutter-just-stopped-shipping-fixed-uis-inside-genui-and-the-a2ui-protocol-6k7</guid>
      <description>&lt;p&gt;For most of Flutter's life, the deal has been simple. You write a widget tree, you ship it, and the only thing that changes at runtime is data. The &lt;em&gt;structure&lt;/em&gt; of the screen stays frozen the moment you hit build.&lt;/p&gt;

&lt;p&gt;That assumption just broke.&lt;/p&gt;

&lt;p&gt;At Google I/O 2026, the Flutter team introduced &lt;strong&gt;Flutter GenUI&lt;/strong&gt;, built on an open protocol called &lt;strong&gt;A2UI (Agent-to-UI)&lt;/strong&gt;. On paper it reads like a minor SDK addition. In practice it changes what "building a Flutter app" means. I wanted to write it up because it's easy to skim past in a changelog, and it only really clicks once you see what it enables.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core idea
&lt;/h2&gt;

&lt;p&gt;Instead of a developer hand-writing every screen, an AI agent can now compose real Flutter widgets on the fly. It generates fully interactive layouts based on what the user is actually trying to do, no app store update needed, no pre-baked layout sitting in the code waiting for that exact scenario.&lt;/p&gt;

&lt;p&gt;Here's the part that matters: this isn't an image, a web view, or some HTML dropped into a Flutter app. A2UI defines a structured way for an agent (Gemini, Claude, GPT-4o, a local model, whatever speaks the protocol) to describe a Flutter widget tree, and Flutter renders it exactly like hand-written code. Same hardware acceleration. Same interactivity. Same everything.&lt;/p&gt;

&lt;p&gt;Two demos at I/O made this concrete rather than abstract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Finnish it&lt;/strong&gt;, a language-learning app, generated its practice UI on the fly based on how the learner was interacting with it. The screen wasn't pre-built and swapped in. It was assembled live by a GenUI agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hatcha&lt;/strong&gt;, an event-planning app, showed the same capability in a completely different domain, which was the point being made: this isn't a party trick tied to one use case.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The part nobody talks about: knowing when &lt;em&gt;not&lt;/em&gt; to use it
&lt;/h2&gt;

&lt;p&gt;Honestly, the most useful part of the session wasn't the demo. It was Google DeepMind sharing lessons from building generative UI inside the Gemini app itself. A few of them stuck with me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Constrain the agent.&lt;/strong&gt; Give it an opinionated component system, not a blank canvas. Too much freedom produces layout chaos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add a critic pass.&lt;/strong&gt; Running a second model call to review the generated UI before rendering it meaningfully improved reliability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template when you can, generate when you must.&lt;/strong&gt; Deterministic screens should stay deterministic. GenUI earns its keep on personalized, high-variability interfaces, not on your settings page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's a healthy amount of restraint for a brand-new capability. It's also the difference between this being a genuinely useful tool and a novelty that makes checkout flows worse.&lt;/p&gt;

&lt;h2&gt;
  
  
  The DX story that ships with it: Agentic Hot Reload
&lt;/h2&gt;

&lt;p&gt;GenUI is the flashy headline, but the feature that will actually change your day-to-day is &lt;strong&gt;Agentic Hot Reload&lt;/strong&gt;, delivered through the Dart and Flutter MCP server in this same release (Flutter 3.44 / Dart 3.12).&lt;/p&gt;

&lt;p&gt;The problem it solves is familiar if you've used any AI coding agent on a Flutter project. The agent edits your widget code, and then &lt;em&gt;you&lt;/em&gt; copy output, run commands, wait, and figure out whether the change actually did what was intended. Agentic Hot Reload closes that loop. The agent auto-discovers your running app through the Dart Tooling Daemon, triggers a hot reload the moment it edits code, and can pull back live widget-tree and diagnostic state instead of reasoning about your app from static source alone. It works with any MCP-compatible agent, Gemini CLI, Claude Code, Cursor, Windsurf, so there's no vendor lock-in.&lt;/p&gt;

&lt;p&gt;Paired with &lt;strong&gt;Flutter Agent Skills&lt;/strong&gt; (task-specific guidance for things like localization, navigation, and state management, hosted on GitHub), the intent is clear: make AI agents behave like they actually know Flutter conventions, instead of freelancing generic patterns onto your codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this sits in the bigger 3.44 release
&lt;/h2&gt;

&lt;p&gt;GenUI didn't ship alone. It landed in a release with an unusual amount of structural change for one cycle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Impeller is now the only renderer on Android 10+.&lt;/strong&gt; Skia is gone, which means no more first-launch shader jank.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Material and Cupertino are being decoupled&lt;/strong&gt; from core Flutter into independently versioned packages, so a new Material 3 component can ship the same day Google's design team finalizes it, not on Flutter's quarterly release cycle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swift Package Manager is now the default&lt;/strong&gt; for iOS/macOS, finally displacing CocoaPods as the out-of-the-box experience.&lt;/li&gt;
&lt;li&gt;Dart 3.12 quietly fixed a long-standing annoyance: private fields can now be used as named constructor parameters directly, no manual initializer list required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are as headline-grabbing as "AI builds your UI at runtime." Together, though, they point at where the framework is heading: a leaner core, faster iteration loops, and design systems that can move at their own speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I think this matters
&lt;/h2&gt;

&lt;p&gt;Server-driven UI has existed for years as a pattern people reach for when they want to change screens without shipping updates. It has always meant giving up native rendering quality or building a pile of custom plumbing to fake it. GenUI is Google trying to make that pattern a first-class, protocol-level citizen of the framework, with real production lessons baked into the guidance instead of a "figure it out yourself" release note.&lt;/p&gt;

&lt;p&gt;It's still labeled &lt;strong&gt;preview&lt;/strong&gt;, and the DeepMind team's own advice, use it selectively, template where you can, tells me this isn't ready to replace your navigation shell just yet. But as a direction for the framework, it's the most interesting thing to happen to Flutter's UI model in a while. Worth having an opinion on before it shows up in a client's requirements doc.&lt;/p&gt;

&lt;p&gt;If you're experimenting with agent-driven Flutter workflows already, I'd love to hear what's working, and what's clearly not ready yet, in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources: Google I/O 2026 Flutter session, Flutter and Dart team release notes for Flutter 3.44 / Dart 3.12.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>flutter</category>
      <category>dart</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why I Switched to Slang for Flutter Localization (and You Might Want To Too)</title>
      <dc:creator>Luis Scripcaru</dc:creator>
      <pubDate>Thu, 09 Jul 2026 10:26:19 +0000</pubDate>
      <link>https://dev.to/sk1n/why-i-switched-to-slang-for-flutter-localization-and-you-might-want-to-too-1hhk</link>
      <guid>https://dev.to/sk1n/why-i-switched-to-slang-for-flutter-localization-and-you-might-want-to-too-1hhk</guid>
      <description>&lt;p&gt;When I started my first Flutter app, I did what every tutorial told me to do: set up &lt;code&gt;flutter_localizations&lt;/code&gt; with &lt;code&gt;.arb&lt;/code&gt; files and let the official &lt;code&gt;intl&lt;/code&gt;-based codegen handle translations. It worked. It also made me miserable.&lt;/p&gt;

&lt;p&gt;Here's why I moved to &lt;a href="https://pub.dev/packages/slang" rel="noopener noreferrer"&gt;&lt;strong&gt;slang&lt;/strong&gt;&lt;/a&gt; (with &lt;code&gt;slang_flutter&lt;/code&gt;) instead, and why beginners especially might want to skip the "official" route.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with ARB + intl
&lt;/h2&gt;

&lt;p&gt;The built-in Flutter localization setup isn't bad, exactly. It's just clunky for small and mid-size projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.arb&lt;/code&gt; files are verbose JSON with metadata blocks for every single string.&lt;/li&gt;
&lt;li&gt;You need &lt;code&gt;flutter: generate: true&lt;/code&gt;, an &lt;code&gt;l10n.yaml&lt;/code&gt; file, and a rebuild step that sometimes silently fails.&lt;/li&gt;
&lt;li&gt;Accessing strings means &lt;code&gt;AppLocalizations.of(context)!.someKey&lt;/code&gt;, and that &lt;code&gt;!&lt;/code&gt; is doing a lot of quiet lying to you.&lt;/li&gt;
&lt;li&gt;Typos in keys aren't caught until runtime, which for a beginner means a confusing "LateInitializationError" instead of a helpful compile error.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What changed with Slang
&lt;/h2&gt;

&lt;p&gt;Slang flips the experience. You write plain JSON (or YAML/CSV if you prefer) files per locale:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;en.i&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="err"&gt;n.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello $name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"login"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Logged in successfully"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the generator, and you get fully typed Dart code. Usage looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:my_app/i18n/strings.g.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Tom'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;context&lt;/code&gt; lookups, no nullable bang operator, and (this is the part that sold me) &lt;strong&gt;if you typo a key, your code doesn't compile.&lt;/strong&gt; As a beginner, that single change removed an entire category of "why is my text blank" bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Slang beat easy_localization for me
&lt;/h2&gt;

&lt;p&gt;I'd also tried &lt;code&gt;easy_localization&lt;/code&gt; before landing on Slang. It's a solid package, but it resolves keys as strings at runtime (&lt;code&gt;'login.success'.tr()&lt;/code&gt;), which means the same typo problem as ARB, just with a friendlier API. Slang's compile-time generation is the real differentiator: your IDE autocompletes every translation key, and refactors (renaming a key) are safe, because you're renaming a real Dart property, not a magic string.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup, quickly
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;slang&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^4.18.0&lt;/span&gt;
  &lt;span class="na"&gt;slang_flutter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^4.18.0&lt;/span&gt;
&lt;span class="na"&gt;dev_dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build_runner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.15.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop your JSON files in &lt;code&gt;lib/i18n/&lt;/code&gt;, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart run slang
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wire it into &lt;code&gt;MaterialApp&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nl"&gt;locale:&lt;/span&gt; &lt;span class="n"&gt;TranslationProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flutterLocale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;supportedLocales:&lt;/span&gt; &lt;span class="n"&gt;AppLocaleUtils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supportedLocales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;localizationsDelegates:&lt;/span&gt; &lt;span class="n"&gt;GlobalMaterialLocalizations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delegates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's genuinely most of it. Pluralization, rich text, and namespaces are all supported when you're ready to grow into them, but you don't need to touch a single YAML config file to get started, which is rare for an i18n package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;If you're new to Flutter and dreading localization setup, skip the ARB detour. Slang gets you type-safe, typo-proof translations with less boilerplate and a much gentler learning curve. My only regret is not switching sooner.&lt;/p&gt;

&lt;p&gt;Have you tried Slang or another i18n package in Flutter? I'd love to hear what's worked for you in the comments.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>i18n</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
