<?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: Muhammad Akbar</title>
    <description>The latest articles on DEV Community by Muhammad Akbar (@makbar89).</description>
    <link>https://dev.to/makbar89</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3929716%2F70ad1a08-af22-4104-98fd-bc91e5011973.jpg</url>
      <title>DEV Community: Muhammad Akbar</title>
      <link>https://dev.to/makbar89</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/makbar89"/>
    <language>en</language>
    <item>
      <title>I built a dev review site in 2 weeks — here's the stack, the rejections, and what I'd do differently</title>
      <dc:creator>Muhammad Akbar</dc:creator>
      <pubDate>Wed, 13 May 2026 16:20:03 +0000</pubDate>
      <link>https://dev.to/makbar89/i-built-a-dev-review-site-in-2-weeks-heres-the-stack-the-rejections-and-what-id-do-differently-14oa</link>
      <guid>https://dev.to/makbar89/i-built-a-dev-review-site-in-2-weeks-heres-the-stack-the-rejections-and-what-id-do-differently-14oa</guid>
      <description>&lt;p&gt;A few months ago I tried to find a "best stack under 100 USD a month" article for a side project. Every result was either an enterprise list with line items at thousands per month, or a vague "use Vercel and Supabase" post with no actual numbers.&lt;/p&gt;

&lt;p&gt;So I built one. The result is &lt;a href="https://cheapstack.dev" rel="noopener noreferrer"&gt;cheapstack.dev&lt;/a&gt; — an editorial site that publishes itemized reference stacks for indie SaaS infrastructure on 50–200 USD a month, with every line item, the date prices were verified, and what to swap when traffic crosses specific thresholds.&lt;/p&gt;

&lt;p&gt;I'm not going to pretend this is a masterpiece. I want to write this post because the things I learned along the way will probably save someone else two weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The build
&lt;/h2&gt;

&lt;p&gt;Stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 16&lt;/strong&gt; with &lt;code&gt;output: "export"&lt;/code&gt; for static export&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Workers Static Assets&lt;/strong&gt; for hosting (free, unlimited bandwidth)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IBM Plex Sans + Plex Mono&lt;/strong&gt; for typography&lt;/li&gt;
&lt;li&gt;Markdown-driven content layer (no CMS, no backend, no database)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two-week evening build, mostly weekends. Lighthouse 100/100/100/100 across all pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Cloudflare Workers, not Vercel
&lt;/h2&gt;

&lt;p&gt;Cheapstack's whole pitch is "real numbers for cheap stacks." Hosting it on Vercel — whose Hobby tier is explicitly non-commercial, and whose Pro tier starts at 20 USD a month — would have been hypocritical the moment I added an affiliate link.&lt;/p&gt;

