<?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: Tech Stories by Hadi</title>
    <description>The latest articles on DEV Community by Tech Stories by Hadi (@tech_stories_by_hadi).</description>
    <link>https://dev.to/tech_stories_by_hadi</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3792120%2F6ba27cb0-fb92-4172-be05-8ccc0bf972d2.jpeg</url>
      <title>DEV Community: Tech Stories by Hadi</title>
      <link>https://dev.to/tech_stories_by_hadi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tech_stories_by_hadi"/>
    <language>en</language>
    <item>
      <title>From Flutter App to PWA: The Easiest Way to Share a Side Project</title>
      <dc:creator>Tech Stories by Hadi</dc:creator>
      <pubDate>Mon, 08 Jun 2026 21:50:11 +0000</pubDate>
      <link>https://dev.to/tech_stories_by_hadi/from-flutter-app-to-pwa-the-easiest-way-to-share-a-side-project-3l4m</link>
      <guid>https://dev.to/tech_stories_by_hadi/from-flutter-app-to-pwa-the-easiest-way-to-share-a-side-project-3l4m</guid>
      <description>&lt;h1&gt;
  
  
  Turning My Flutter App into a PWA
&lt;/h1&gt;

&lt;p&gt;Following up on my Smart Shower Meter project, I decided to make it a Progressive Web App (PWA) while still using Flutter.&lt;/p&gt;

&lt;p&gt;👉 Read about the original project here: &lt;a href="https://shadmehr.eu/never-built-a-mobile-app-now-we-can" rel="noopener noreferrer"&gt;Never Built a Mobile App? Now We Can&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 You can skip this guide and &lt;a href="https://smart-shower-meter.linguly.io/" rel="noopener noreferrer"&gt;just try it first&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;I originally chose Flutter because it allowed me to build a cross-platform app from a single codebase.&lt;/p&gt;

&lt;p&gt;But I quickly realised that getting an iOS version into the hands of friends for testing would take much longer than expected. Between App Store requirements, TestFlight, and developer fees, sharing a small hobby project felt more complicated than building it.&lt;/p&gt;

&lt;p&gt;So I thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why not just make it a PWA?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Users can open it directly in their browser and even install it on their device without going through an app store.&lt;/p&gt;

&lt;p&gt;Since Flutter already supports web, the transition was surprisingly easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  How?
&lt;/h2&gt;

&lt;p&gt;The goal was simple: keep the existing Flutter app and make it easy to access, deploy, and update.&lt;/p&gt;

&lt;p&gt;Like many developers these days, I started with coding agents and AI assistants to generate most of the setup. They got me most of the way there, but understanding the deployment stack still mattered when things broke (more on that later).&lt;/p&gt;

&lt;p&gt;The final setup consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flutter Web&lt;/li&gt;
&lt;li&gt;PWA support&lt;/li&gt;
&lt;li&gt;Docker Compose&lt;/li&gt;
&lt;li&gt;Coolify hosting&lt;/li&gt;
&lt;li&gt;Automatic CI/CD&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PWA Enabled
&lt;/h3&gt;

&lt;p&gt;A Progressive Web App is basically a website that behaves like an app.&lt;/p&gt;

&lt;p&gt;Users can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install it from their browser&lt;/li&gt;
&lt;li&gt;Launch it from their home screen&lt;/li&gt;
&lt;li&gt;Use it in a standalone window&lt;/li&gt;
&lt;li&gt;Get faster loading through caching&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flutter already ships with most of the required web infrastructure, so enabling PWA support mostly came down to configuring the web build and ensuring the generated app included the proper manifest and service worker files.&lt;/p&gt;

&lt;p&gt;The result feels surprisingly close to a native application for a project of this size.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Compose
&lt;/h3&gt;

&lt;p&gt;Once the web build worked, I wanted a deployment setup that could be reproduced easily.&lt;/p&gt;

