<?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: CodeLong888</title>
    <description>The latest articles on DEV Community by CodeLong888 (@codelong888).</description>
    <link>https://dev.to/codelong888</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%2F3891284%2F7cd6aec6-b3b2-4745-b86e-7d2bec7fe714.png</url>
      <title>DEV Community: CodeLong888</title>
      <link>https://dev.to/codelong888</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codelong888"/>
    <language>en</language>
    <item>
      <title>Is your launch-site backlink actually dofollow? I checked 24 platforms</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Sat, 10 Oct 2026 01:15:47 +0000</pubDate>
      <link>https://dev.to/codelong888/is-your-launch-site-backlink-actually-dofollow-i-checked-24-platforms-1jb7</link>
      <guid>https://dev.to/codelong888/is-your-launch-site-backlink-actually-dofollow-i-checked-24-platforms-1jb7</guid>
      <description>&lt;p&gt;Every launch site promises you a backlink. Fewer of them say what kind.&lt;/p&gt;

&lt;p&gt;I wanted to know what you actually get, so on 10 October 2026 I opened a live listing page on 24 launch and directory sites and read the &lt;code&gt;rel&lt;/code&gt; attribute on the link that points at the listed product. Nothing fancy, just the HTML the server sends.&lt;/p&gt;

&lt;p&gt;Disclosure up front: I run &lt;a href="https://yourhack.ai" rel="noopener noreferrer"&gt;yourhack.ai&lt;/a&gt;, which is one of the sites in the comparison. Our own listing links are nofollow by default and turn followed when you link back or pay, so I'm not pretending to be neutral, just showing my working.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I found
&lt;/h2&gt;

&lt;p&gt;On the 23 sites where I could read the markup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;13&lt;/strong&gt; served a plain, followed link on the listing I opened&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;9&lt;/strong&gt; used &lt;code&gt;rel="nofollow"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1&lt;/strong&gt; used &lt;code&gt;rel="ugc"&lt;/code&gt; (Product Hunt, from my July check; it blocked my requests this time)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more interesting part is how many "dofollow" promises come with a condition attached:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Site&lt;/th&gt;
&lt;th&gt;Free link&lt;/th&gt;
&lt;th&gt;The condition&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DevHunt&lt;/td&gt;
&lt;td&gt;nofollow&lt;/td&gt;
&lt;td&gt;Their FAQ: "Links on free listings are nofollow; paid launches get a permanent dofollow link."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uneed&lt;/td&gt;
&lt;td&gt;followed, conditional&lt;/td&gt;
&lt;td&gt;Free plan ties the dofollow link to an upvote score of 20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenHunts&lt;/td&gt;
&lt;td&gt;nofollow on 2 of 3 listings&lt;/td&gt;
&lt;td&gt;"Dofollow backlink if top 3" on the free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Launch&lt;/td&gt;
&lt;td&gt;nofollow&lt;/td&gt;
&lt;td&gt;Free tier lists two conditions for dofollow: a top 3 daily ranking and displaying their badge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TinyLaunch&lt;/td&gt;
&lt;td&gt;followed on the pages I opened&lt;/td&gt;
&lt;td&gt;Free tier promises a backlink only for top 3 products&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Peerlist Launchpad&lt;/td&gt;
&lt;td&gt;couldn't read it (client-rendered)&lt;/td&gt;
&lt;td&gt;Their FAQ: only the top 5 projects of the week get a backlink&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show HN&lt;/td&gt;
&lt;td&gt;mostly nofollow&lt;/td&gt;
&lt;td&gt;27 of 29 titles on /shownew were nofollow; the one I opened from /show was not&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fazier&lt;/td&gt;
&lt;td&gt;followed on paid launches&lt;/td&gt;
&lt;td&gt;Free tier requires a link back to Fazier on your site&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So "free dofollow backlink" very often means "free, if you win, pay, or link back". That's a fair trade, it just isn't the headline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check it yourself in 10 seconds
&lt;/h2&gt;

&lt;p&gt;Open your listing, view source, and search for your domain. Or from a terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sL&lt;/span&gt; &lt;span class="s2"&gt;"https://example-directory.com/your-listing"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oiE&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;a [^&amp;gt;]*yourdomain\.com[^&amp;gt;]*&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the tag has &lt;code&gt;nofollow&lt;/code&gt;, &lt;code&gt;ugc&lt;/code&gt; or &lt;code&gt;sponsored&lt;/code&gt; in its &lt;code&gt;rel&lt;/code&gt;, search engines are asked not to count it as an endorsement. No &lt;code&gt;rel&lt;/code&gt;, or only &lt;code&gt;noopener&lt;/code&gt; / &lt;code&gt;noreferrer&lt;/code&gt;, means it's followed.&lt;/p&gt;

&lt;p&gt;Two gotchas I hit:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Some sites render links with JavaScript&lt;/strong&gt;, so the HTML from curl has no link at all. Crawlers often see the same thing on their first pass.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirect links.&lt;/strong&gt; One site's "View tool" button points at its own short link that 302s to you with a &lt;code&gt;?ref=&lt;/code&gt; tag. The anchor itself had no nofollow, but it isn't a direct link to your domain.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A free checker, because I got tired of doing this by hand
&lt;/h2&gt;

&lt;p&gt;I turned the check into a small free tool: &lt;a href="https://yourhack.ai/dofollow-checker" rel="noopener noreferrer"&gt;Dofollow Backlink Checker&lt;/a&gt;. Paste the page that links to you plus your domain, and it lists every link to your site with its anchor text and &lt;code&gt;rel&lt;/code&gt;, and flags pages that are noindex or nofollow as a whole.&lt;/p&gt;

&lt;p&gt;Two siblings came out of the same work, for the day before you launch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://yourhack.ai/social-preview-checker" rel="noopener noreferrer"&gt;Social Preview Checker&lt;/a&gt;: how your link card looks on X, LinkedIn, Facebook and Slack, and which Open Graph tags are missing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://yourhack.ai/launch-readiness-checker" rel="noopener noreferrer"&gt;Launch Readiness Checker&lt;/a&gt;: HTTPS, title, meta description, share image, favicon, viewport, H1, noindex, canonical and server response time, with a fix for each miss&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full comparison of all 25 sites (cost, account, link type and stated review time, with every URL I opened) is here: &lt;a href="https://yourhack.ai/submit-your-tool" rel="noopener noreferrer"&gt;Where to submit your startup: Product Hunt alternatives compared&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;A backlink from a launch site is a bonus, not the point. The same human visitors click a nofollow link as a followed one. Pick the two or three sites whose audience overlaps with your users, write a real description for each, and then check what you got instead of trusting the pricing page.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>startup</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Where to list a vibe-coded app in 2026: launch sites compared</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Thu, 01 Oct 2026 02:06:38 +0000</pubDate>
      <link>https://dev.to/codelong888/where-to-list-a-vibe-coded-app-in-2026-launch-sites-compared-ph6</link>
      <guid>https://dev.to/codelong888/where-to-list-a-vibe-coded-app-in-2026-launch-sites-compared-ph6</guid>
      <description>&lt;p&gt;You built the thing in a weekend with Cursor or Lovable. Now you need somewhere to put it, and every "best launch sites" list you find is either two years old or written by one of the sites on it.&lt;/p&gt;

&lt;p&gt;Disclosure first: I run VibeKing, which is one of those sites. On September 30 we went through 21 launch directories and wrote down what each one asks for, using only what the directory states on its own pages. This post is the short version of that guide. VibeKing is in the table too, and I'll get to it near the end. Nothing here is ranked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free is rarely free
&lt;/h2&gt;

&lt;p&gt;Almost every launch site has a free tier. What changes is what you pay with instead of money. In practice it's one of three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time.&lt;/strong&gt; The free queue can be long. OpenHunts' free queue was about 60 weeks when we checked. Uneed assigns free launches a date that can be up to five months out. AlternativeTo says at least a few months.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A link on your site.&lt;/strong&gt; LaunchIgniter, Smol Launch, Startup Fame, Fazier and Dang.ai all want their badge or a link back before the free listing counts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Votes.&lt;/strong&gt; Uneed needs an upvote score of 10 to keep a free launch published. Awesome Indie and Uneed both tie extra perks to 20 upvotes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither is a scam. You just need to decide upfront which of these you can actually afford. A two-person team with a launch date can't wait 60 weeks. Someone with no audience will struggle on a board that runs on votes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free and immediate: Show HN, Product Hunt, Peerlist
&lt;/h2&gt;