&lt;p&gt;Cloudflare Workers Static Assets bills 0 USD a month, even with commercial use, and edges out Vercel on first-byte latency in 60% of regions. The DX is rougher (you can't just &lt;code&gt;next build&lt;/code&gt; and deploy — you need &lt;code&gt;output: "export"&lt;/code&gt; and a wrangler config), but for a site that's truly static the trade is worth it.&lt;/p&gt;

&lt;p&gt;I tried &lt;code&gt;@opennextjs/cloudflare&lt;/code&gt; first because Cheapstack started life as a dynamic Next.js app with edge runtime OG images. Two days of debugging dynamic-route 404s later, I realized I didn't need any of that. Pre-generating the OG image as a 1200x420 PNG and switching to plain static export resolved everything in 30 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; if your site has no per-user state and no per-request logic, static export beats every adapter. Adapter complexity buys you flexibility you don't have.&lt;/p&gt;

&lt;h2&gt;
  
  
  The content layer
&lt;/h2&gt;

&lt;p&gt;I went into this thinking I'd write everything from scratch. Then I realized the actual work was structuring the data so the prose was a thin layer on top.&lt;/p&gt;

&lt;p&gt;Every tool on the site lives in one file:&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;// src/lib/tools.ts&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ToolCategory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;pricing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;usd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;verified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}[];&lt;/span&gt;
  &lt;span class="nl"&gt;affiliate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ... more fields&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TOOLS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Tool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;digitalocean&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="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;postmark&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="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;// ~70 tools&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stack guides, comparison pages, and tool roundups all pull from this single registry. When DigitalOcean changes their pricing, I update one entry and 11 pages reflect it. When an affiliate program approves me, I drop the tracking URL into the &lt;code&gt;affiliate&lt;/code&gt; field and every link to that tool across the site updates.&lt;/p&gt;

&lt;p&gt;This is mundane infrastructure but it's the difference between a site that decays in 3 months and a site that stays accurate for years.&lt;/p&gt;

&lt;h2&gt;
  
  
  Affiliate programs: the reality of being new
&lt;/h2&gt;

&lt;p&gt;I applied to 12 affiliate programs in week one. Here's the score so far:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Program&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DigitalOcean (via Awin)&lt;/td&gt;
&lt;td&gt;Declined — "site too new"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Squarespace (via Impact / Acceleration Partners)&lt;/td&gt;
&lt;td&gt;Declined — "site not yet live or traffic levels below necessary"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hostinger (direct)&lt;/td&gt;
&lt;td&gt;Pending review, day 4 of 3–7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8 other Impact-network brands&lt;/td&gt;
&lt;td&gt;Auto-deferred 30–60 days&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So far: 0 approved, 2 declined, 1 pending, 9 deferred. The "site too new" pattern across every network was demoralizing — I'd built the whole monetization architecture on the assumption that applying with a live, polished site would be enough.&lt;/p&gt;

&lt;p&gt;It's not. Affiliate networks gate on traffic signal, not site quality. The site needs to show up in Google for 30+ days with consistent search clicks before most programs unlock.&lt;/p&gt;

&lt;p&gt;This was a real lesson: &lt;strong&gt;the FTC disclosures on cheapstack are mostly aspirational at the moment.&lt;/strong&gt; Every tool link has &lt;code&gt;rel="sponsored nofollow noopener"&lt;/code&gt; and a clear disclosure — even though most of them don't pay me anything. I left the architecture in because (a) when programs do approve me, the wiring is already there, and (b) the credibility hit of &lt;em&gt;adding&lt;/em&gt; affiliate disclosures later would be worse than declaring intent on day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually on the site
&lt;/h2&gt;

&lt;p&gt;For the curious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;6 stack guides&lt;/strong&gt; — itemized monthly bills for SaaS-100 (~87 USD/mo), MVP-50, marketplace-150, course-100, newsletter-25, landing-15&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 comparisons&lt;/strong&gt; — Firebase vs Supabase, Postmark vs Resend, Beehiiv vs Ghost, Neon vs PlanetScale, Clerk vs Auth.js, Vercel vs Cloudflare Pages, Stripe vs Lemon Squeezy, Stripe vs Paddle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;12 tool roundups&lt;/strong&gt; — hosting, databases, transactional email, newsletter platforms, domain registrars, SEO tools, CRM, landing builders, payments, analytics, headless CMS, auth services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 framework deep-dives&lt;/strong&gt; — Next.js, Astro, SvelteKit, Remix, Nuxt, SolidStart, Qwik, RedwoodSDK&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything's at &lt;a href="https://cheapstack.dev" rel="noopener noreferrer"&gt;cheapstack.dev&lt;/a&gt; if you want to see how it shipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  Early signal
&lt;/h2&gt;

&lt;p&gt;Four days post-launch, before any external traffic push:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Search Console: 41 impressions, position 12.1 average&lt;/li&gt;
&lt;li&gt;Indexed: 8 of 47 pages (normal week-1 curve)&lt;/li&gt;
&lt;li&gt;Most interesting query: "affordable node.js headless cms under 50/month" — exactly the kind of long-tail commercial-intent query the site was designed for&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Position 12 means page 2 of Google. With backlinks and another month of indexing it could realistically move to page 1 for that query. That's the whole game.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Skip the OpenNext adapter entirely.&lt;/strong&gt; Static export from day one. Two days saved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply to affiliate programs only after 30 days of traffic.&lt;/strong&gt; Day-one applications are a coin flip and rejection cool-down windows are 60–90 days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write less, structure more.&lt;/strong&gt; The articles that are working are the ones with strong data tables and clean comparisons. Prose-heavy pieces sit in the middle of the rankings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start the newsletter on day one.&lt;/strong&gt; I held off until "the site was ready." That was wrong. The newsletter is the only thing you actually own — everything else (Google rank, affiliate approvals, social reach) is rented from someone else.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;More long-tail comparison pages targeting the queries already showing up in GSC&lt;/li&gt;
&lt;li&gt;A weekly newsletter when I cross 100 organic visits/day&lt;/li&gt;
&lt;li&gt;Real receipts from working indie builds (if you're running profitable on a 50–200 USD/mo stack, I'd love to feature your build — with permission)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've built anything similar — editorial site, affiliate engine, programmatic SEO play — I'd love to hear what worked and what didn't. The two-week timeline only worked because I made a lot of decisions fast; some of them are probably wrong.&lt;/p&gt;

&lt;p&gt;Site: &lt;a href="https://cheapstack.dev" rel="noopener noreferrer"&gt;cheapstack.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>indiehackers</category>
      <category>webdev</category>
      <category>saas</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
