<?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: Umair Shakoor</title>
    <description>The latest articles on DEV Community by Umair Shakoor (@unseenumair).</description>
    <link>https://dev.to/unseenumair</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%2F2905443%2F4e2ff77e-d743-43fc-b868-f4abf4c58f53.jpg</url>
      <title>DEV Community: Umair Shakoor</title>
      <link>https://dev.to/unseenumair</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/unseenumair"/>
    <language>en</language>
    <item>
      <title>Why I Built a Zero-Dependency Python REPL Alternative (`urepl`)</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Wed, 01 Jul 2026 07:48:11 +0000</pubDate>
      <link>https://dev.to/unseenumair/why-i-built-a-zero-dependency-python-repl-alternative-urepl-1cd1</link>
      <guid>https://dev.to/unseenumair/why-i-built-a-zero-dependency-python-repl-alternative-urepl-1cd1</guid>
      <description>&lt;p&gt;Hey DEV Community! &lt;/p&gt;

&lt;p&gt;Like many of you, I spend a lot of time jumping between terminal environments. Recently, while working with interactive shells, I found myself frustrated by how bare-bones the default Python REPL looks and behaves compared to the out-of-the-box Node.js experience. &lt;/p&gt;

&lt;p&gt;Instead of just dealing with it, I decided to build a lightweight, native solution and publish it to PyPI.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem with Bloat
&lt;/h3&gt;

&lt;p&gt;When looking at alternative REPLs, I noticed a trend: many require massive third-party package dependency trees. That adds latency to terminal load times and makes them heavy to run inside lean Docker containers or cloud environments.&lt;/p&gt;

&lt;p&gt;I wanted something clean. &lt;strong&gt;Zero dependencies.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Enter &lt;code&gt;native-tab-repl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;By leveraging pure Python built-in modules, I configured a setup that safely binds native autocompletion across platforms (handling Unix &lt;code&gt;readline&lt;/code&gt; and Windows fallback hooks gracefully) and injected a dynamic environment greeting banner.&lt;/p&gt;

&lt;p&gt;You can install it instantly on any system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;native-tab-repl

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And launch it with the entrypoint binary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;urepl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code is fully open-source and open for inspection. I'd love for you to try it out, check the underlying code logic, and let me know how we can make the terminal experience even better!&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/unseenumair/urepl" rel="noopener noreferrer"&gt;https://github.com/unseenumair/urepl&lt;/a&gt;&lt;br&gt;
🔗 &lt;strong&gt;PyPI:&lt;/strong&gt; &lt;a href="https://pypi.org/project/native-tab-repl/" rel="noopener noreferrer"&gt;https://pypi.org/project/native-tab-repl/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>tools</category>
      <category>cli</category>
    </item>
    <item>
      <title>Seriously ?</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Thu, 04 Jun 2026 06:16:36 +0000</pubDate>
      <link>https://dev.to/unseenumair/seriously--4d0l</link>
      <guid>https://dev.to/unseenumair/seriously--4d0l</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/unseenumair/i-got-tired-of-ai-fluff-on-my-social-feeds-so-im-building-a-micro-chrome-extension-to-fix-it-34ah" class="crayons-story__hidden-navigation-link"&gt;I got tired of AI fluff on my social feeds, so I’m building a micro Chrome extension to fix it&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/unseenumair" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F2905443%2F4e2ff77e-d743-43fc-b868-f4abf4c58f53.jpg" alt="unseenumair profile" class="crayons-avatar__image" width="735" height="735"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/unseenumair" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Umair Shakoor
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Umair Shakoor
                
              
              &lt;div id="story-author-preview-content-3815396" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/unseenumair" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F2905443%2F4e2ff77e-d743-43fc-b868-f4abf4c58f53.jpg" class="crayons-avatar__image" alt="" width="735" height="735"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Umair Shakoor&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/unseenumair/i-got-tired-of-ai-fluff-on-my-social-feeds-so-im-building-a-micro-chrome-extension-to-fix-it-34ah" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 4&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/unseenumair/i-got-tired-of-ai-fluff-on-my-social-feeds-so-im-building-a-micro-chrome-extension-to-fix-it-34ah" id="article-link-3815396"&gt;
          I got tired of AI fluff on my social feeds, so I’m building a micro Chrome extension to fix it
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/extensions"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;extensions&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/product"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;product&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/unseenumair/i-got-tired-of-ai-fluff-on-my-social-feeds-so-im-building-a-micro-chrome-extension-to-fix-it-34ah" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/unseenumair/i-got-tired-of-ai-fluff-on-my-social-feeds-so-im-building-a-micro-chrome-extension-to-fix-it-34ah#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            1 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>I got tired of AI fluff on my social feeds, so I’m building a micro Chrome extension to fix it</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Thu, 04 Jun 2026 02:12:29 +0000</pubDate>
      <link>https://dev.to/unseenumair/i-got-tired-of-ai-fluff-on-my-social-feeds-so-im-building-a-micro-chrome-extension-to-fix-it-34ah</link>
      <guid>https://dev.to/unseenumair/i-got-tired-of-ai-fluff-on-my-social-feeds-so-im-building-a-micro-chrome-extension-to-fix-it-34ah</guid>
      <description>&lt;p&gt;Every time I scroll through tech social media lately, I feel like I'm reading the exact same ChatGPT-generated templates over and over again.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"In today's fast-paced digital landscape, it is a testament to..."&lt;/em&gt; 🙄&lt;/p&gt;