&lt;p&gt;These three cost nothing and don't make you wait.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Show HN&lt;/strong&gt; has no queue and nothing to buy. The catch is in the rules: it has to be something people can try right now. Landing pages and waitlists get sent elsewhere. Drop the signup wall if you can, and stay in the thread to answer questions. That's half of what Show HN is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Product Hunt&lt;/strong&gt; is free, and you pick the day. Product Hunt's own advice is that the best day is "the day on which you're most prepared". It also says company accounts aren't allowed, so launch as a person. It's a same-day race, so it rewards people who show up with a network and spend the whole day replying to comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Peerlist Launchpad&lt;/strong&gt; opens every Monday. It needs a verified Peerlist profile, so it suits you best if you already have one.&lt;/p&gt;

&lt;p&gt;If your app is usable today, start here. Most vibe-coded apps are small, free and quick to try, and that's exactly what these three reward.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheap paid tiers
&lt;/h2&gt;

&lt;p&gt;If you need a date and can't wait in a queue, the one-time tiers are cheap. These were the listed prices on September 30:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Directory&lt;/th&gt;
&lt;th&gt;Cheapest paid option&lt;/th&gt;
&lt;th&gt;Free tier, as stated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenHunts&lt;/td&gt;
&lt;td&gt;$9.90 Premium ($19 list)&lt;/td&gt;
&lt;td&gt;~60-week queue, or add their badge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LaunchIgniter&lt;/td&gt;
&lt;td&gt;$12 Basic&lt;/td&gt;
&lt;td&gt;date not guaranteed, badge required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uneed&lt;/td&gt;
&lt;td&gt;$14.99 Fast-track ($29.99 to pick your date)&lt;/td&gt;
&lt;td&gt;up to 5 months&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BuiltByIndies&lt;/td&gt;
&lt;td&gt;$15 Premium&lt;/td&gt;
&lt;td&gt;next launch week with space&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Smol Launch&lt;/td&gt;
&lt;td&gt;$19 Premium&lt;/td&gt;
&lt;td&gt;50 verified slots a week, badge required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fazier&lt;/td&gt;
&lt;td&gt;$29 Lite ($39 list)&lt;/td&gt;
&lt;td&gt;within 30 days, link required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Launch Llama&lt;/td&gt;
&lt;td&gt;$39 Instant Launch&lt;/td&gt;
&lt;td&gt;about 4 weeks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TinyLaunch&lt;/td&gt;
&lt;td&gt;$39 Premium&lt;/td&gt;
&lt;td&gt;"standard queue"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microlaunch&lt;/td&gt;
&lt;td&gt;$39 with code ($49 list)&lt;/td&gt;
&lt;td&gt;not stated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DevHunt&lt;/td&gt;
&lt;td&gt;$49 paid launch&lt;/td&gt;
&lt;td&gt;not stated&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two more are priced like subscriptions: SaaSHub's featured listing is $99 a month, and Startup Fame's Highlight is $19 a month. AlternativeTo has a $5 priority review, but it doesn't guarantee approval.&lt;/p&gt;

&lt;p&gt;Spending $10 to $40 to skip a five-month wait is often a reasonable trade. Spending $99 a month on a side project with no revenue usually isn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Match the site to what you built
&lt;/h2&gt;

&lt;p&gt;This matters more than price, and it's the part most lists skip.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DevHunt&lt;/strong&gt; only takes developer tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There's An AI For That&lt;/strong&gt; and &lt;strong&gt;Dang.ai&lt;/strong&gt; are for AI tools. TAAFT has no free tier; review costs $49. Dang.ai's free tier can take up to 4 weeks and wants a link back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SaaSHub&lt;/strong&gt; and &lt;strong&gt;AlternativeTo&lt;/strong&gt; work best when your app replaces something people already search for ("alternative to Notion"). A brand-new category won't get much from them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BetaList&lt;/strong&gt; explicitly rejects vercel.app, netlify.app and herokuapp.com URLs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last one catches a lot of vibe-coded apps. If yours still lives on a free subdomain, buy a domain before you launch anywhere. It costs about as much as one paid launch, and whatever you earn from listings then points at something you own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read audience numbers as marketing
&lt;/h2&gt;

&lt;p&gt;Some directories publish their reach and most don't. The ones that do are self-reported: There's An AI For That says 5M+ monthly users, Uneed says 90K monthly visitors and 26,000 newsletter subscribers, and Microlaunch says 30k+ unique visitors a month. Launch Llama's pricing page quotes two different newsletter sizes for the same list. I'm not saying any of these are false. They're marketing numbers, so give them the weight you'd give any marketing number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where VibeKing fits
&lt;/h2&gt;

&lt;p&gt;VibeKing is a free directory for indie and AI-built apps and side projects. It has about 2,600 listings right now. A person reviews every free submission, usually within a few days. After that, the listing goes live once you add a small badge to your site, so it's in the "link on your site" group above. If you don't want the badge or the wait, there's a one-time Fast Track at $29 (a launch price; it goes to $99 later) that goes live straight away.&lt;/p&gt;

&lt;p&gt;I'm obviously biased. Treat it as one more stop in the queue phase, not a replacement for Show HN or Product Hunt.&lt;/p&gt;

&lt;h2&gt;
  
  
  A plan that doesn't eat your month
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Before anything:&lt;/strong&gt; a custom domain, a version people can try without a signup, and a quick check of your homepage basics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Launch week:&lt;/strong&gt; pick one big free launch, Show HN or Product Hunt, and actually be there all day to answer people.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same week:&lt;/strong&gt; join two or three free queues that match what you built. They'll come up over the next weeks and months, which beats one spike that drops to zero by Thursday.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Only if you need a date:&lt;/strong&gt; pay for one cheap tier, not five.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After launch:&lt;/strong&gt; open your own listing pages and check they're live and say what you think they say. Directories change their terms, and the listing you got may not match the pricing page you read.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Prices and queues move every month. The full table, with a separate guide for each directory and links to its sources, is at &lt;a href="https://vibeking.fun/launch" rel="noopener noreferrer"&gt;vibeking.fun/launch&lt;/a&gt;. It's dated, so check the date before you rely on any number.&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>startup</category>
      <category>sideprojects</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I gave a new AI model my browser racing game and one sentence: "make it AAA quality"</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Wed, 02 Sep 2026 16:59:24 +0000</pubDate>
      <link>https://dev.to/codelong888/i-gave-a-new-ai-model-my-browser-racing-game-and-one-sentence-make-it-aaa-quality-4nl</link>
      <guid>https://dev.to/codelong888/i-gave-a-new-ai-model-my-browser-racing-game-and-one-sentence-make-it-aaa-quality-4nl</guid>
      <description>&lt;p&gt;Four days ago my side project &lt;a href="https://mylambo.money" rel="noopener noreferrer"&gt;mylambo.money&lt;/a&gt; got a browser racing game: a 3D supercar with 25 ad panels, and a one-lap race where you start last against the projects on the leaderboard. It worked. It also looked like a tech demo.&lt;/p&gt;

&lt;p&gt;Today I opened Claude Code on the new Claude Fable 5.1 model and typed one sentence: &lt;strong&gt;"make it AAA quality."&lt;/strong&gt; I did not write a line of code. This is what happened, with the numbers from the session.&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%2Fod87gc2ul7n7r379ec3w.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%2Fod87gc2ul7n7r379ec3w.jpg" alt="Before and after, same lap: the day version from four days ago on the left, tonight's build on the right" width="799" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The starting point
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One file, &lt;code&gt;race.js&lt;/code&gt;, 2,028 lines, vanilla ES modules, three.js r180 vendored, no build step (it is a Cloudflare Pages site).&lt;/li&gt;
&lt;li&gt;8 rivals on rails. No collisions, no AI.&lt;/li&gt;
&lt;li&gt;The player car was a point with a heading and a speed. No slip, no body roll. The wheels did not even spin: the hook was called every frame but nothing ever set it.&lt;/li&gt;
&lt;li&gt;A text 3-2-1 countdown, while the start gantry had five red lights modelled on it that were never used.&lt;/li&gt;
&lt;li&gt;One synthesised music loop, no engine sound.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What the model did first: split the file
&lt;/h2&gt;

