<?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: CodeWithRasul</title>
    <description>The latest articles on DEV Community by CodeWithRasul (@codewithrasul_5dc431417e8).</description>
    <link>https://dev.to/codewithrasul_5dc431417e8</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%2F2453497%2F9821fe27-959b-4c0e-9f2e-6fdc9774cd98.jpg</url>
      <title>DEV Community: CodeWithRasul</title>
      <link>https://dev.to/codewithrasul_5dc431417e8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codewithrasul_5dc431417e8"/>
    <language>en</language>
    <item>
      <title>Vergate: a version gate for Flutter with force update, soft update and maintenance mode</title>
      <dc:creator>CodeWithRasul</dc:creator>
      <pubDate>Sat, 03 Oct 2026 18:35:24 +0000</pubDate>
      <link>https://dev.to/codewithrasul_5dc431417e8/vergate-a-version-gate-for-flutter-with-force-update-soft-update-and-maintenance-mode-1jhk</link>
      <guid>https://dev.to/codewithrasul_5dc431417e8/vergate-a-version-gate-for-flutter-with-force-update-soft-update-and-maintenance-mode-1jhk</guid>
      <description>&lt;p&gt;Hi r/FlutterDevs,&lt;/p&gt;

&lt;p&gt;I just published &lt;strong&gt;Vergate&lt;/strong&gt;, a Flutter package that decides whether the installed version of your app may run. It handles force updates, optional updates and maintenance mode.&lt;/p&gt;

&lt;p&gt;I built it for my own apps, where I wanted one reusable solution instead of rewriting the same version check each time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Force update:&lt;/strong&gt; a dialog that cannot be dismissed, driven by &lt;code&gt;min_version&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Soft update:&lt;/strong&gt; a banner or dialog, driven by &lt;code&gt;latest_version&lt;/code&gt;, with "Remind me later" and "Skip this version" remembered between launches&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance mode:&lt;/strong&gt; an optional &lt;code&gt;from&lt;/code&gt;/&lt;code&gt;until&lt;/code&gt; window, a live countdown, and an automatic re-check when the window ends&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-platform rules:&lt;/strong&gt; separate versions and store links for Android and iOS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release notes&lt;/strong&gt; shown in the update dialog&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail-open:&lt;/strong&gt; network or parsing errors never lock the user out&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Re-checks on app resume:&lt;/strong&gt; users who return from the store get in right away&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pluggable data sources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vergate does not depend on Firebase or any specific service. The rules are a small JSON document, and it ships with a few ways to load it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;JsonUrlSource&lt;/code&gt;: any URL that returns JSON (your own API, GitHub raw, S3)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CallbackSource&lt;/code&gt;: plug in anything else with a simple async function (I use it for Firebase Remote Config)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ItunesLookupSource&lt;/code&gt;: reads the latest version from the App Store (soft updates on iOS)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FallbackSource&lt;/code&gt;: tries several sources in order&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also implement the &lt;code&gt;VergateSource&lt;/code&gt; interface yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The theme follows your Material theme, so dark mode works out of the box. You can override colors, radii and icons, pass your own texts (including a &lt;code&gt;stringsBuilder&lt;/code&gt; for localization), or replace any screen with your own widget. The core &lt;code&gt;VergateController&lt;/code&gt; is also UI-free if you want to build everything yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick start&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final vergate = VergateController(
  source: JsonUrlSource(Uri.parse('https://example.com/app-version.json')),
);

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  vergate.start();
  runApp(const MyApp());
}

MaterialApp(
  builder: (context, child) =&amp;gt; VergateGate(
    controller: vergate,
    child: child!,
  ),
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Design notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The gate is an overlay, not a route, so it works above the Navigator and your app's state is never lost.&lt;/li&gt;
&lt;li&gt;While a force update or maintenance screen is shown, the app underneath is blocked for touch, focus and screen readers.&lt;/li&gt;
&lt;li&gt;A client-side gate is not a substitute for server-side version checks on security-critical APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limitations (v0.1.0)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is no store lookup for Android, because Google Play has no official API for it. Put the Android version in your own config.&lt;/li&gt;
&lt;li&gt;The update button opens the store page. Android's In-App Update API is not used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pub.dev: &lt;a href="https://pub.dev/packages/vergate" rel="noopener noreferrer"&gt;https://pub.dev/packages/vergate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/therasuldev/vergate" rel="noopener noreferrer"&gt;https://github.com/therasuldev/vergate&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the first release, so I'd really appreciate feedback: missing features, API design, edge cases I haven't thought of, or bug reports. Thanks for reading!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>mobile</category>
      <category>opensource</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