&lt;p&gt;I wasted 20 minutes this morning skimming through long-form corporate posts that said absolutely nothing. It’s making it exhausting to find actual technical value, real developer insights, or organic engineering conversations.&lt;/p&gt;

&lt;p&gt;So, instead of just complaining about it, I decided to fix it. &lt;/p&gt;

&lt;p&gt;I'm building a lightweight, highly-focused &lt;strong&gt;Micro Chrome Extension&lt;/strong&gt; designed to sanitize social feeds (specifically LinkedIn and X). &lt;/p&gt;

&lt;h3&gt;
  
  
  How it works under the hood (conceptually):
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DOM Mutation Observer:&lt;/strong&gt; It listens for new posts as you infinite-scroll down your feed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heuristic/Regex Filtering:&lt;/strong&gt; It checks the DOM text contents for common AI-cliché triggers, engagement-bait formatting, and high-perplexity patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Action:&lt;/strong&gt; It automatically collapses or blurs out the flagged posts, keeping your feed strictly populated by human thoughts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I want to make sure it functions perfectly before launching it on the Web Store, and I'd love some feedback from fellow devs. &lt;/p&gt;

&lt;p&gt;If your timeline is also driving you crazy and you want to test the early beta or look at the logic, &lt;strong&gt;drop a comment below&lt;/strong&gt; or leave a reaction, and I'll send you the details!&lt;/p&gt;

&lt;p&gt;What are the specific ChatGPT trigger words that drive &lt;em&gt;you&lt;/em&gt; the most insane? Let me know so I can add them to the filter array. 👇&lt;/p&gt;

</description>
      <category>extensions</category>
      <category>productivity</category>
      <category>product</category>
      <category>ai</category>
    </item>
    <item>
      <title>How I Built Expiring Links With Zero Backend (React + TypeScript Only)</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Wed, 29 Apr 2026 02:12:35 +0000</pubDate>
      <link>https://dev.to/unseenumair/how-i-built-expiring-links-with-zero-backend-react-typescript-only-17cp</link>
      <guid>https://dev.to/unseenumair/how-i-built-expiring-links-with-zero-backend-react-typescript-only-17cp</guid>
      <description>&lt;p&gt;Most "expiring link" tools work the same way: generate a link, store the destination and expiry in a database, check the database on every click, redirect or block accordingly.&lt;/p&gt;

&lt;p&gt;That's the obvious approach. It's also the one that requires a backend, a database, server costs, and a breach surface.&lt;/p&gt;

&lt;p&gt;I had a constraint: React + TypeScript only, deployed on Vercel, no Node.js, no database, no backend whatsoever.&lt;/p&gt;