&lt;p&gt;Docker Compose became the single source of truth for running the application.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistent deployments&lt;/li&gt;
&lt;li&gt;Version-controlled infrastructure&lt;/li&gt;
&lt;li&gt;Easy server migration&lt;/li&gt;
&lt;li&gt;Built-in health checks and configuration management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means I can move the project to another server with minimal effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coolify to Host It
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://coolify.io" rel="noopener noreferrer"&gt;Coolify&lt;/a&gt; is an open-source Platform as a Service (PaaS) that I use for most of my personal projects.&lt;/p&gt;

&lt;p&gt;For this project I'm using its &lt;a href="https://coolify.io/docs/applications/build-packs/docker-compose" rel="noopener noreferrer"&gt;Docker Compose deployment&lt;/a&gt; option. By simply providing the repository URL and selecting &lt;code&gt;Docker Compose&lt;/code&gt; as the build pack, Coolify handles the build and deployment process automatically.&lt;/p&gt;

&lt;p&gt;It also integrates nicely with GitHub.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every merge to &lt;code&gt;main&lt;/code&gt; automatically triggers a deployment, giving me a simple CI/CD pipeline with almost no setup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Did I Learn?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Security? Never Heard of : )
&lt;/h3&gt;

&lt;p&gt;One thing I learned quickly is that AI-generated infrastructure shouldn't be trusted blindly.&lt;/p&gt;

&lt;p&gt;To make sure the setup was reasonably secure, I had to ask specific security questions and validate responses across different models and documentation sources.&lt;/p&gt;

&lt;p&gt;This was mainly an experiment, so there may still be issues lurking around.&lt;/p&gt;

&lt;p&gt;If you spot something questionable, I'd be happy to discuss it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Debug in This Setup?
&lt;/h3&gt;

&lt;p&gt;For this project I initially tried solving deployment issues exclusively through coding agents and chat interfaces.&lt;/p&gt;

&lt;p&gt;A few hours later...&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.amazonaws.com%2Fuploads%2Farticles%2Ft6m6ec37gfqfyp8b88u3.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.amazonaws.com%2Fuploads%2Farticles%2Ft6m6ec37gfqfyp8b88u3.png" alt=" " width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nothing worked.&lt;/p&gt;

&lt;p&gt;The setup involved Flutter, Docker, health checks, networking, and Coolify. Despite providing logs and screenshots, the agents kept insisting the problem was related to port configuration.&lt;/p&gt;

&lt;p&gt;It wasn't.&lt;/p&gt;

&lt;p&gt;Switching back to a more traditional debugging approach solved the issue in just a couple of attempts.&lt;/p&gt;

&lt;p&gt;For the younger readers, by "traditional debugging" I mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the official docs&lt;/li&gt;
&lt;li&gt;Find the relevant troubleshooting guide&lt;/li&gt;
&lt;li&gt;Inspect the logs&lt;/li&gt;
&lt;li&gt;Verify assumptions one by one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my case, the answer was sitting in the &lt;a href="https://coolify.io/docs/troubleshoot/applications/no-available-server" rel="noopener noreferrer"&gt;Coolify troubleshooting documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The application was failing its health checks.&lt;/p&gt;

&lt;p&gt;After fixing that configuration, everything worked immediately.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AI can generate solutions quickly. Understanding the system helps you identify the correct problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bonus: Feel free to check &lt;a href="https://github.com/neo2100/smart_shower_meter/pull/27" rel="noopener noreferrer"&gt;the commit history&lt;/a&gt; and pull request discussion to watch both me and several LLMs confidently debug the wrong thing for a while 😅&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;a href="https://smart-shower-meter.linguly.io" rel="noopener noreferrer"&gt;&lt;strong&gt;PWA&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;a href="https://github.com/neo2100/smart_shower_meter" rel="noopener noreferrer"&gt;&lt;strong&gt;Source Code&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📱 &lt;a href="https://github.com/neo2100/smart_shower_meter#try-it-yourself-%EF%B8%8F" rel="noopener noreferrer"&gt;&lt;strong&gt;Android Version&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback, bug reports, and contributions are always welcome.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>pwa</category>
      <category>githubcopilot</category>
      <category>coolify</category>
    </item>
  </channel>
</rss>