&lt;p&gt;Before touching a feature it refactored the one file into 14 modules, none over 800 lines, with a shared &lt;code&gt;state&lt;/code&gt; object and an &lt;code&gt;events&lt;/code&gt; bus as the contract between them (&lt;code&gt;physics&lt;/code&gt;, &lt;code&gt;rivals&lt;/code&gt;, &lt;code&gt;camera&lt;/code&gt;, &lt;code&gt;audio&lt;/code&gt;, &lt;code&gt;fx&lt;/code&gt;, &lt;code&gt;env&lt;/code&gt;, &lt;code&gt;hud&lt;/code&gt;, &lt;code&gt;track&lt;/code&gt;, and so on). Then it spawned five agents, four of them in parallel, one per module group. The four that finished reported 865,875 tokens between them. The fifth hit the account's session limit mid-sentence; its last log line was "Now I have the full picture. Let me make the track.js changes first." It came back three hours later and did.&lt;/p&gt;

&lt;p&gt;Nothing could be checked in a browser during the build. Headless Chrome software-renders WebGL on the CPU and has frozen this machine before, so every module was verified with &lt;code&gt;node --check&lt;/code&gt;, an import resolver, and a node harness that mapped &lt;code&gt;three&lt;/code&gt; to the vendored build and drove the real physics through full laps. 37 assertions for the car, 173 for the seams between modules (a second harness that mounts the real game entry with a stubbed DOM and runs two races, mute, resize, close and re-mount).&lt;/p&gt;

&lt;h2&gt;
  
  
  The car
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Velocity-vector physics instead of a point: lateral grip that turns slide into forward speed, a handbrake for drifting (Space), six gears with a torque dip on upshift, nitro (Shift) that refills in a slipstream.&lt;/li&gt;
&lt;li&gt;Wheels that actually spin and steer. This took measuring the glTF: the wheel nodes are empty groups with the hub at the origin, the tyre is 0.768 m in diameter, and the front axles are yawed 30 degrees in the asset, so each wheel gets a pivot that undoes that before it spins.&lt;/li&gt;
&lt;li&gt;Body roll and pitch on a pivot under the car, so the 25 sponsor plates lean with it.&lt;/li&gt;
&lt;li&gt;A clean lap is about 15.6 seconds. The scoring API refuses anything under 9, and it was not touched.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The rivals
&lt;/h2&gt;

&lt;p&gt;Each rival is the same car flattened into four merged buffers (paint, trim, metal, lights), four draw calls instead of about twenty. They now brake for corners using the circuit's own curvature (a 900-sample radius table built once), change lanes to pass slower cars, block the player about 30% of the time when directly ahead, and rubber-band mildly so the field stays within sight. Pole still laps in about 16.1 s, so a clean lap from the back wins by a dozen metres.&lt;/p&gt;

&lt;h2&gt;
  
  
  The night
&lt;/h2&gt;

&lt;p&gt;The first pass kept daylight, and my verdict when I saw the before/after video was blunt: I did not see any upgrade at all. Fair. The stadium was already there four days ago. So the second pass turned the sun off.&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%2Fkzkkr8m35zg9iif3kqcj.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%2Fkzkkr8m35zg9iif3kqcj.jpg" alt="The night race: floodlit circuit, neon hoardings, brake lights" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A pool of six spotlights re-targeted every frame to the six floodlight towers nearest the car (two on phones), with additive beam cones for all towers in one draw call, and pooled lens flares.&lt;/li&gt;
&lt;li&gt;Two real spotlights on the player's headlights plus a painted road wedge, because 800-candela headlights blew out everything within 20 metres on the first try.&lt;/li&gt;
&lt;li&gt;The reflection probe is baked from the venue itself with &lt;code&gt;PMREMGenerator.fromScene&lt;/code&gt; once the track exists, so the floodlights reflect in the wet road and the clearcoat paint.&lt;/li&gt;
&lt;li&gt;Wet asphalt: a puddle mask painted into the roughness map, with a specular cap injected through &lt;code&gt;onBeforeCompile&lt;/code&gt; so the floods do not turn the road into a mirror at low camera angles.&lt;/li&gt;
&lt;li&gt;Bloom with a threshold of 1.05. The 25 sponsor plates are unlit white and render at exactly 1.0, so every threshold below that made the car glow like a lamp. Real emitters are written above 1.0 instead.&lt;/li&gt;
&lt;/ul&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%2Fpxt39mss0vpq21srks5h.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%2Fpxt39mss0vpq21srks5h.jpg" alt="The menu at night" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The graphics agent could see its own frames: eight rounds of GPU screenshots through Playwright with &lt;code&gt;--use-angle=d3d11&lt;/code&gt;, judging each one and fixing the four different ways the image went white before it landed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Everything else
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;F1 start: five lights on the gantry, one per second, a random hold, lights out, with a camera sweep along the grid.&lt;/li&gt;
&lt;li&gt;Slow-motion orbit at the flag, then a results screen with top speed, overtakes and a personal best kept in &lt;code&gt;localStorage&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Engine, tyre squeal, wind, kerb rumble, gear clicks, overtake chime, crowd roar: all Web Audio synthesis, zero downloads.&lt;/li&gt;
&lt;li&gt;Tacho with gear numeral, lap bar, gaps to the cars ahead and behind, overtake toasts, tilt steering and haptics on phones.&lt;/li&gt;
&lt;li&gt;Tyre smoke, skid marks, sparks, speed lines, fireworks, confetti.&lt;/li&gt;
&lt;/ul&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%2Fi2jz3ckq0wq9unx1ap83.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%2Fi2jz3ckq0wq9unx1ap83.jpg" alt="Nitro on the straight" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would tell you
&lt;/h2&gt;

&lt;p&gt;It cost more than two million tokens across the agents and two rate limits, and the visible difference was not the physics or the sound. It was turning the lights off. If you are going to have a model rebuild a game, decide what the screenshot should look like first; the feel is invisible in a video.&lt;/p&gt;

&lt;p&gt;The race is live and free, no account: &lt;a href="https://mylambo.money/race" rel="noopener noreferrer"&gt;mylambo.money/race&lt;/a&gt;. The car model is the Khronos glTF Sample Assets CarConcept, CC BY 4.0.&lt;/p&gt;

</description>
      <category>threejs</category>
      <category>webdev</category>
      <category>ai</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>An OpenAI flagship lost 38% of its daily usage in three days — then set three straight all-time highs</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Sun, 16 Aug 2026 01:41:04 +0000</pubDate>
      <link>https://dev.to/codelong888/an-openai-flagship-lost-38-of-its-daily-usage-in-three-days-then-set-three-straight-all-time-4ebb</link>
      <guid>https://dev.to/codelong888/an-openai-flagship-lost-38-of-its-daily-usage-in-three-days-then-set-three-straight-all-time-4ebb</guid>
      <description>&lt;p&gt;Everyone publishes AI model leaderboards. Almost nobody publishes the &lt;strong&gt;day-level curve&lt;/strong&gt; — and the&lt;br&gt;