&lt;p&gt;So I had to find a different way.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Idea: Put Everything in the URL
&lt;/h2&gt;

&lt;p&gt;Instead of storing link data on a server, encode it directly into the URL itself.&lt;/p&gt;

&lt;p&gt;When a user creates an expiring link, the app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Takes the destination URL&lt;/li&gt;
&lt;li&gt;Takes the expiry timestamp (Unix ms)&lt;/li&gt;
&lt;li&gt;Combines them into a JSON object&lt;/li&gt;
&lt;li&gt;Encodes it with &lt;code&gt;btoa()&lt;/code&gt; (base64)&lt;/li&gt;
&lt;li&gt;Appends it as a URL parameter&lt;/li&gt;
&lt;li&gt;Shortens the full URL via TinyURL's API
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;destinationUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;expiryTimestamp&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;longUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://onetimelink.vercel.app/r?d=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Then shorten&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shortUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;shortenWithTinyURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;longUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When someone visits the short link, TinyURL expands it back to the long URL. The React app decodes the parameter client-side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URLSearchParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Invalid link&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Expired — show expiration screen&lt;/span&gt;
    &lt;span class="nf"&gt;setExpired&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Valid — redirect&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Malformed link&lt;/span&gt;
  &lt;span class="nf"&gt;setInvalid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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;No database query. No server call. No stored data anywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;p&gt;The link carries its own expiry inside itself. The server never needs to know anything. The decision to redirect or block happens entirely in the browser, client-side, on every click.&lt;/p&gt;

&lt;p&gt;This has some interesting properties:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero storage = zero breach surface.&lt;/strong&gt; There's no database of sensitive links sitting on a server somewhere. The data exists only in the URL you shared. If the URL is lost, the data is gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No server costs.&lt;/strong&gt; The entire product runs on Vercel's free tier. No compute happens server-side on link visits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Works offline (partially).&lt;/strong&gt; If someone has the URL cached, the expiry check still works because it's just a timestamp comparison — no network request needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Tradeoffs
&lt;/h2&gt;

&lt;p&gt;This approach has real limitations worth being honest about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;URL length.&lt;/strong&gt; Base64-encoding a JSON object adds characters. TinyURL handles the shortening, but the intermediate URL before shortening is long. If TinyURL's API rate limit is hit, the long URL is returned as a fallback — functional but not pretty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No server-side validation.&lt;/strong&gt; A determined user could decode the base64, modify the expiry timestamp, re-encode it, and create a "non-expiring" version of the link. For most use cases this doesn't matter — the threat model is casual oversharing, not adversarial attacks. But it's worth knowing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No analytics.&lt;/strong&gt; Since nothing is stored server-side, there's no way to know how many times a link was clicked. You get one-directional expiry enforcement, not a dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can't revoke early.&lt;/strong&gt; Once a link is created, it expires when it expires. There's no mechanism to kill it early because there's no server-side record to delete.&lt;/p&gt;




&lt;h2&gt;
  
  
  What It's Actually Good For
&lt;/h2&gt;

&lt;p&gt;This architecture is a good fit for the specific problem it solves: a freelancer or agency owner sharing something sensitive with a client, once, with a defined window.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Temporary login credentials for a handoff&lt;/li&gt;
&lt;li&gt;A staging environment link during a review period&lt;/li&gt;
&lt;li&gt;A private document with a natural end date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For these use cases, the limitations above don't matter. The client clicks once, gets what they need, and after the window closes the link is dead.&lt;/p&gt;

&lt;p&gt;For anything requiring analytics, multi-click tracking, or early revocation — you need a proper backend. This approach deliberately trades those features for zero storage and zero complexity.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React + TypeScript&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Vercel (free tier)&lt;/li&gt;
&lt;li&gt;TinyURL API (free tier, no auth required)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;btoa()&lt;/code&gt; / &lt;code&gt;atob()&lt;/code&gt; for encoding — built into every browser, no library needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total server infrastructure cost: $0.&lt;/p&gt;




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

&lt;p&gt;If you're building something where users need to share sensitive links temporarily, the approach above is a legitimate alternative to a full backend for certain use cases.&lt;/p&gt;

