<?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: Diogo Abreu</title>
    <description>The latest articles on DEV Community by Diogo Abreu (@diogoabreudev).</description>
    <link>https://dev.to/diogoabreudev</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%2F3882546%2Ff1912950-c1b3-4956-98c9-bc60b5201fe6.jpeg</url>
      <title>DEV Community: Diogo Abreu</title>
      <link>https://dev.to/diogoabreudev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/diogoabreudev"/>
    <language>en</language>
    <item>
      <title>How I went from getting tired of explaining the same things to AI, to developing a cutting edge solution, to accidentally creating a brand</title>
      <dc:creator>Diogo Abreu</dc:creator>
      <pubDate>Wed, 06 May 2026 09:00:00 +0000</pubDate>
      <link>https://dev.to/diogoabreudev/how-i-went-from-getting-tired-of-explaining-the-same-things-to-ai-to-developing-a-cutting-edge-fjp</link>
      <guid>https://dev.to/diogoabreudev/how-i-went-from-getting-tired-of-explaining-the-same-things-to-ai-to-developing-a-cutting-edge-fjp</guid>
      <description>&lt;p&gt;There’s a moment every developer hits when “AI-assisted coding” starts feeling less like acceleration and more like friction.&lt;/p&gt;

&lt;p&gt;For me, that moment came somewhere between deleting yet another &lt;code&gt;useEffect&lt;/code&gt;-based data fetch and watching Cursor confidently generate a &lt;code&gt;tailwind.config.js&lt;/code&gt; file in a project that absolutely did not need one.&lt;/p&gt;

&lt;p&gt;That loop kept repeating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wrong patterns&lt;/li&gt;
&lt;li&gt;Outdated APIs&lt;/li&gt;
&lt;li&gt;Defaults that no longer reflect how modern apps are built&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the more cutting-edge the stack became—&lt;strong&gt;Next.js 16, React 19, Tailwind v4&lt;/strong&gt;—the worse it got.&lt;/p&gt;

&lt;p&gt;So I stopped fixing the symptoms and built my own rules pack instead.&lt;br&gt;
Afterwards, I wanted to have some place that I could centralize it and future digital products and tools.&lt;/p&gt;

&lt;p&gt;That place became &lt;strong&gt;Saastenance&lt;/strong&gt;—and this post is both a technical deep dive and the story of how a small dev tool quietly turned into a full digital product and part of a brand.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Real Problem: AI Is Only As Good As Its Defaults
&lt;/h2&gt;

&lt;p&gt;Tools like Cursor and Claude Code don’t “understand” your stack—they pattern match based on training data.&lt;/p&gt;

&lt;p&gt;And most of that data is already outdated.&lt;/p&gt;

&lt;p&gt;So unless you explicitly constrain them, they will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reintroduce deprecated patterns&lt;/li&gt;
&lt;li&gt;Ignore new framework primitives&lt;/li&gt;
&lt;li&gt;Drift away from your architecture over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I needed wasn’t better prompts.&lt;/p&gt;

&lt;p&gt;I needed &lt;strong&gt;persistent, enforceable rules&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Enter: The AI Rules Pack
&lt;/h2&gt;

&lt;p&gt;The AI Rules Pack is a structured set of rules (in &lt;code&gt;.mdc&lt;/code&gt; format) that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defines how your AI should think&lt;/li&gt;
&lt;li&gt;Locks in modern best practices&lt;/li&gt;
&lt;li&gt;Prevents regression into outdated patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It works with Cursor, Claude Code, and OpenAI Codex. It installs via a CLI where you choose your stack preferences.&lt;/p&gt;

&lt;p&gt;But the interesting part—the &lt;em&gt;reason it exists&lt;/em&gt;—comes from how &lt;strong&gt;Next.js 16 broke a lot of assumptions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let’s walk through that.&lt;/p&gt;


&lt;h2&gt;
  
  
  Breaking Changes in Next.js 16 (That AI Keeps Getting Wrong)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Data Fetching: &lt;code&gt;useEffect&lt;/code&gt; Is No Longer the Default
&lt;/h3&gt;
&lt;h4&gt;
  
  
  ❌ Before (what AI still generates)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  ✅ After (Next.js 16 pattern)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Why this matters
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Server Components are the default&lt;/li&gt;
&lt;li&gt;Fetching happens on the server&lt;/li&gt;
&lt;li&gt;No client waterfall, no loading flicker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yet AI still defaults to client-side fetching unless told otherwise.&lt;/p&gt;