curve is where the actual story is.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://whatstrending.ai/models" rel="noopener noreferrer"&gt;whatstrending.ai&lt;/a&gt; we snapshot every model's daily request count&lt;br&gt;
from OpenRouter's usage feed into a database, once a day, &lt;code&gt;INSERT OR IGNORE&lt;/code&gt; — a row can never be&lt;br&gt;
revised after the fact. We're 78 days in. Here is what &lt;code&gt;openai/gpt-5.6-luna&lt;/code&gt; did over the last two&lt;br&gt;
weeks:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Requests/day&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Aug 04&lt;/td&gt;
&lt;td&gt;162.9M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 05&lt;/td&gt;
&lt;td&gt;180.8M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 06&lt;/td&gt;
&lt;td&gt;193.8M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 07&lt;/td&gt;
&lt;td&gt;210.8M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 08&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;222.5M&lt;/strong&gt; ← peak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 09&lt;/td&gt;
&lt;td&gt;209.6M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 10&lt;/td&gt;
&lt;td&gt;171.6M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 11&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;137.3M&lt;/strong&gt; ← floor: −38.3% off peak in 3 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 12&lt;/td&gt;
&lt;td&gt;143.2M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 13&lt;/td&gt;
&lt;td&gt;157.3M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 14&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;231.8M&lt;/strong&gt; ← new all-time high, +47.4% in one day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 15&lt;/td&gt;
&lt;td&gt;237.3M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aug 16&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;243.5M&lt;/strong&gt; ← third consecutive all-time high&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A flagship model shed &lt;strong&gt;more than a third of its daily traffic in three days&lt;/strong&gt;, then won all of it&lt;br&gt;
back — and more — inside the same week. Three consecutive days above the old peak as of Aug 16.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this isn't a data artifact
&lt;/h2&gt;

&lt;p&gt;Three checks, run before writing this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The whole table didn't move.&lt;/strong&gt; The all-model daily total went 3.56B → 3.66B (+2.8%) on the day
luna jumped 47%, and 3.70B → 3.73B (+0.8%) on Aug 16. Luna's &lt;em&gt;share&lt;/em&gt; moved: roughly 4.4% → 6.5%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Peers didn't dip with it.&lt;/strong&gt; During luna's drawdown (Aug 09–11), &lt;code&gt;deepseek/deepseek-v4-flash-0731&lt;/code&gt;
and &lt;code&gt;tencent/hy3&lt;/code&gt; were setting their own highs on the same days — so this is not a provider-wide
trailing-edge reporting droop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rows are frozen at write time.&lt;/strong&gt; Aug 14 read 231.8M on the day we collected it and reads 231.8M
today. Nothing was backfilled or revised.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why it matters
&lt;/h2&gt;

&lt;p&gt;Monthly aggregates — which is what every public ranking shows — would have flattened this entire&lt;br&gt;
event into "usage grew". The day-level series shows real flagship usage is far more volatile than&lt;br&gt;
anything the leaderboards suggest: a −38% drawdown and a full recovery to new highs fit inside eight&lt;br&gt;
days. If you're making routing, capacity, or "which model is winning" decisions off monthly numbers,&lt;br&gt;
you're averaging away the actual signal.&lt;/p&gt;

&lt;p&gt;The live, daily-updated version of this curve is here:&lt;br&gt;
&lt;strong&gt;&lt;a href="https://whatstrending.ai/models" rel="noopener noreferrer"&gt;https://whatstrending.ai/models&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Method: daily snapshot of OpenRouter per-day request counts, 100 models/day, 78 days and counting,&lt;br&gt;
stored append-only (&lt;code&gt;INSERT OR IGNORE&lt;/code&gt;) in Cloudflare D1.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>openrouter</category>
      <category>data</category>
    </item>
    <item>
      <title>We ping 2,587 vibe-coded apps every 6 hours. The 'AI apps die fast' narrative isn't holding up</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Sat, 15 Aug 2026 07:57:35 +0000</pubDate>
      <link>https://dev.to/codelong888/we-ping-2587-vibe-coded-apps-every-6-hours-the-ai-apps-die-fast-narrative-isnt-holding-up-1jo5</link>
      <guid>https://dev.to/codelong888/we-ping-2587-vibe-coded-apps-every-6-hours-the-ai-apps-die-fast-narrative-isnt-holding-up-1jo5</guid>
      <description>&lt;p&gt;Everyone "knows" vibe-coded apps are abandoned within weeks. Someone ships a weekend project with Cursor or Lovable, tweets about it, and the domain quietly dies when the trial credits run out.&lt;/p&gt;

&lt;p&gt;I run &lt;a href="https://vibeking.fun" rel="noopener noreferrer"&gt;VibeKing&lt;/a&gt;, a directory of products built with AI coding tools. A couple of weeks ago I added a liveness engine: every product in the catalogue gets an HTTP check every 6 hours, cycling through all of them continuously. No sampling, no estimates — every single URL, checked repeatedly, with failure counts.&lt;/p&gt;

&lt;p&gt;Here's what the data actually says so far.&lt;/p&gt;

&lt;h2&gt;
  
  
  93.1% of them are up
&lt;/h2&gt;

&lt;p&gt;Of &lt;strong&gt;2,587 approved products&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;th&gt;Share&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Live&lt;/td&gt;
&lt;td&gt;2,408&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;93.1%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;At risk (intermittent failures)&lt;/td&gt;
&lt;td&gt;178&lt;/td&gt;
&lt;td&gt;6.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confirmed dead&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;"At risk" means the checker has caught the site failing on recent checks but it hasn't sustained enough consecutive failures to be declared dead. "Dead" requires repeated failures over multiple checks — a bar nothing has cleared yet in the observation window.&lt;/p&gt;

&lt;p&gt;Two honest caveats. First, this window is short — the engine has been running since early August, so this measures &lt;em&gt;current&lt;/em&gt; availability, not long-term survival. The interesting numbers arrive in 6-12 months, and I'll publish those too, whichever way they cut. Second, there's a survivorship component: some products died before ever being catalogued, and those deaths aren't in the denominator. What this data can say is narrower but still useful: &lt;strong&gt;of the vibe-coded products visible enough to be catalogued, 93% are up right now&lt;/strong&gt; — the wasteland narrative describes launches that never got noticed, not the ones that did.&lt;/p&gt;

&lt;h2&gt;
  
  
  What vibe coders build: tools for other vibe coders
&lt;/h2&gt;

&lt;p&gt;Category distribution of the same 2,587:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;th&gt;Share&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AI Coding&lt;/td&gt;
&lt;td&gt;691&lt;/td&gt;
&lt;td&gt;26.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev Tools&lt;/td&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;15.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;316&lt;/td&gt;
&lt;td&gt;12.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SaaS&lt;/td&gt;
&lt;td&gt;237&lt;/td&gt;
&lt;td&gt;9.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Productivity&lt;/td&gt;
&lt;td&gt;178&lt;/td&gt;
&lt;td&gt;6.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Design&lt;/td&gt;
&lt;td&gt;161&lt;/td&gt;
&lt;td&gt;6.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;42% of AI-built products are developer tooling.&lt;/strong&gt; The community's biggest output category is tools for itself — the classic gold-rush-shovels pattern, visible in the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  .com still wins, but the builder TLDs are a third of everything
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;TLD&lt;/th&gt;
&lt;th&gt;Share&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;.com&lt;/td&gt;
&lt;td&gt;46.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.ai&lt;/td&gt;
&lt;td&gt;11.4%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.app&lt;/td&gt;
&lt;td&gt;10.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.io&lt;/td&gt;
&lt;td&gt;6.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.dev&lt;/td&gt;
&lt;td&gt;3.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;.ai + .app + .io + .dev together are &lt;strong&gt;30.5%&lt;/strong&gt; — nearly a third of vibe-coded products launch on a "builder" TLD. And still, when makers want to be taken seriously, they buy the .com.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method, briefly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Catalogue: 2,587 approved products on &lt;a href="https://vibeking.fun" rel="noopener noreferrer"&gt;vibeking.fun&lt;/a&gt;, collected from launch platforms and direct submissions&lt;/li&gt;
&lt;li&gt;Liveness: HTTP checks in rotating batches every 6 hours via Cloudflare Workers cron; a product is "at risk" after repeated recent failures and "dead" only after sustained consecutive failures&lt;/li&gt;
&lt;li&gt;Anti-bot handling: sites that block automated checks (401/403/405/429) count as &lt;em&gt;alive&lt;/em&gt; — refusing bots is not being down&lt;/li&gt;
&lt;li&gt;Nothing here is estimated. Counts are from the production database, queried today.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll re-run this in a few months when the longitudinal picture exists. If you want your product in the tracked set: &lt;a href="https://vibeking.fun/submit" rel="noopener noreferrer"&gt;vibeking.fun/submit&lt;/a&gt; — free, no signup wall for browsing, and the checker will keep an eye on your uptime for you.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>indiehackers</category>
      <category>data</category>
    </item>
    <item>
      <title>Your hreflang says English-only. Does your language switcher agree?</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Thu, 13 Aug 2026 19:51:06 +0000</pubDate>
      <link>https://dev.to/codelong888/your-hreflang-says-english-only-does-your-language-switcher-agree-146</link>
      <guid>https://dev.to/codelong888/your-hreflang-says-english-only-does-your-language-switcher-agree-146</guid>
      <description>&lt;p&gt;I run a maintenance sweep over my own site every day. Yesterday it found 1,474 dead internal links that had been sitting there in plain sight, on 737 pages, and every automated check I had was green.&lt;/p&gt;