&lt;p&gt;The live implementation is at &lt;a href="https://onetimelink.vercel.app" rel="noopener noreferrer"&gt;onetimelink.vercel.app&lt;/a&gt; — free to use, no account needed.&lt;/p&gt;

&lt;p&gt;More on the architecture and the product direction on the &lt;a href="https://onetimelink.vercel.app/blog" rel="noopener noreferrer"&gt;OneTimeLink blog&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Still building in public. 408 organic users, $0 revenue, first paying customer is the only milestone that matters right now. Follow along if you want the unfiltered version.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>I Abandoned My Side Project. 210 Strangers Found It Anyway.</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Thu, 23 Apr 2026 04:30:24 +0000</pubDate>
      <link>https://dev.to/unseenumair/i-abandoned-my-side-project-210-strangers-found-it-anyway-202i</link>
      <guid>https://dev.to/unseenumair/i-abandoned-my-side-project-210-strangers-found-it-anyway-202i</guid>
      <description>&lt;p&gt;I built a tool in React + TypeScript, got frustrated with it, and moved on to other ideas.&lt;/p&gt;

&lt;p&gt;Three months later I opened Google Search Console out of curiosity.&lt;/p&gt;

&lt;p&gt;6,700 impressions. 283 clicks. Position 6.5 on Google.&lt;/p&gt;

&lt;p&gt;For a project I had completely abandoned.&lt;/p&gt;




&lt;h2&gt;
  
  
  The backstory
&lt;/h2&gt;

&lt;p&gt;This was my second SaaS attempt. I'd already failed once and was deep in the "just ship something" mindset.&lt;/p&gt;

&lt;p&gt;The idea was simple: URL shortener with expiry. When the time runs out, the link dies. No backend. No database. No auth.&lt;/p&gt;

&lt;p&gt;I built it, looked at TinyURL and Bitly, thought &lt;em&gt;"these already exist and they're worth $48M, I can't compete"&lt;/em&gt; — and moved on.&lt;/p&gt;

&lt;p&gt;That was a mistake in reasoning. More on that in a second.&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%2F4trs1m9094pvjc14m45n.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%2F4trs1m9094pvjc14m45n.png" alt="Google Search Console Performance ScreenShot of oneTimeLink" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The accidental traction
&lt;/h2&gt;

&lt;p&gt;When I came back to check on it, the keywords ranking were interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"expire link generator"&lt;/li&gt;
&lt;li&gt;"temporary link"&lt;/li&gt;
&lt;li&gt;"one time use link"&lt;/li&gt;
&lt;li&gt;"expiring link"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't brand searches. These are &lt;strong&gt;problem-aware searches.&lt;/strong&gt; People knew they had a problem and were looking for a solution.&lt;/p&gt;

&lt;p&gt;I set up GA4. Within 24 hours:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;45 users&lt;/li&gt;
&lt;li&gt;20% generated a link&lt;/li&gt;
&lt;li&gt;72.5% bounce rate (bad, but the intent traffic was real)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bounce rate told me the landing page was wrong. The usage rate told me the problem was real.&lt;/p&gt;




&lt;h2&gt;
  
  
  The technical decision that made this possible
&lt;/h2&gt;

&lt;p&gt;Here's the part developers find interesting.&lt;/p&gt;

&lt;p&gt;I had a constraint: no backend. I was building in React + TypeScript only, deployed on Vercel. No Node.js, no database, no server.&lt;/p&gt;

