<?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: Yahia Hammadieh</title>
    <description>The latest articles on DEV Community by Yahia Hammadieh (@yhammadieh).</description>
    <link>https://dev.to/yhammadieh</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%2F4095799%2Fa59807d7-e922-4e9a-8f81-e85078154a48.jpg</url>
      <title>DEV Community: Yahia Hammadieh</title>
      <link>https://dev.to/yhammadieh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yhammadieh"/>
    <language>en</language>
    <item>
      <title>Why I Built 89+ Client-Side Developer Tools with Astro and Vanilla JS</title>
      <dc:creator>Yahia Hammadieh</dc:creator>
      <pubDate>Wed, 26 Aug 2026 16:22:18 +0000</pubDate>
      <link>https://dev.to/yhammadieh/why-i-built-89-client-side-developer-tools-with-astro-and-vanilla-js-mi6</link>
      <guid>https://dev.to/yhammadieh/why-i-built-89-client-side-developer-tools-with-astro-and-vanilla-js-mi6</guid>
      <description>&lt;p&gt;How many times have you needed to format a JSON payload, test a regex string, inspect a JWT, or run a quick SQL query, only to land on an ad-heavy website that sends your data to a backend server?&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Compare Value Web&lt;/strong&gt; — a suite of &lt;strong&gt;89+ developer sandboxes, sysadmin generators, and price calculators&lt;/strong&gt; running 100% in-memory in your browser.&lt;/p&gt;

&lt;p&gt;🌐 &lt;a href="https://compare-value.com" rel="noopener noreferrer"&gt;https://compare-value.com&lt;/a&gt;&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%2F2oa2v51ph09pdw4fik8g.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%2F2oa2v51ph09pdw4fik8g.png" alt=" " width="799" height="382"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ What's Inside the Workstation?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Sandboxes:&lt;/strong&gt; In-browser SQLite query studio, MongoDB document runner, WebSocket tester, and REST API playground.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DevOps &amp;amp; SysAdmin:&lt;/strong&gt; Multi-stage Dockerfile builders, Nginx reverse proxy generators, systemd unit generators, and IPv4 subnet calculators.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Generation:&lt;/strong&gt; cURL-to-multilanguage converters, JSON to TypeScript/Zod/Pydantic/Go structs, and SVG-to-JSX optimizers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global Command Palette:&lt;/strong&gt; &lt;code&gt;Ctrl + K&lt;/code&gt; provides instant keyboard navigation across all 89+ tools, with starred tools persisted locally.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚡ Performance &amp;amp; Privacy Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│              COMPARE VALUE WEB ARCHITECTURE              │
│                                                         │
│  [Astro 5 SSG] ──► [Cloudflare Edge CDN] ──► [Browser] │
│                                                   │     │
│                       ┌───────────────────────────┴──┐  │
│                       ▼                              ▼  │
│              [Vanilla JS Engines]            [localStorage]
│              • WebAssembly SQLite            • Pinned Tools
│              • In-Memory Parsers             • Recent Tray
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Zero Server Overhead
&lt;/h3&gt;

&lt;p&gt;The static site is generated with &lt;strong&gt;Astro&lt;/strong&gt; and served through &lt;strong&gt;Cloudflare Pages&lt;/strong&gt; edge infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Client-Side Privacy
&lt;/h3&gt;

&lt;p&gt;Tools execute within Web Workers or directly in browser memory.&lt;/p&gt;

&lt;p&gt;Sensitive data such as API tokens, API payloads, and SQL queries are processed locally and are not sent to a backend server.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. No Heavy Framework Overhead
&lt;/h3&gt;

&lt;p&gt;The tools are built with lightweight, modular &lt;strong&gt;Vanilla JavaScript&lt;/strong&gt;, keeping the client-side footprint small without unnecessary framework overhead.&lt;/p&gt;

&lt;p&gt;There is also &lt;strong&gt;no tracking analytics&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  📱 The Mobile Companion
&lt;/h2&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%2Fu0g5elvzap38i7h7oc27.jpg" 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%2Fu0g5elvzap38i7h7oc27.jpg" alt=" " width="736" height="1444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alongside the web platform, I built an offline-first &lt;strong&gt;Flutter companion app&lt;/strong&gt; for physical price normalization and supermarket budget management.&lt;/p&gt;