&lt;p&gt;The cause is a bug class I have not seen written up, so here it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two places encode "which languages does this page have"
&lt;/h2&gt;

&lt;p&gt;A partially translated site has, whether you planned it or not, &lt;strong&gt;two independent answers&lt;/strong&gt; to the question &lt;em&gt;does this page exist in Chinese?&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;&amp;lt;link rel="alternate" hreflang="..."&amp;gt;&lt;/code&gt; tags in &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; — what you tell crawlers.&lt;/li&gt;
&lt;li&gt;The EN / 简 / 繁 buttons in your nav — what you tell humans.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mine disagreed. The &lt;code&gt;hreflang&lt;/code&gt; side was correct: a few page families on my site are English-only, so those pages emit an English self-reference and nothing else. There is even a comment in the source explaining why, because declaring an alternate that 404s poisons the whole hreflang cluster.&lt;/p&gt;

&lt;p&gt;The nav switcher never got that memo. It was doing the naive thing:&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="c1"&gt;// every page, unconditionally&lt;/span&gt;
&lt;span class="s2"&gt;`&amp;lt;a href="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;EN&amp;lt;/a&amp;gt;
 &amp;lt;a href="/zh-cn&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;简&amp;lt;/a&amp;gt;
 &amp;lt;a href="/zh-tw&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;繁&amp;lt;/a&amp;gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So on every English-only page, the two Chinese buttons pointed at URLs that do not exist. Click 简 on the API docs, get a 404.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why nothing caught it
&lt;/h2&gt;

&lt;p&gt;This is the part worth internalising. The bug survived because it fails every test you would think to write:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The pages are all 200.&lt;/strong&gt; Uptime checks, sitemap validation, status sweeps — all green. The broken thing is a link &lt;em&gt;on&lt;/em&gt; a healthy page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;hreflang&lt;/code&gt; is correct.&lt;/strong&gt; Any SEO audit that checks hreflang reciprocity passes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The 404s are correct too.&lt;/strong&gt; Those Chinese URLs &lt;em&gt;should&lt;/em&gt; 404; the page genuinely does not exist in Chinese.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It is invisible on the pages you look at most.&lt;/strong&gt; My homepage, tools, and guides &lt;em&gt;are&lt;/em&gt; translated, so the switcher works perfectly everywhere I click during normal use. It only breaks in the families I never browse by hand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every component was individually correct. The defect only existed in the relationship between two of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The check that found it
&lt;/h2&gt;

&lt;p&gt;Nothing clever. Take a page, extract every on-site &lt;code&gt;href&lt;/code&gt;, and curl all of them — recording the status &lt;strong&gt;and&lt;/strong&gt; the redirect count:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://example.com/some-page &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'href="/[^"]*"'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/href="//;s/"//'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; p&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
      &lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}:%{num_redirects}'&lt;/span&gt; &lt;span class="s2"&gt;"https://example.com&lt;/span&gt;&lt;span class="nv"&gt;$p&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"200:0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$p&lt;/span&gt;&lt;span class="s2"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;num_redirects&lt;/code&gt; half matters as much as the status. &lt;code&gt;200:1&lt;/code&gt; is a link that works but burns a hop, and a page full of those is a page slowly leaking crawl budget. I run this against one rotating page per sweep rather than crawling the whole site — cheap, and over a couple of weeks it covers everything that matters.&lt;/p&gt;

&lt;p&gt;On the page I happened to rotate to yesterday, &lt;a href="https://hackmyip.com/api-docs" rel="noopener noreferrer"&gt;the API docs&lt;/a&gt;, it printed exactly two lines. Both were the language switcher.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix is not "add the missing pages"
&lt;/h2&gt;

&lt;p&gt;The tempting fix is to generate the Chinese versions so the links resolve. That is how you end up maintaining machine-translated pages nobody reads, and — if they serve near-identical content — competing with yourself in search.&lt;/p&gt;

&lt;p&gt;The real fix is to make the two sources of truth &lt;strong&gt;one&lt;/strong&gt; source of truth. I already had a set listing the English-only paths, used by the &lt;code&gt;hreflang&lt;/code&gt; generator. The switcher just needed to consult it:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;zhLinks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;EN_ONLY_PAGES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
  &amp;lt;a href="/zh-cn&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;简&amp;lt;/a&amp;gt;
  &amp;lt;a href="/zh-tw&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;繁&amp;lt;/a&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On English-only pages the switcher now renders the EN button alone. 1,474 dead links gone; the rest of the site keeps its full switcher. Whenever a page family gets translated for real, adding it to that one set fixes the crawler signal and the human UI in the same commit — which is the actual win here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things to take away
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;If two subsystems answer the same question, one of them is going to be wrong.&lt;/strong&gt; Language availability, feature flags, pricing tiers — anywhere you have a "which of these exist" list, count how many places encode it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Green status checks do not mean green links.&lt;/strong&gt; A 200 page can be full of 404s. Check the edges of your graph, not just the nodes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit the family, not a sample.&lt;/strong&gt; Spot-checking would have found nothing, because the switcher works on most pages. Enumerating every link on one page found it in seconds.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The crawler-facing side of this is what I care about most, since AI assistants read my &lt;a href="https://hackmyip.com/llms.txt" rel="noopener noreferrer"&gt;machine-readable site directory&lt;/a&gt; and follow whatever URLs it hands them. A dead link is not just a bad click — it is a citation you never get.&lt;/p&gt;

&lt;p&gt;Go curl your own language switcher.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>i18n</category>
    </item>
    <item>
      <title>How to check if an IP is blacklisted (DNSBL), from raw DNS to one curl</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Wed, 29 Jul 2026 13:35:06 +0000</pubDate>
      <link>https://dev.to/codelong888/how-to-check-if-an-ip-is-blacklisted-dnsbl-from-raw-dns-to-one-curl-4jl5</link>
      <guid>https://dev.to/codelong888/how-to-check-if-an-ip-is-blacklisted-dnsbl-from-raw-dns-to-one-curl-4jl5</guid>
      <description>&lt;p&gt;Your emails start bouncing, or a website suddenly challenges every request from your server. Very often the reason is boring: your IP landed on a DNSBL and you did not know.&lt;/p&gt;

&lt;p&gt;A DNSBL (DNS-based blackhole list) is a reputation database you query over plain DNS. Mail servers do this on every incoming connection. Spamhaus, SpamCop, Barracuda and a dozen others each run their own list, their own criteria, and their own delisting process.&lt;/p&gt;

&lt;h2&gt;
  
  
  The raw mechanic (it is just DNS)
&lt;/h2&gt;

&lt;p&gt;To check an IP against a list, you reverse its octets and query them as a subdomain of the list's zone. Checking &lt;code&gt;127.0.0.2&lt;/code&gt; against SpamCop looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;nslookup &lt;span class="nt"&gt;-type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;A 2.0.0.127.bl.spamcop.net
&lt;span class="go"&gt;
Name:    2.0.0.127.bl.spamcop.net
Address:  127.0.0.2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the name resolves (typically to something in &lt;code&gt;127.0.0.0/8&lt;/code&gt;), the IP is listed. If you get &lt;code&gt;NXDOMAIN&lt;/code&gt;, it is clean on that list. &lt;code&gt;127.0.0.2&lt;/code&gt; is the standard test address that every DNSBL keeps permanently listed, which is why the query above always "hits" and is a handy way to confirm your resolver can reach a list at all.&lt;/p&gt;

&lt;p&gt;That last part matters more than people expect. Some lists, Spamhaus in particular, refuse queries coming from big public resolvers like 8.8.8.8 or 1.1.1.1. You can query them and get nothing back, conclude "clean", and be wrong. If you script your own checker, query through your own resolver and treat "no answer" as unknown, not clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking a dozen lists with one request
&lt;/h2&gt;

&lt;p&gt;Checking one list tells you little. An IP that is clean on SpamCop can be listed on UCEPROTECT or PSBL. To do it properly you loop over 10 to 15 zones, handle each list's return-code semantics, and handle the resolver problem above.&lt;/p&gt;

&lt;p&gt;Or you let one endpoint do it. I run a free, keyless API that fans out the DNS queries server-side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="s2"&gt;"https://hackmyip.com/api/blacklist?ip=1.1.1.1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&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;"ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.1.1.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"total_lists"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"total_checked"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"unavailable_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"listed_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"clean"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CLEAN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"results"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Barracuda"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b.barracudacentral.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"listed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"not_listed"&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;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SpamCop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bl.spamcop.net"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"listed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"not_listed"&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;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Spamhaus ZEN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"zen.spamhaus.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"listed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unavailable"&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;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;(Response trimmed; the real one returns all 12 lists: Spamhaus ZEN, Barracuda, SpamCop, Spam Eating Monkey, UCEPROTECT L1, Composite Blocking List, Invaluement, PSBL, Mailspike, Truncate, WPBL, and Suomispam.)&lt;/p&gt;

&lt;p&gt;One honest detail I want to point out because most checkers get it wrong: notice &lt;code&gt;total_checked: 10&lt;/code&gt; versus &lt;code&gt;total_lists: 12&lt;/code&gt;, and &lt;code&gt;"status": "unavailable"&lt;/code&gt; on Spamhaus in that run. When a zone cannot be reached from the edge location serving your request, the API says so instead of silently reporting "clean". If you build on top of this, treat &lt;code&gt;unavailable&lt;/code&gt; as "check this one another way", not as a pass.&lt;/p&gt;

&lt;p&gt;There is also a browser version of the same check at &lt;a href="https://hackmyip.com/blacklist" rel="noopener noreferrer"&gt;hackmyip.com/blacklist&lt;/a&gt; if you just want to paste an IP and look, and the full endpoint list lives in the &lt;a href="https://hackmyip.com/api" rel="noopener noreferrer"&gt;API docs&lt;/a&gt;. No key, no signup, CORS enabled, so you can call it from a frontend too.&lt;/p&gt;

&lt;h2&gt;
  
  
  If your IP is actually listed
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Fix the cause first. A listing almost always has a reason: a compromised machine on your network, a web form being abused to send mail, an open relay, or a neighbor on the same shared IP range. Delisting without fixing the cause gets you relisted fast.&lt;/li&gt;
&lt;li&gt;Then go to each list's own delisting page. There is no central authority; every list has its own form and its own rules.&lt;/li&gt;
&lt;li&gt;Some lists age entries out automatically after the abuse stops, others keep you until you ask. Recheck after a day or two.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are on a cloud provider or CGNAT, you may simply have inherited a previous tenant's reputation. Same playbook applies, and it is a good argument for checking an IP before you build anything mail-related on it.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>networking</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>how i run a 2,500-page directory from a single cloudflare worker</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Tue, 21 Jul 2026 03:01:26 +0000</pubDate>
      <link>https://dev.to/codelong888/how-i-run-a-2500-page-directory-from-a-single-cloudflare-worker-lf1</link>
      <guid>https://dev.to/codelong888/how-i-run-a-2500-page-directory-from-a-single-cloudflare-worker-lf1</guid>
      <description>&lt;p&gt;quick build writeup, because i haven't seen many people run a directory this way and it's been surprisingly nice to live with.&lt;/p&gt;

&lt;p&gt;the site is vibeking, a directory of vibe-coded products (stuff people built mostly by prompting AI). around 2,500 entries right now, each with its own page, and the whole thing runs as ONE cloudflare worker with a d1 database behind it. no framework, no build step, no origin server. here's how it works and the two things that bit me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;one entry, not one page.&lt;/strong&gt; the trick that makes a big directory maintainable is you never build pages, you build data. every product is a row in d1 (name, tagline, url, category, tags). one render function turns any row into a full page: title, meta, og tags, json-ld, internal links to related products, all of it. so the 2,000th product costs the same effort as the 5th. the worker matches /product/:slug, pulls the row, renders. that's basically the whole architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;d1 at the edge is great until you think about it wrong.&lt;/strong&gt; it's sqlite, and for a read-heavy directory that's perfect. the mistake i made early was doing too much per request. put indexes on whatever you sort/filter by (category, votes, created_at) on day one, not after it's slow.&lt;/p&gt;

&lt;p&gt;now the two things that actually bit me, because this is the useful part:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. the soft-404 that quietly poisons your seo.&lt;/strong&gt; my worker had a catch-all that, for any path it didn't recognize, just served the homepage with a 200. felt harmless. it is not. google crawls a bunch of guessed/junk urls, every one returns 200-homepage, and google decides "this site returns the same page for everything" and starts distrusting your urls. for a directory whose entire seo bet is thousands of unique pages, that's poison. the fix is boring but critical: any unmatched path must return a real 404. probe your own site with a fake url and confirm you get a 404. i'd fixed this on a couple of my other sites and STILL had to catch it here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. the cold-start problem is real and your page count doesn't save you.&lt;/strong&gt; here's the humbling bit. i thought 2,500 pages was a moat. it isn't, on its own. a brand-new domain with 2,500 thin pages is 2,500 pages google mostly ignores, because you haven't earned trust yet. page count is potential energy, not traffic. what turns it on is the slow stuff: real internal linking, genuinely useful individual pages, being something an AI assistant would recommend, and earning a few real links from outside. i'm in the middle of that part now and it's the opposite of fun, which is probably why it's the part most of us skip.&lt;/p&gt;

&lt;p&gt;if you're building anything directory-shaped on workers, those are the two i'd save you: return real 404s, and don't mistake a big sitemap for traction.&lt;/p&gt;

&lt;p&gt;the site if you want to see the pattern in the wild: &lt;a href="https://vibeking.fun/?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=distro" rel="noopener noreferrer"&gt;vibeking.fun&lt;/a&gt;. happy to answer anything about the worker/d1 setup in the comments.&lt;/p&gt;

&lt;p&gt;thanks for reading.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>cloudflare</category>
      <category>serverless</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I built 1,081 free tools. Today a stranger finally asked to join.</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Sun, 19 Jul 2026 16:59:01 +0000</pubDate>
      <link>https://dev.to/codelong888/i-built-1081-free-tools-today-a-stranger-finally-asked-to-join-1f8l</link>
      <guid>https://dev.to/codelong888/i-built-1081-free-tools-today-a-stranger-finally-asked-to-join-1f8l</guid>
      <description>&lt;p&gt;Seventeen days ago I launched &lt;a href="https://yourhack.ai" rel="noopener noreferrer"&gt;yourhack.ai&lt;/a&gt;, a directory of free, client-side web tools. Calculators, converters, formatters, PDF stuff. Everything runs in the browser, nothing gets uploaded, no signups.&lt;/p&gt;

&lt;p&gt;I kept adding tools almost every day. The counter says 1,081 now, which sounds impressive until you realize a counter is just me talking to myself. A directory you fill yourself is a monologue.&lt;/p&gt;

&lt;p&gt;Today that changed. A stranger submitted their own product through the submit form and asked to be listed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this tiny event matters
&lt;/h2&gt;

&lt;p&gt;Nobody submits their product to a site they think is dead. A submission is someone spending their own effort betting that being on YOUR page is worth something. You cannot fake that signal, and you cannot buy it, which makes it the first piece of real product-market evidence a directory can get.&lt;/p&gt;

&lt;p&gt;One submission is a small number. But the difference between zero and one is the difference between "my project" and "a place". Everything after this is just more.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually did with it
&lt;/h2&gt;

&lt;p&gt;I did not auto-approve it, and honestly that surprised me too.&lt;/p&gt;

&lt;p&gt;The submission described itself as a free calculator. I opened the site: the calculator was behind a $4.99/mo plan, and the free part was a reference library. Decent product, but the listing copy oversold it. So I rewrote the listing to match reality (free library, paid tools, affiliate links disclosed) before approving it.&lt;/p&gt;

&lt;p&gt;That felt like the actual job of a directory. Anyone can aggregate links. The only thing that makes a directory worth listing on is that someone checks what's behind the link.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boring lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Review flows get used before you're ready.&lt;/strong&gt; I wrote the submission form in week one and assumed it would sit idle for months. Real usage always arrives before the polish does.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The first outside user finds your real bugs.&lt;/strong&gt; Mine surfaced a policy question I had never written down: can makers edit a listing after approval? (Answer now: no. Approved listings are frozen; edits go back through review.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ship the door before you expect visitors.&lt;/strong&gt; If the submit form had not existed, this person would have bounced and I would never have known anyone cared.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you run a directory, a gallery, a showcase, anything with a "submit" button: the day that button gets pressed by someone you don't know is the day the site becomes real. Build the door early.&lt;/p&gt;

&lt;p&gt;The directory is at &lt;a href="https://yourhack.ai" rel="noopener noreferrer"&gt;yourhack.ai&lt;/a&gt;, and if you've built a free web tool, the door is at &lt;a href="https://yourhack.ai/submit" rel="noopener noreferrer"&gt;yourhack.ai/submit&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>webdev</category>
      <category>sideprojects</category>
      <category>indiehacking</category>
    </item>
    <item>
      <title>i built 1000+ free web tools in a couple weeks and turns out building it was the easy part</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Fri, 17 Jul 2026 11:20:35 +0000</pubDate>
      <link>https://dev.to/codelong888/i-built-1000-free-web-tools-in-a-couple-weeks-and-turns-out-building-it-was-the-easy-part-50ei</link>
      <guid>https://dev.to/codelong888/i-built-1000-free-web-tools-in-a-couple-weeks-and-turns-out-building-it-was-the-easy-part-50ei</guid>
      <description>&lt;p&gt;so i've been building this thing called yourhack.ai for the last couple weeks and i wanted to write down the honest version of how it's going, mostly because everything i read about side projects is either a flex or a "how i hit $10k MRR" thing and this is very much neither lol.&lt;/p&gt;

&lt;p&gt;it started dumb. i kept needing quick little tools online, convert this file, format this json, compress this image, count these words. and every single time i'd land on some site absolutely drowning in ads and popups, half of them making you create an account just to download the result of a 10 second task. it genuinely irritated me every time.&lt;/p&gt;

&lt;p&gt;so i built one. a clean little tool that does the thing and gets out of the way. then i built another. and uh, i didn't really stop. it's over 1000 now.&lt;/p&gt;

&lt;p&gt;the thing that let it get out of hand this fast is honestly the only clever bit: i don't build pages, i build entries. every tool is basically one object in a file (name, description, a little render function), and a template turns that into a full page with its own url, seo tags, structured data, search entry, all of it. so adding the 500th tool costs about the same as the 5th. the whole site is a single cloudflare worker at the edge, and most of the tools run entirely in your browser so your files just stay on your machine (the newer ai-powered ones do hit a server, being upfront about that).&lt;/p&gt;

&lt;p&gt;anyway, that's the part i'm proud of. here's the part that's been humbling me.&lt;/p&gt;

&lt;p&gt;i genuinely, kind of embarrassingly, believed that if i just made enough actually-useful stuff, people would find it. that was the whole plan. make it good and they'll come.&lt;/p&gt;

&lt;p&gt;they did not come lol.&lt;/p&gt;

&lt;p&gt;turns out a brand new domain is basically invisible. you can ship a thousand genuinely useful pages and google will just not care, because your site hasn't earned any trust yet and trust is the whole game. i had it backwards. i thought building was 90% of it and getting the word out was some small thing at the end. it's the opposite. building was the easy part, the fun part, the part fully in my control. distribution is slow and awkward and mostly out of my hands, and i'm just not naturally good at it.&lt;/p&gt;

&lt;p&gt;and the embarrassing tell is what i keep doing about it: instead of doing the scary distribution work, i just build more tools. because building is comfortable and putting myself out there is not. i'm aware it's a cope. i've been doing it anyway. writing this is me trying to break the pattern a little.&lt;/p&gt;

&lt;p&gt;where i've landed for now is to stop trying to "launch" and just be genuinely useful over a long stretch of time. answer real questions clearly, make the site something an AI assistant would actually recommend when someone asks it for a tool, and let that compound slowly instead of chasing a spike that dies in two days.&lt;/p&gt;

&lt;p&gt;so that's the honest state of it. i can build fast, i'm bad at getting seen, and i'm working on the second one.&lt;/p&gt;

&lt;p&gt;if you've been through this, i'd genuinely love to hear what worked for you. not "post everywhere", i mean the specific one or two things that actually moved the needle. if you want to see the thing itself it's &lt;a href="https://yourhack.ai" rel="noopener noreferrer"&gt;yourhack.ai&lt;/a&gt;, though honestly i'd take the distribution advice over the traffic.&lt;/p&gt;

&lt;p&gt;thanks for reading this far.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>indiehackers</category>
      <category>javascript</category>
    </item>
    <item>
      <title>I tracked every trending AI repo's stars daily for 3 weeks. The growth is not where I expected</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Fri, 10 Jul 2026 00:38:14 +0000</pubDate>
      <link>https://dev.to/codelong888/i-tracked-every-trending-ai-repos-stars-daily-for-3-weeks-the-growth-is-not-where-i-expected-4j8a</link>
      <guid>https://dev.to/codelong888/i-tracked-every-trending-ai-repos-stars-daily-for-3-weeks-the-growth-is-not-where-i-expected-4j8a</guid>
      <description>&lt;p&gt;I run a small AI trends site, and three weeks ago I started doing something simple: every day, snapshot the star count of every repo that crosses my GitHub trending scan for AI. No judgment, no curation, just append-only rows in a database.&lt;/p&gt;

&lt;p&gt;611 repos and 2,671 data points later (June 19 to July 10), the picture of what's actually growing looks pretty different from what my feeds told me was hot. Here's what the data says.&lt;/p&gt;

&lt;p&gt;Before publishing this I re-checked every number below against GitHub's live API. Star counts drift by the hour, so treat them as of July 10.&lt;/p&gt;

&lt;h2&gt;
  
  
  The top 10 risers, by raw stars gained
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Repo&lt;/th&gt;
&lt;th&gt;Gained&lt;/th&gt;
&lt;th&gt;Window&lt;/th&gt;
&lt;th&gt;From → To&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;calesthio/OpenMontage&lt;/td&gt;
&lt;td&gt;+30,253&lt;/td&gt;
&lt;td&gt;21 days&lt;/td&gt;
&lt;td&gt;5,899 → 36,152&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeusData/codebase-memory-mcp&lt;/td&gt;
&lt;td&gt;+20,483&lt;/td&gt;
&lt;td&gt;19 days&lt;/td&gt;
&lt;td&gt;7,516 → 27,999&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mattpocock/skills&lt;/td&gt;
&lt;td&gt;+19,053&lt;/td&gt;
&lt;td&gt;15 days&lt;/td&gt;
&lt;td&gt;137,485 → 156,538&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;obra/superpowers&lt;/td&gt;
&lt;td&gt;+16,887&lt;/td&gt;
&lt;td&gt;20 days&lt;/td&gt;
&lt;td&gt;232,908 → 249,795&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NousResearch/hermes-agent&lt;/td&gt;
&lt;td&gt;+14,896&lt;/td&gt;
&lt;td&gt;21 days&lt;/td&gt;
&lt;td&gt;197,297 → 212,193&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Panniantong/Agent-Reach&lt;/td&gt;
&lt;td&gt;+14,334&lt;/td&gt;
&lt;td&gt;14 days&lt;/td&gt;
&lt;td&gt;34,780 → 49,114&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;usestrix/strix&lt;/td&gt;
&lt;td&gt;+13,243&lt;/td&gt;
&lt;td&gt;12 days&lt;/td&gt;
&lt;td&gt;26,363 → 39,606&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;addyosmani/agent-skills&lt;/td&gt;
&lt;td&gt;+12,685&lt;/td&gt;
&lt;td&gt;21 days&lt;/td&gt;
&lt;td&gt;63,156 → 75,841&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;asgeirtj/system_prompts_leaks&lt;/td&gt;
&lt;td&gt;+11,720&lt;/td&gt;
&lt;td&gt;21 days&lt;/td&gt;
&lt;td&gt;43,415 → 55,135&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;msitarzewski/agency-agents&lt;/td&gt;
&lt;td&gt;+11,055&lt;/td&gt;
&lt;td&gt;10 days&lt;/td&gt;
&lt;td&gt;118,241 → 129,296&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Windows differ because I only hold snapshots for the days a repo appeared in my scan; each row states its own real window.&lt;/p&gt;

&lt;p&gt;Three things in this data genuinely surprised me.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. "Skills" are eating agent frameworks
&lt;/h2&gt;

&lt;p&gt;Four of the top ten are not agent frameworks. They are collections of packaged expertise that plug into an existing agent: obra/superpowers (still compounding at roughly 840 stars a day on a 250k base), mattpocock/skills, addyosmani/agent-skills, msitarzewski/agency-agents.&lt;/p&gt;

&lt;p&gt;A year ago this table would have been full of new frameworks. Now the framework layer looks settled and the growth is in what you load INTO the agent. The moat moved from orchestration code to encoded judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The sharpest climbs are applications, not infrastructure
&lt;/h2&gt;

&lt;p&gt;The steepest sustained climb from a newcomer in my dataset is MadsLorentzen/ai-job-search: +10,591 stars in 3 days, roughly 3,500 a day. It is an AI job application framework. Not a model, not a devtool.&lt;/p&gt;

&lt;p&gt;Same pattern elsewhere: OpenMontage (agentic video production) went 6x in three weeks and topped the whole table. xbtlin/ai-berkshire, a Chinese-language value-investing research agent, went from 1,518 to 12,339 in 15 days, an 8x. People are starring things that do a job for them, not things that help them build things.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. A 14-year-old repo gained 10k stars in two days
&lt;/h2&gt;

&lt;p&gt;smicallef/spiderfoot was created in April 2012. It is a classic OSINT automation tool. Between my June 21 and June 23 snapshots it gained 10,413 stars, the fastest burst I recorded from any repo.&lt;/p&gt;

&lt;p&gt;Old tools that happen to be perfect agent tools are getting second lives. If your decade-old project has a clean CLI and does one thing well, it is suddenly relevant again, because agents can drive it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methodology, honestly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Snapshots are daily and only cover repos while they appear in my trending scan, so tracking windows differ per repo. Every delta above states its own window, measured between my first and last snapshot for that repo.&lt;/li&gt;
&lt;li&gt;"Gained" is the difference between those two snapshots, no extrapolation.&lt;/li&gt;
&lt;li&gt;I cross-checked the endpoints against GitHub's API on publish day; stored values matched within normal hourly drift.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The live version of this table updates daily on &lt;a href="https://whatstrending.ai/repos" rel="noopener noreferrer"&gt;the rising repos page&lt;/a&gt;, and there's a &lt;a href="https://whatstrending.ai/pulse" rel="noopener noreferrer"&gt;daily AI briefing&lt;/a&gt; built from the same tracked data (model usage movers, funding, and rising repos), archived per day.&lt;/p&gt;

&lt;p&gt;I'll keep the snapshots running. If this is useful I can post the four-week edition with week-over-week velocity, which the raw data already supports.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>github</category>
      <category>opensource</category>
      <category>datascience</category>
    </item>
    <item>
      <title>I put 300+ free web tools in one place, with no ads and no signup</title>
      <dc:creator>CodeLong888</dc:creator>
      <pubDate>Fri, 03 Jul 2026 01:51:49 +0000</pubDate>
      <link>https://dev.to/codelong888/i-put-300-free-web-tools-in-one-place-with-no-ads-and-no-signup-1cf6</link>
      <guid>https://dev.to/codelong888/i-put-300-free-web-tools-in-one-place-with-no-ads-and-no-signup-1cf6</guid>
      <description>&lt;p&gt;I use a lot of little web tools. A JSON formatter here, a cron parser there, a "cm to inches" when I am reading a spec written by someone on the other side of the planet. And every single time, the same friction: the first result is buried in ads, a cookie wall pops up, and half of them want me to sign in just to format some text.&lt;/p&gt;

&lt;p&gt;So I built the thing I actually wanted: &lt;a href="https://yourhack.ai" rel="noopener noreferrer"&gt;yourhack.ai&lt;/a&gt;, a directory of 300+ free web tools. No ads. No signup. Nothing you paste ever leaves your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is in it
&lt;/h2&gt;

&lt;p&gt;A bit of everything, all client side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developer&lt;/strong&gt;: JSON formatter, Base64, JWT decoder, regex tester, cron parser, hash generators, diff checker, timestamp converter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Converters&lt;/strong&gt;: length, weight, temperature, and dedicated pages for the pairs people actually search, like &lt;a href="https://yourhack.ai/cm-to-inches" rel="noopener noreferrer"&gt;cm to inches&lt;/a&gt; and &lt;a href="https://yourhack.ai/kg-to-lbs" rel="noopener noreferrer"&gt;kg to lbs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calculators&lt;/strong&gt;: &lt;a href="https://yourhack.ai/mortgage-calculator" rel="noopener noreferrer"&gt;mortgage&lt;/a&gt;, loan, percentage, &lt;a href="https://yourhack.ai/bmi-calculator" rel="noopener noreferrer"&gt;BMI&lt;/a&gt;, GPA, and a pile more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generators&lt;/strong&gt;: passwords, QR codes, UUIDs, fake data, usernames&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF and image&lt;/strong&gt;: merge, split, compress, resize, crop, all in the browser&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Random and fun&lt;/strong&gt;: dice, wheel of names, and the rest&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every tool is its own page, works offline once loaded, and runs entirely on your machine. A privacy-friendly toolbox by default, because there is no server to send your data to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I actually enjoyed building
&lt;/h2&gt;

&lt;p&gt;The whole site is one Cloudflare Worker with a tiny registry. Adding a tool is one object:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json-formatter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JSON Formatter &amp;amp; Validator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;developer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Format, validate and minify JSON in your browser.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json formatter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json validator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nx"&gt;intro&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A short SEO paragraph for the page.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;the self-contained tool HTML + inline script&amp;gt;`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The router, the shared template, the SEO tags, the JSON-LD, the sitemap, and the search index all read from that array. So the marginal cost of tool number 301 is one entry: no new routing, no new template. That is what made it possible to grow past 300 without the codebase turning into spaghetti.&lt;/p&gt;

&lt;p&gt;No backend, no database, no build step. Static render on the edge plus inline JavaScript per tool. It costs almost nothing to run, which is the whole reason it can stay free with no ads.&lt;/p&gt;

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

&lt;p&gt;It is live at &lt;a href="https://yourhack.ai" rel="noopener noreferrer"&gt;yourhack.ai&lt;/a&gt;. Light and dark mode, mobile friendly, and it grows every day.&lt;/p&gt;

&lt;p&gt;If there is a tool you keep googling and hate the ad-choked result for, tell me and I will add it. That is genuinely the roadmap right now: whatever people keep needing.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