&lt;p&gt;So how do you build expiring links without storing anything?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encode everything in the URL itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a user creates a link with an expiry, the app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Takes the destination URL&lt;/li&gt;
&lt;li&gt;Takes the expiry timestamp&lt;/li&gt;
&lt;li&gt;Encodes both into a single URL-safe string&lt;/li&gt;
&lt;li&gt;Passes that to TinyURL's API to shorten it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When someone visits the link:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The short URL expands to the encoded long URL&lt;/li&gt;
&lt;li&gt;The app decodes the destination and expiry from the URL parameters&lt;/li&gt;
&lt;li&gt;Checks current timestamp against expiry&lt;/li&gt;
&lt;li&gt;If expired: shows expiration screen. If valid: redirects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No database query. No server call. No stored data. &lt;strong&gt;The link carries its own expiry inside itself.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simplified encoding logic&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;destinationUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;expiryTimestamp&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;longUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://onetimelink.vercel.app/r?d=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;encoded&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Then shorten via TinyURL API&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shortUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;shortenWithTinyURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;longUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This has a counterintuitive benefit: &lt;strong&gt;zero server storage = zero breach risk.&lt;/strong&gt; There's nothing to hack. The data lives in the URL and nowhere else.&lt;/p&gt;

&lt;p&gt;For freelancers sharing sensitive client links, that's not a technical footnote. That's the entire value proposition.&lt;/p&gt;




&lt;h2&gt;
  
  
  The validation mistake I almost made
&lt;/h2&gt;

&lt;p&gt;After seeing the traction, my first instinct was to look at Google Drive's sharing features and think &lt;em&gt;"people can already control access there, my expiry idea isn't a moat."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I almost pivoted away from it.&lt;/p&gt;

&lt;p&gt;Instead I sent &lt;strong&gt;21 DMs&lt;/strong&gt; to freelancers, founders, and CTOs asking one question:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"When you send a client a password or sensitive link — what do you actually do?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Three replies came back:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Djune (Founder &amp;amp; CEO):&lt;/strong&gt; &lt;em&gt;"I encrypt it in a message with a 1-hour life span with a PIN only they know."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uzair (Top Rated Freelancer):&lt;/strong&gt; &lt;em&gt;"I just send them a document with the credentials."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Waqas (CTO):&lt;/strong&gt; &lt;em&gt;"Yes, this is a real problem. I use 1Password sharing or split the info across two channels. If you're building something: focus on one-time access, expiry, and making it easy for non-technical clients."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That last reply rewrote my entire positioning.&lt;/p&gt;

&lt;p&gt;The insight wasn't "expiring links." The insight was &lt;strong&gt;"easy for non-technical clients."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every existing solution — 1Password sharing, encrypted messages, split credentials — requires the recipient to do something. Install an app. Enter a PIN. Have an account.&lt;/p&gt;

&lt;p&gt;OneTimeLink requires nothing from the recipient. They click. It works. Or it's expired.&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%2Fq624zbkyk6fr9346f4y7.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%2Fq624zbkyk6fr9346f4y7.png" alt="Google Analytics G4A overview for oneTimeLink" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I changed after validation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Repositioned headline:&lt;/strong&gt;&lt;br&gt;
Before: &lt;em&gt;"Share URLs that expire automatically"&lt;/em&gt;&lt;br&gt;
After: &lt;em&gt;"Share Sensitive Links Your Clients Can Actually Use"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bounce rate:&lt;/strong&gt; 72.5% → 51.9% after the copy change alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Average engagement:&lt;/strong&gt; 9s → 19s.&lt;/p&gt;

&lt;p&gt;Same product. Different words. Completely different results.&lt;/p&gt;




&lt;h2&gt;
  
  
  Current state: honest numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;210 organic users (zero paid traffic)&lt;/li&gt;
&lt;li&gt;26 users generated at least one link (12.4% activation)&lt;/li&gt;
&lt;li&gt;5 users attempted Pro waitlist signup&lt;/li&gt;
&lt;li&gt;Revenue: $0.00&lt;/li&gt;
&lt;li&gt;Paying customers: 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm building in public because I think the honest version of this journey is more useful than the highlight reel.&lt;/p&gt;

&lt;p&gt;The next milestone is the first paying user. Not the first hundred. Just one person who values this enough to pay $7/month.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set up analytics on day one.&lt;/strong&gt; I flew blind for months.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't confuse "utility" with "demand."&lt;/strong&gt; Useful ≠ something people will pay for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Talk to users before building features.&lt;/strong&gt; Three DM replies taught me more than three months of solo building.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The technical constraint became the product.&lt;/strong&gt; No backend wasn't a limitation. It became the trust signal: &lt;em&gt;"nothing stored on our servers, ever."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Try it / feedback welcome
&lt;/h2&gt;