&lt;h3&gt;
  
  
  2. Server Actions Replace Client Mutation Logic
&lt;/h3&gt;
&lt;h4&gt;
  
  
  ❌ Before
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  ✅ After
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormData&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;use server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

  &lt;span class="c1"&gt;// direct DB call or mutation&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Why this matters
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;No API route needed&lt;/li&gt;
&lt;li&gt;No client fetch boilerplate&lt;/li&gt;
&lt;li&gt;Stronger co-location of logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI often mixes both patterns—which creates unnecessary complexity.&lt;/p&gt;


&lt;h3&gt;
  
  
  3. &lt;code&gt;middleware.ts&lt;/code&gt; Is No Longer Your Auth Layer
&lt;/h3&gt;

&lt;p&gt;This one shows up constantly.&lt;/p&gt;
&lt;h4&gt;
  
  
  ❌ Before
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// middleware.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// auth logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  ✅ After
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;route handlers&lt;/strong&gt;, &lt;strong&gt;server actions&lt;/strong&gt;, or &lt;strong&gt;framework-native auth solutions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Middleware is now edge-specific and limited&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Why this matters
&lt;/h4&gt;

&lt;p&gt;AI overuses middleware because it used to be a catch-all solution.&lt;/p&gt;

&lt;p&gt;In modern apps, it's usually the wrong tool.&lt;/p&gt;


&lt;h3&gt;
  
  
  4. Tailwind v4: No &lt;code&gt;tailwind.config.js&lt;/code&gt;
&lt;/h3&gt;
&lt;h4&gt;
  
  
  ❌ Before
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;extend&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  ✅ After
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Zero-config by default&lt;/li&gt;
&lt;li&gt;CSS-first configuration
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@theme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Why this matters
&lt;/h4&gt;

&lt;p&gt;AI still scaffolds Tailwind like it's 2021.&lt;/p&gt;

&lt;p&gt;That leads to unnecessary files and wrong mental models.&lt;/p&gt;


&lt;h3&gt;
  
  
  5. Forms: &lt;code&gt;useFormState&lt;/code&gt; Is Not the Move
&lt;/h3&gt;
&lt;h4&gt;
  
  
  ❌ Before
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formAction&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  ✅ After
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Use native &lt;code&gt;&amp;lt;form action={serverAction}&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Or lightweight client validation where needed&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Why this matters
&lt;/h4&gt;

&lt;p&gt;React 19 + Server Actions changed the ergonomics completely.&lt;/p&gt;

&lt;p&gt;Yet AI keeps reaching for older abstractions.&lt;/p&gt;


&lt;h3&gt;
  
  
  6. Routing + Layout Assumptions
&lt;/h3&gt;

&lt;p&gt;AI still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overuses client components&lt;/li&gt;
&lt;li&gt;Misplaces logic in layouts&lt;/li&gt;
&lt;li&gt;Avoids async components&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  ✅ Modern expectation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Layouts are server-first&lt;/li&gt;
&lt;li&gt;Components are async by default&lt;/li&gt;
&lt;li&gt;Client components are opt-in&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Pattern Behind the Problems
&lt;/h2&gt;

&lt;p&gt;None of these issues are “bugs.”&lt;/p&gt;

&lt;p&gt;They’re &lt;strong&gt;default mismatches&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;AI is trained on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Older Next.js versions&lt;/li&gt;
&lt;li&gt;Mixed patterns&lt;/li&gt;
&lt;li&gt;Transitional APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So unless you enforce constraints, it will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blend paradigms&lt;/li&gt;
&lt;li&gt;Reintroduce deprecated logic&lt;/li&gt;
&lt;li&gt;Slow your team down&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Solution: Encode Your Standards
&lt;/h2&gt;

&lt;p&gt;That’s what the AI Rules Pack does.&lt;/p&gt;

&lt;p&gt;Instead of correcting AI every time, you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define rules once&lt;/li&gt;
&lt;li&gt;Apply them automatically&lt;/li&gt;
&lt;li&gt;Keep outputs consistent across projects&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Example Rule (Conceptually)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- NEVER use useEffect for data fetching
- ALWAYS prefer server components
- USE server actions for mutations
- DO NOT create tailwind.config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now scale that across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture decisions&lt;/li&gt;
&lt;li&gt;Naming conventions&lt;/li&gt;
&lt;li&gt;Library choices&lt;/li&gt;
&lt;li&gt;Auth/data patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s where this becomes powerful.&lt;/p&gt;