&lt;p&gt;Key features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Cost-Per-Unit:&lt;/strong&gt; Compare prices across volume, mass, and unit counts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-Device OCR:&lt;/strong&gt; Uses Google ML Kit to scan supermarket shelf price tags directly with the camera.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌐 Explore the Workstation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Web Tools:&lt;/strong&gt; &lt;a href="https://compare-value.com" rel="noopener noreferrer"&gt;https://compare-value.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android App:&lt;/strong&gt; &lt;a href="https://play.google.com/store/apps/details?id=com.valuecompare.value_compare" rel="noopener noreferrer"&gt;https://play.google.com/store/apps/details?id=com.valuecompare.value_compare&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try the in-browser SQLite studio or cURL generator, and let me know what utilities you would like to see next!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>astro</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Social Link Vault AI (Mobile &amp; Architecture Focus)</title>
      <dc:creator>Yahia Hammadieh</dc:creator>
      <pubDate>Wed, 26 Aug 2026 16:16:55 +0000</pubDate>
      <link>https://dev.to/yhammadieh/social-link-vault-ai-mobile-architecture-focus-4ggg</link>
      <guid>https://dev.to/yhammadieh/social-link-vault-ai-mobile-architecture-focus-4ggg</guid>
      <description>&lt;p&gt;Most bookmark and read-it-later tools suffer from the same pattern: bloated web dashboards, heavy cloud dependencies, and subscriptions for basic search features.&lt;/p&gt;

&lt;p&gt;I wanted a mobile solution that prioritizes &lt;strong&gt;capture speed, offline performance, and complete local privacy&lt;/strong&gt;. Here is how I designed and built &lt;strong&gt;Social Link Vault AI&lt;/strong&gt; using Flutter and SQLite FTS5.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Technical Architecture
&lt;/h2&gt;

&lt;p&gt;The app is built on clean architecture principles, separating presentation, domain, and local data persistence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Storage:&lt;/strong&gt; Local SQLite database via &lt;code&gt;sqflite&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search Engine:&lt;/strong&gt; Full-Text Search 5 (&lt;code&gt;FTS5&lt;/code&gt;) virtual tables for real-time, zero-latency queries across thousands of items.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Management:&lt;/strong&gt; BLoC / Cubit for deterministic reactive UI states.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Layer:&lt;/strong&gt; Google Gemini API (&lt;code&gt;google_generative_ai&lt;/code&gt;) for automated summarization, topic tagging, and category routing.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SQLite FTS5 Virtual Table Configuration&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'''
  CREATE VIRTUAL TABLE IF NOT EXISTS links_fts USING fts5(
    title,
    url,
    description,
    ai_summary,
    notes,
    tags,
    content='&lt;/span&gt;&lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="s"&gt;',
    content_rowid='&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="s"&gt;'
  );
'''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚡ Key Engineering Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Zero-Friction Capture &amp;amp; URL Sanitization
&lt;/h3&gt;

&lt;p&gt;When sharing a URL from social apps, links are often bloated with tracking parameters such as &lt;code&gt;utm_*&lt;/code&gt;, &lt;code&gt;fbclid&lt;/code&gt;, &lt;code&gt;igshid&lt;/code&gt;, and &lt;code&gt;ref&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The ingestion router automatically strips this query noise before writing the URL to the database:&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="kt"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;sanitizeUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;rawUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rawUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;cleanParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;queryParameters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;removeWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'utm_'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'fbclid'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'igshid'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'si'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'ref'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;queryParameters:&lt;/span&gt; &lt;span class="n"&gt;cleanParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&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;h3&gt;
  
  
  2. Zero-Permission Storage Compliance
&lt;/h3&gt;

&lt;p&gt;Instead of requesting broad Android media storage permissions such as &lt;code&gt;READ_MEDIA_IMAGES&lt;/code&gt;, the app relies strictly on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The native Android System Photo Picker.&lt;/li&gt;
&lt;li&gt;The Storage Access Framework (SAF) for exports.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps the app's permission footprint minimal while still supporting backup and media-related workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Biometrics &amp;amp; On-Device Security
&lt;/h3&gt;

&lt;p&gt;Sensitive text snippets, such as API keys, recovery phrases, and confidential notes, are encrypted and masked with &lt;code&gt;••••••••••••&lt;/code&gt; by default.&lt;/p&gt;

&lt;p&gt;Unmasking requires biometric authentication, such as Fingerprint or PIN, backed by hardware keystores through &lt;code&gt;flutter_secure_storage&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Try the Open Beta
&lt;/h2&gt;

&lt;p&gt;The app is currently in Open Beta on Google Play:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://play.google.com/store/apps/details?id=com.yzh.social_link_vault_ai" rel="noopener noreferrer"&gt;Download / Test on Google Play&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;I'd love feedback from fellow Flutter developers on the capture UX, local search indexing speed, and offline backup flow&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%2Fsfzsx6nf3376zoxm6tl6.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%2Fsfzsx6nf3376zoxm6tl6.png" alt=" " width="800" height="1433"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>mobile</category>
      <category>sqlite</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