&lt;p&gt;If you're a freelancer or developer who shares sensitive stuff with clients, I'd genuinely love brutal feedback:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://onetimelink.vercel.app" rel="noopener noreferrer"&gt;onetimelink.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What would make you actually pay $7/month for this?&lt;/p&gt;

&lt;p&gt;Drop it in the comments. I read everything.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Building OneTimeLink in public. Follow along if you want the unfiltered version.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Update — April 29, 2026
&lt;/h2&gt;

&lt;p&gt;A lot has changed since I first published this.&lt;/p&gt;

&lt;p&gt;The tool now has proper positioning, a pricing page, a waitlist, and 408 organic users in the last 28 days — still $0 revenue, still building.&lt;/p&gt;

&lt;p&gt;I've also started writing about the actual problem: why freelancers share passwords unsafely, what expiring links actually do, and how agencies handle sensitive client deliverables.&lt;/p&gt;

&lt;p&gt;If any of that is useful to you, it's all here: &lt;a href="https://onetimelink.vercel.app/blog" rel="noopener noreferrer"&gt;onetimelink.vercel.app/blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most read so far: &lt;a href="https://onetimelink.vercel.app/blog/best-expire-link-generator-for-freelancers" rel="noopener noreferrer"&gt;The Best Expire Link Generator for Freelancers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Still building in public. Still at $0. First paying customer is the only milestone that matters right now.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>startup</category>
      <category>webdev</category>
      <category>saas</category>
    </item>
    <item>
      <title>Git Commits</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Thu, 19 Mar 2026 12:49:58 +0000</pubDate>
      <link>https://dev.to/unseenumair/git-commits-45ci</link>
      <guid>https://dev.to/unseenumair/git-commits-45ci</guid>
      <description>&lt;p&gt;I always wonder that how those top engineers write the best commits meanwhile Le me who just commit "update" after doing tons of stuff 😂&lt;/p&gt;

&lt;p&gt;until I realized that a commit message should be satisfy :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If someone reads this commit, will they understand the change WITHOUT opening code?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's it . &lt;/p&gt;

&lt;p&gt;Congrats, you understand what is good commit message !&lt;/p&gt;

&lt;p&gt;but when to commit ?&lt;/p&gt;

&lt;p&gt;most people like me after doing random changes commit msg "final changes" , however the real rule is :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"if you can clearly explain what you have changed till now and it is a small change then commit otherwise don't"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you have added feature of file validation instead of waiting to finish whole project then commit. Just commit on that step with "add file validation"&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;PS : Hope, this make sense . I learned this the hard way, but you are lucky to know it easily 😁&lt;/p&gt;

</description>
      <category>git</category>
      <category>bash</category>
      <category>linux</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>I got tired of opening 3 different tools just to do simple image edits.</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Mon, 09 Mar 2026 10:08:18 +0000</pubDate>
      <link>https://dev.to/unseenumair/i-got-tired-of-opening-3-different-tools-just-to-do-simple-image-edits-536i</link>
      <guid>https://dev.to/unseenumair/i-got-tired-of-opening-3-different-tools-just-to-do-simple-image-edits-536i</guid>
      <description>&lt;p&gt;So I built &lt;strong&gt;BubbleKit&lt;/strong&gt; 🫧&lt;/p&gt;

&lt;p&gt;A tiny browser tool that lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🖼️ Remove backgrounds&lt;/li&gt;
&lt;li&gt;📏 Resize images&lt;/li&gt;
&lt;li&gt;⚡ Export WebP fast&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love honest feedback 🙏&lt;/p&gt;

</description>
      <category>startup</category>
      <category>buildinpublic</category>
      <category>youtube</category>
      <category>nanobanana</category>
    </item>
    <item>
      <title>Calculator using Vanilla JavaScript</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Thu, 11 Dec 2025 13:29:00 +0000</pubDate>
      <link>https://dev.to/unseenumair/calculator-using-vanilla-javascript-1mbm</link>
      <guid>https://dev.to/unseenumair/calculator-using-vanilla-javascript-1mbm</guid>
      <description>&lt;h2&gt;
  
  
  🚀 What I Practiced