&lt;h2&gt;
  
  
  The &lt;code&gt;nextjs-core.mdc&lt;/code&gt; (Free)
&lt;/h2&gt;

&lt;p&gt;Here’s the free core rules file for Next.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// nextjs-core.mdc
---
description: Next.js 16 Cache Components — "use cache" directive, cacheLife profiles, cacheTag, updateTag, refresh, and the new caching mental model
globs: "**/*.ts,**/*.tsx"
alwaysApply: true
---

## Next.js 16 — Cache Components

### The New Mental Model

In Next.js 16 with `cacheComponents: true`, **everything is dynamic by default**. Caching is entirely opt-in. This is the opposite of Next.js 13-15 where `fetch()` was cached by default and you had to opt out.

Old model (Next.js 13-15):

- `fetch()` → cached by default
- Add `cache: 'no-store'` to opt out
- `export const revalidate = 60` for ISR
- Confusing implicit behaviour

New model (Next.js 16 Cache Components):

- Everything dynamic by default
- Add `"use cache"` to opt into caching
- `cacheLife()` sets the duration
- `cacheTag()` enables on-demand invalidation
- Explicit, predictable, composable

### Setup

(add ts code block tags here)
// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  cacheComponents: true,

  // Optional: define custom profiles
  cacheLife: {
    products: { stale: 300, revalidate: 900, expire: 86400 },
    dashboard: { stale: 60, revalidate: 300, expire: 3600 },
    blog: { stale: 3600, revalidate: 900, expire: 86400 },
    realtime: { stale: 0, revalidate: 10, expire: 60 },
  },
};

export default nextConfig;
(close code blocks)

### The `"use cache"` Directive

Add at the top of any async function, component, page, or layout to make it cacheable.

(add ts code block tags here)
import { cacheLife, cacheTag } from "next/cache"

// Cache a data access function
export async function getProducts(category: string) {
  "use cache"
  cacheLife("hours")
  cacheTag("products", `category-${category}`)
  // arguments automatically become part of the cache key
  // getProducts("shoes") and getProducts("hats") are separate cache entries
  return db.query.products.findMany({ where: { category } })
}

// Cache a Server Component
async function FeaturedProducts() {
  "use cache"
  cacheLife("hours")
  cacheTag("products")
  const products = await db.query.products.findMany({ where: { featured: true } })
  return (
    &amp;lt;ul&amp;gt;
      {products.map(p =&amp;gt; &amp;lt;ProductCard key={p.id} product={p} /&amp;gt;)}
    &amp;lt;/ul&amp;gt;
  )
}

// Cache an entire page
export default async function BlogPage() {
  "use cache"
  cacheLife("days")
  const posts = await getPosts()
  return &amp;lt;PostList posts={posts} /&amp;gt;
}

// Cache a layout
export default async function MarketingLayout({ children }: { children: React.ReactNode }) {
  "use cache"
  cacheLife("max")
  const nav = await getNavLinks()
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Nav links={nav} /&amp;gt;
      {children}
    &amp;lt;/div&amp;gt;
  )
}
(close code blocks)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This alone eliminates a huge percentage of bad AI output.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Dev Tool → Product → Brand
&lt;/h2&gt;

&lt;p&gt;Originally, this wasn’t meant to be a product.&lt;/p&gt;

&lt;p&gt;It was just a personal fix.&lt;/p&gt;

&lt;p&gt;But then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I made it reusable&lt;/li&gt;
&lt;li&gt;Added a CLI installer&lt;/li&gt;
&lt;li&gt;Wrote documentation&lt;/li&gt;
&lt;li&gt;Structured it for different stacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And at some point, I realized:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How am I going to centralize this product and other side projects so people know what they're getting?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s when &lt;strong&gt;Saastenance&lt;/strong&gt; was born.&lt;/p&gt;

&lt;p&gt;Not just for this pack—but as a storefront for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developer tools&lt;/li&gt;
&lt;li&gt;AI workflows&lt;/li&gt;
&lt;li&gt;Opinionated systems that reflect how things are &lt;em&gt;actually built&lt;/em&gt; today&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What You Get
&lt;/h2&gt;

&lt;p&gt;The AI Rules Pack includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full rule sets for modern frontend SaaS&lt;/li&gt;
&lt;li&gt;Cursor + Claude Code + OpenAI Codex compatibility&lt;/li&gt;
&lt;li&gt;CLI installer (one command setup)&lt;/li&gt;
&lt;li&gt;Stack customization&lt;/li&gt;
&lt;li&gt;Git commit conventions for automatic commit message suggestions&lt;/li&gt;
&lt;li&gt;Complementary Cursor Memories guide&lt;/li&gt;
&lt;li&gt;Documentation + usage guide&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s designed to answer one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“How do I make AI code like a senior developer on my team?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Launch Offer
&lt;/h2&gt;

&lt;p&gt;To celebrate the launch, I’m offering:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30% off with code: &lt;code&gt;SAASTELAUNCH30&lt;/code&gt; (valid through May)&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;AI isn’t replacing developers.&lt;/p&gt;

&lt;p&gt;But developers who &lt;strong&gt;systemize AI&lt;/strong&gt; will replace those who don’t.&lt;/p&gt;

&lt;p&gt;You can keep correcting outputs…&lt;/p&gt;

&lt;p&gt;Or you can define the rules once—and never fight the same battle again.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get the Full Pack
&lt;/h2&gt;

&lt;p&gt;👉 &lt;a href="https://saastenance.com/products/ai-rules-pack-frontend-development" rel="noopener noreferrer"&gt;https://saastenance.com/products/ai-rules-pack-frontend-development&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you're building with modern frontend tools, this will save you hours—and a lot of frustration.&lt;/p&gt;

&lt;p&gt;And if nothing else, hopefully this gave you a clearer picture of how &lt;strong&gt;Next.js 16 is reshaping the way we write frontend code&lt;/strong&gt;—and why your AI might still be living in the past.&lt;/p&gt;

</description>
      <category>promptengineering</category>
      <category>ai</category>
      <category>frontend</category>
      <category>saas</category>
    </item>
    <item>
      <title>How to safely parse, merge, or generate .env files (without uploading secrets online)</title>
      <dc:creator>Diogo Abreu</dc:creator>
      <pubDate>Fri, 17 Apr 2026 16:00:00 +0000</pubDate>
      <link>https://dev.to/diogoabreudev/how-to-safely-parse-merge-or-generate-env-files-without-uploading-secrets-online-1cbh</link>
      <guid>https://dev.to/diogoabreudev/how-to-safely-parse-merge-or-generate-env-files-without-uploading-secrets-online-1cbh</guid>
      <description>&lt;p&gt;Working with .env files is something we all do, but it’s surprisingly easy to make mistakes.&lt;/p&gt;

&lt;p&gt;Duplicate keys, malformed values, missing quotes… they can be annoying to debug.&lt;/p&gt;

&lt;p&gt;At some point I thought:&lt;br&gt;
“Why isn’t there a simple tool that does all the work for me?”&lt;/p&gt;

&lt;p&gt;Then I realized something else:&lt;br&gt;
An online .env viewer sounds like a &lt;strong&gt;terrible idea&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If I saw one, I’d assume it’s stealing companys' keys.&lt;/p&gt;

&lt;p&gt;So I built one with a constraint:&lt;br&gt;
Everything must &lt;strong&gt;run 100% in the browser&lt;/strong&gt; and be &lt;strong&gt;100% safe&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No uploads&lt;/li&gt;
&lt;li&gt;No backend&lt;/li&gt;
&lt;li&gt;No storage&lt;/li&gt;
&lt;li&gt;No network requests at all&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All very highlighted and verifiable through devtools.&lt;/p&gt;

&lt;p&gt;The result is a small tool that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parses .env files instantly&lt;/li&gt;
&lt;li&gt;Detects duplicate keys&lt;/li&gt;
&lt;li&gt;Highlights syntax issues&lt;/li&gt;
&lt;li&gt;Shows everything in a clean table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, I included some other pages to &lt;strong&gt;merge&lt;/strong&gt; multiple .env files together, or to &lt;strong&gt;generate&lt;/strong&gt; a fresh .env file with the most commonly used keys.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://env-tools.vercel.app/" rel="noopener noreferrer"&gt;https://env-tools.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’d really appreciate some feedback, especially on how to make the “this is safe” part clearer. Hope this tool is useful and thank you very much in advance!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>frontend</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