&lt;/h2&gt;

&lt;p&gt;This is a practice project to improve my skills in JS eval and DOM.  &lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Project Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Calculator&lt;/strong&gt; is a great practice project for JS eval and DOM.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Practiced JS eval&lt;/li&gt;
&lt;li&gt;✅ Explored amazing array Functions like includes()&lt;/li&gt;
&lt;li&gt;✅ Learned JS DOM&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live&lt;/strong&gt; &lt;a href="https://unseenumair.github.io/calculator/" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source&lt;/strong&gt; &lt;a href="https://github.com/unseenumair/calculator" rel="noopener noreferrer"&gt;Code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PS:&lt;/strong&gt; Any suggestions or feedback? 🤔&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Umair's Coming Soon Portfolio</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Tue, 09 Dec 2025 06:53:53 +0000</pubDate>
      <link>https://dev.to/unseenumair/umairs-coming-soon-portfolio-29hm</link>
      <guid>https://dev.to/unseenumair/umairs-coming-soon-portfolio-29hm</guid>
      <description>&lt;h2&gt;
  
  
  🚀 What I Practiced
&lt;/h2&gt;

&lt;p&gt;This is a practice project to improve my skills in &lt;strong&gt;JavaScript&lt;/strong&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Project Overview
&lt;/h2&gt;

&lt;p&gt;You have not seen this kind of &lt;strong&gt;Coming Soon Portfolio&lt;/strong&gt; yet&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Practiced JavaScript&lt;/li&gt;
&lt;li&gt;✅ Explored Canvas&lt;/li&gt;
&lt;li&gt;✅ Learned Ui/Ux&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live&lt;/strong&gt; &lt;a href="https://unseenumair.github.io/" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source&lt;/strong&gt; &lt;a href="https://github.com/unseenumair/unseenumair.github.io/" rel="noopener noreferrer"&gt;Code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PS:&lt;/strong&gt; Any suggestions or feedback? 🤔&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>portfolio</category>
      <category>frontend</category>
      <category>programming</category>
    </item>
    <item>
      <title>𝗠𝗼𝘀𝘁 𝘁𝗲𝗮𝗰𝗵𝗲𝗿𝘀 𝗗𝗢𝗡’𝗧 𝗸𝗻𝗼𝘄 𝘁𝗵𝗶𝘀 𝗮𝗯𝗼𝘂𝘁 𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁'𝘀 finally {} 𝗯𝗹𝗼𝗰𝗸...</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Mon, 01 Dec 2025 13:25:40 +0000</pubDate>
      <link>https://dev.to/unseenumair/-finally--28id</link>
      <guid>https://dev.to/unseenumair/-finally--28id</guid>
      <description>&lt;h2&gt;
  
  
  try{} and catch{} are easy:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;try{} runs code (and prevents script crash on error)&lt;/li&gt;
&lt;li&gt;catch{} handles the error&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  But finally{} 𝗶𝘀 𝘁𝗵𝗲 𝗺𝗶𝘀𝘂𝗻𝗱𝗲𝗿𝘀𝘁𝗼𝗼𝗱 𝗼𝗻𝗲.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Most people say:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"finally{} always runs after try{} or catch{}."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Correct… 𝗯𝘂𝘁 𝗼𝗻𝗹𝘆 𝗵𝗮𝗹𝗳 𝘁𝗵𝗲 𝘁𝗿𝘂𝘁𝗵.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here’s the surprise:
&lt;/h3&gt;

&lt;p&gt;You 𝗱𝗼𝗻’𝘁 𝗻𝗲𝗲𝗱 finally{} to run code after try/catch in a simple block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The End&lt;/span&gt;&lt;span class="dl"&gt;"&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;You could just place console.log("The End") after everything.&lt;/p&gt;

&lt;p&gt;So… what’s the real purpose of finally{}?&lt;/p&gt;

&lt;h3&gt;
  
  
  𝗧𝗵𝗲 𝗿𝗲𝗮𝗹 𝗽𝗼𝘄𝗲𝗿 𝗮𝗽𝗽𝗲𝗮𝗿𝘀 𝗶𝗻𝘀𝗶𝗱𝗲 𝗳𝘂𝗻𝗰𝘁𝗶𝗼𝗻𝘀:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;

 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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="nx"&gt;error&lt;/span&gt;

 &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The End&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&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;Normally, when a function hits return, the remaining code never executes.&lt;/p&gt;

&lt;p&gt;But with finally{}, this line 𝘀𝘁𝗶𝗹𝗹 𝗿𝘂𝗻𝘀, even if both try and catch returned.&lt;/p&gt;

&lt;p&gt;That's the true magic of finally{} —&lt;/p&gt;

&lt;p&gt;It 𝗮𝗹𝘄𝗮𝘆𝘀 executes, even after a return, making it perfect for cleanup, logs, closing connections, releasing resources, etc.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I was confused about this early on, but once it clicked, it made advanced JS flow much clearer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;𝗣𝗦: Which JavaScript concept confused you the most when you first learned it?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>discuss</category>
    </item>
    <item>
      <title>🎉 Mini Game Project Completed: Tic Tac Toe! 🕹️</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Mon, 24 Nov 2025 14:42:33 +0000</pubDate>
      <link>https://dev.to/unseenumair/mini-game-project-completed-tic-tac-toe-51in</link>
      <guid>https://dev.to/unseenumair/mini-game-project-completed-tic-tac-toe-51in</guid>
      <description>&lt;p&gt;I'm excited to share that I've completed a &lt;strong&gt;Mini Game Project&lt;/strong&gt; – &lt;strong&gt;Tic Tac Toe&lt;/strong&gt;!  &lt;/p&gt;

&lt;p&gt;It might sound simple, but small projects like this are essential for building a &lt;strong&gt;strong foundation&lt;/strong&gt; as a Frontend Developer 💻. They prepare you for bigger, more complex projects.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;Most web-based Tic Tac Toe games lack a clean, user-friendly UI – so I decided to create one! 🎨  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fun fact: It's a &lt;strong&gt;2-player game&lt;/strong&gt;, perfect to play with friends 👯
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 &lt;strong&gt;Try it out and share your feedback or suggestions!&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Preview:&lt;/strong&gt; &lt;a href="https://us-tictactoe.netlify.app/" rel="noopener noreferrer"&gt;us-tictactoe.netlify.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source Code:&lt;/strong&gt; &lt;a href="https://github.com/unseenumair/games/tree/main/TicTacToe" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>tictactoe</category>
      <category>beginners</category>
      <category>100daysofcode</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>No other Icons Library Needed 🥶</title>
      <dc:creator>Umair Shakoor</dc:creator>
      <pubDate>Fri, 21 Nov 2025 02:46:49 +0000</pubDate>
      <link>https://dev.to/unseenumair/no-other-icons-library-needed-4500</link>
      <guid>https://dev.to/unseenumair/no-other-icons-library-needed-4500</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Iconify&lt;/strong&gt; is here.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It is &lt;strong&gt;OpenSource&lt;/strong&gt; All in one Modern Ui Icons library.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  They also have a CDN :
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://code.iconify.design/iconify-icon/3.0.0/iconify-icon.min.js"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Just Paste this script in html head tag&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Copy Web Components from
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;a href="https://icon-sets.iconify.design/" rel="noopener noreferrer"&gt;Iconify&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;by searching for your desired icon. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Then, paste that  tag in your body , whereever you wanna use it and Boom 🤯.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tip :
&lt;/h3&gt;

&lt;p&gt;Use CSS &lt;strong&gt;Font-Size&lt;/strong&gt; to cusomtize the size of the icon and you can also do that by giving width &amp;amp; height to iconify-icon tag.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Have you any suggestions or feedback?&lt;br&gt;
Tell us in comments, I love it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;🫠 Like &amp;amp; Follow us - If you want these kind of more things...&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>iconify</category>
      <category>webdev</category>
      <category>100daysofcode</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
