<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Bugster]]></title><description><![CDATA[The AI QA Engineer]]></description><link>https://newsletter.bugster.dev</link><image><url>https://substackcdn.com/image/fetch/$s_!d5w4!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15a0e52f-b918-4606-871c-a7a81d61c598_1280x1280.png</url><title>Bugster</title><link>https://newsletter.bugster.dev</link></image><generator>Substack</generator><lastBuildDate>Thu, 14 May 2026 09:46:50 GMT</lastBuildDate><atom:link href="https://newsletter.bugster.dev/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Bugster]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[bugsterdev@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[bugsterdev@substack.com]]></itunes:email><itunes:name><![CDATA[Bugster]]></itunes:name></itunes:owner><itunes:author><![CDATA[Bugster]]></itunes:author><googleplay:owner><![CDATA[bugsterdev@substack.com]]></googleplay:owner><googleplay:email><![CDATA[bugsterdev@substack.com]]></googleplay:email><googleplay:author><![CDATA[Bugster]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[E2E Testing: What It Actually Is (And Why You Probably Need It)]]></title><description><![CDATA[Understanding end-to-end testing, when to use it, and why it catches bugs that unit tests miss. Learn how E2E testing validates complete user workflows and prevents production failures.]]></description><link>https://newsletter.bugster.dev/p/e2e-testing-what-it-actually-is-and</link><guid isPermaLink="false">https://newsletter.bugster.dev/p/e2e-testing-what-it-actually-is-and</guid><dc:creator><![CDATA[Bugster]]></dc:creator><pubDate>Mon, 13 Oct 2025 14:18:26 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b1f47be4-c544-4930-bff6-223e8b08b986_2784x1858.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4><strong>Why Your Unit Tests Aren&#8217;t Enough (And What You&#8217;re Missing)</strong></h4><p>Your unit tests pass. Integration tests are green. You deploy to production... and users report the checkout flow is broken.</p><p>We&#8217;ve all been there. The problem? Most testing strategies have a critical blind spot: they test individual pieces but never validate if those pieces actually work together from a user&#8217;s perspective.</p><p></p><h4><strong>What E2E Testing Really Means</strong></h4><p>End-to-end testing validates your application exactly how users experience it - from first click to final action. While unit tests check if LEGO pieces are well-made, E2E tests confirm the entire castle actually stands up.</p><p></p><h4><strong>The Bugs You&#8217;re Missing</strong></h4><p>Without E2E testing, you&#8217;re shipping:</p><p>Race conditions that only appear when operations run simultaneously</p><p>Browser-specific bugs that work in Chrome but fail in Safari</p><p>State leakage where components corrupt shared state</p><p>Real-world edge cases like users clicking buttons multiple times or refreshing during submission</p><p></p><h4><strong>When You Actually Need E2E Testing</strong></h4><p>Your application critically needs E2E testing if it has:</p><p>&#128722; Complex user flows (checkout, onboarding, multi-step forms)</p><p>&#128176; Third-party integrations (payment processors, auth providers)</p><p>&#128188; Complex state management (shopping carts, session handling)</p><p>&#128272; Authentication flows that touch multiple systems</p><p>E-commerce, SaaS, fintech, and healthcare platforms can&#8217;t afford to skip this.</p><p></p><h4><strong>The Modern Approach</strong></h4><p>Traditional E2E testing was a maintenance nightmare. Modern solutions use AI to:</p><p>Self-heal tests when UI changes</p><p>Generate tests automatically from your codebase</p><p>Understand context and stress-test the code you actually modified</p><p>Eliminate flaky tests with intelligent waiting</p><p></p><h4><strong>Bottom Line</strong></h4><p>Your users don&#8217;t care about your unit tests. They care that your app works.</p><p>E2E testing validates what actually matters: the complete user experience.</p><div><hr></div><p>Want to dive deeper? Read the full article to learn:</p><ul><li><p>When NOT to use E2E testing</p></li><li><p>How to build an effective E2E strategy</p></li><li><p>Common mistakes (and how to avoid them)</p></li><li><p>The real ROI of E2E testing</p></li></ul><p>Read the Complete Guide: <a href="https://www.bugster.dev/blog/e2e-testing-what-it-actually-is-and-why-you-probably-need-it">https://www.bugster.dev/blog/e2e-testing-what-it-actually-is-and-why-you-probably-need-it</a></p><div><hr></div><p>Test the experience, not just the code.</p><p>The Bugster Team</p>]]></content:encoded></item><item><title><![CDATA[Bugster vs. AI Code Review Tools: The Real Browser Advantage]]></title><description><![CDATA[Why testing your app like a real user complements analyzing code for comprehensive bug detection]]></description><link>https://newsletter.bugster.dev/p/bugster-vs-ai-code-review-tools-the</link><guid isPermaLink="false">https://newsletter.bugster.dev/p/bugster-vs-ai-code-review-tools-the</guid><dc:creator><![CDATA[Bugster]]></dc:creator><pubDate>Thu, 11 Sep 2025 20:52:43 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f0f4b2a7-a86e-4d36-8eed-b49bf30cb5a3_1770x822.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Why This Comparison Matters</h2><p>In frontend development, not all bugs are created equal. <strong>AI Code Review tools</strong> analyze your diff and examine code semantics, while <strong>AI E2E Testing tools</strong> execute your app like real users do.</p><p>Think of it like this: one tool reads your recipe, the other actually cooks the dish. Both approaches are valuable, but they surface very different kinds of mistakes. Understanding this split helps you build a bug detection strategy that doesn&#8217;t leave blind spots.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.bugster.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>What AI Code Review Tools Do (Greptile, BugBot, CodeRabbit)</h2><p>AI Code Review tools plug directly into your PRs. They analyze code semantics, logic patterns, guards, and validations. Their strength? Catching <strong>deterministic bugs in your source code</strong> before it ever ships.</p><p>Take <strong>Greptile</strong>: it understands your entire codebase context and spots complex logic errors, security vulnerabilities, and architectural anti-patterns that human reviewers often miss.</p><p><strong>What these tools excel at:</strong></p><ul><li><p>Logic and control flow errors</p></li><li><p>Security vulnerabilities (SQL injection, XSS in code)</p></li><li><p>Code quality and maintainability issues</p></li><li><p>Architectural anti-patterns</p></li><li><p>Type safety and null reference errors</p></li><li><p>Dead code and redundancy detection</p></li></ul><p>In short: they&#8217;re like having a super-powered static analysis reviewer who never gets tired.</p><div><hr></div><h2>What AI E2E Testing Tools Do (Bugster)</h2><p>AI E2E tools like <strong>Bugster</strong> go down a different path: instead of reading your recipe, they step into the kitchen. Bugster spins up real browsers, navigates your app, clicks the buttons, fills the forms, and validates what happens in the messy, real-world runtime.</p><p>Bugster&#8217;s <strong>destructive agent</strong> adds another layer: it looks at your PR changes and stress-tests those modified areas directly. That means your new features and fixes get hammered under realistic conditions before users ever touch them.</p><p><strong>What Bugster excels at:</strong></p><ul><li><p>User interaction flows and state consistency</p></li><li><p>Visual layout and responsive design issues</p></li><li><p>Real browser runtime errors</p></li><li><p>End-to-end user flows with external services</p></li><li><p>Performance under real network conditions</p></li></ul><div><hr></div><h2>Bug Detection Matrix: What Each Tool Actually Catches</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TUkt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TUkt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png 424w, https://substackcdn.com/image/fetch/$s_!TUkt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png 848w, https://substackcdn.com/image/fetch/$s_!TUkt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png 1272w, https://substackcdn.com/image/fetch/$s_!TUkt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TUkt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png" width="857" height="648" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:648,&quot;width&quot;:857,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:81980,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.bugster.dev/i/173389731?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TUkt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png 424w, https://substackcdn.com/image/fetch/$s_!TUkt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png 848w, https://substackcdn.com/image/fetch/$s_!TUkt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png 1272w, https://substackcdn.com/image/fetch/$s_!TUkt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e086dc1-6afd-4500-99eb-137ac12c5261_857x648.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is the core tradeoff: static tools safeguard your code logic; real-browser tools safeguard your user experience.</p><div><hr></div><h2>Illustrative Cases: When Each Tool Shines</h2><h3>Case 1: Authentication Token Expiration</h3><p><strong>The Code (passes all static analysis):</strong></p><pre><code><code>// This looks perfect to AI Code Review Tools
const AuthProvider = ({ children }) =&gt; {
  const [token, setToken] = useState(localStorage.getItem('token'));

  const refreshToken = async () =&gt; {
    const response = await fetch('/api/refresh');
    const newToken = await response.json();
    setToken(newToken);
  };

  return (
    &lt;AuthContext.Provider value={{ token, refreshToken }}&gt;
      {children}
    &lt;/AuthContext.Provider&gt;
  );
};

</code></code></pre><p><strong>What AI Code Review Tools catches:</strong> Logic is sound, no security vulnerabilities in code</p><p><strong>What Bugster catches:</strong></p><ul><li><p>User gets logged out mid-checkout because token expires</p></li><li><p>Refresh mechanism fails on slow connections</p></li><li><p>User loses form data when authentication redirects occur</p></li><li><p>Error messages don't appear properly when auth fails</p></li></ul><h3>Case 2: Calendar End-of-Month Edge Case</h3><p><strong>The Code (perfect logic according to static analysis):</strong></p><pre><code><code>// AI Code Review Tools sees no issues here
function getNextAvailableDate(currentDate) {
  const next = new Date(currentDate);
  next.setDate(next.getDate() + 1);
  return next;
}

</code></code></pre><p><strong>What AI Code Review Tools catches:</strong> The date logic is mathematically correct</p><p><strong>What Bugster catches:</strong></p><ul><li><p>Calendar breaks when users select January 31st (next month has no 31st)</p></li><li><p>Date picker shows impossible dates in February</p></li><li><p>Timezone shifts cause booking conflicts</p></li><li><p>Mobile date picker has different behavior than desktop</p></li></ul><h3>Case 3: Third-Party Checkout Integration</h3><p><strong>The Code (passes all code review standards):</strong></p><pre><code><code>// AI Code Review Tools approves this implementation
const processPayment = async (paymentData) =&gt; {
  try {
    const result = await stripe.createPaymentIntent(paymentData);
    return { success: true, paymentIntent: result };
  } catch (error) {
    return { success: false, error: error.message };
  }
};

</code></code></pre><p><strong>What AI Code Review Tools catches:</strong> Error handling is properly implemented, no obvious security issues</p><p><strong>What Bugster catches:</strong></p><ul><li><p>Stripe modal doesn't load on slow 3G connections</p></li><li><p>Payment succeeds but confirmation page fails to load</p></li><li><p>Users can double-click and create duplicate charges</p></li><li><p>Payment form breaks when browser blocks third-party scripts</p></li><li><p>Success/failure states don't update UI properly</p></li></ul><div><hr></div><h2>The Complementary Strategy: AI Code Review + Bugster</h2><p>This isn&#8217;t about picking sides. The strongest teams layer both approaches.</p><p><strong>1. Pre-Commit: AI Code Review</strong></p><ul><li><p>Catches logic errors, security vulnerabilities, and quality issues</p></li><li><p>Instant feedback in PR workflow</p></li></ul><p><strong>2. Pre-Deploy: AI E2E Testing (Bugster)</strong></p><ul><li><p>Validates user experience in real browsers</p></li><li><p>Exercises integrations, state, and UX edge cases</p></li></ul><h3>Ideal CI/CD Pipeline:</h3><pre><code><code>&#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
&#9474;   Code Review   &#9474;  &#8592; Greptile, BugBot catch logic
&#9474; Static Analysis &#9474;    &amp; security bugs in source code
&#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
         &#8595;
&#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
&#9474;  Real Browser   &#9474;  &#8592; Bugster catches user experience
&#9474;     Testing     &#9474;    bugs in actual environment
&#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
         &#8595;
&#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
&#9474;   Production    &#9474;  &#8592; Maximum bug prevention
&#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;

</code></code></pre><p><strong>Call to Action:</strong> Activate both layers: AI code reviewer on PRs + Bugster on preview environments for your 5 core user flows. This combination gives you comprehensive coverage from code quality to user experience.</p><div><hr></div><h2>Conclusion: Two Tools, One Mission</h2><p><strong>AI Code Review Tools</strong> keep your codebase logically sound and secure. <strong>Bugster</strong> ensures that sound code translates into a seamless user experience.</p><p>The future of frontend isn&#8217;t static analysis <em>or</em> real browser testing, it&#8217;s both. Together, they give you confidence from commit to production.</p><p><em>Ready to see what your code reviewers can&#8217;t? Try <a href="https://www.bugster.dev/">Bugster&#8217;s</a> destructive testing on your next PR and find the UX bugs hiding in plain sight.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.bugster.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Prompt caching: how we reduced LLM spend by 60x (and Get 20 % Faster Responses) ]]></title><description><![CDATA[TL;DR &#8212; Caching the static prompt prefix (tools + system + stable memory) in our E2E testing agent delivered 60x lower cost per test and ~20% lower p95 latency, with the same "accuracy".]]></description><link>https://newsletter.bugster.dev/p/prompt-caching-how-we-reduced-llm</link><guid isPermaLink="false">https://newsletter.bugster.dev/p/prompt-caching-how-we-reduced-llm</guid><dc:creator><![CDATA[Bugster]]></dc:creator><pubDate>Wed, 13 Aug 2025 15:02:19 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/286b1af2-e3e4-4587-912b-6749d1be07fe_1648x840.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gLVZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gLVZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png 424w, https://substackcdn.com/image/fetch/$s_!gLVZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png 848w, https://substackcdn.com/image/fetch/$s_!gLVZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png 1272w, https://substackcdn.com/image/fetch/$s_!gLVZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gLVZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png" width="1456" height="764" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:764,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2581693,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://newsletter.bugster.dev/i/170880554?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gLVZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png 424w, https://substackcdn.com/image/fetch/$s_!gLVZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png 848w, https://substackcdn.com/image/fetch/$s_!gLVZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png 1272w, https://substackcdn.com/image/fetch/$s_!gLVZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf153abe-991e-485f-bc39-9e1a3dac9f49_3696x1940.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2>Context</h2><p>Bugster is an agent that <strong>drives a real browser</strong> to test apps end-to-end. That means <strong>multi-step loops</strong> with a lot of repeated context: tools, rules, DOM summaries, session state.</p><p>Ahead of our Product Hunt launch we ran a one-hour stress test (users + synthetic load). Functionally we were solid (TCR <strong>80.2%</strong>), but two things popped:</p><ol><li><p>We were <strong>hitting the max Input Tokens/min</strong> on our top LLM tier.</p></li><li><p><strong>Cost/test</strong> was too high to scale.</p></li></ol><p>Queues? Bad DX. Heavy memory pruning? Risky this close to launch. We needed a <strong>surgical</strong> win.</p><h2>The lever: prompt caching</h2><p>Prompt caching lets the API reuse the <strong>prefix</strong> you repeat across calls. In Claude, the cached prefix is evaluated in this order: <strong>tools &#8594; system &#8594; messages</strong> (i.e., everything <strong>before</strong> your cache breakpoint). You mark that breakpoint with <code>cache_control</code>. <a href="https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching">Anthropic</a></p><p><strong>Why it works:</strong></p><ul><li><p><strong>First call</strong>: you pay a small write premium on the cached prefix.</p></li><li><p><strong>Subsequent calls</strong>: you pay <strong>~10% of base input</strong> for the cached part (cheap) and full price only for the <strong>delta</strong> you add. Pricing multipliers are documented. <a href="https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching">Anthropic</a></p></li></ul><p>Since <strong>Mar 13, 2025</strong>, Claude <strong>doesn&#8217;t count cache-read tokens toward ITPM</strong> on 3.7 Sonnet &#8594; more throughput <strong>without</strong> changing tiers. OTPM is unchanged.</p><div><hr></div><h2>Results in our agent</h2><ul><li><p><strong>Cost</strong>: 60x reduction per test (depends on how prefix-heavy the loop is).</p></li><li><p><strong>Latency</strong>: <strong>&#8722;20% p95</strong> (less work per request + less queuing at ITPM).</p></li><li><p><strong>Quality</strong>: TCR stayed flat (80.1&#8211;80.5%).</p></li><li><p><strong>Rate limits</strong>: no longer spiking ITPM thanks to cache-aware reads. <a href="https://www.anthropic.com/news/token-saving-updates?utm_source=chatgpt.com">Anthropic</a></p></li></ul><blockquote><p>Reality check: the <strong>documented ceiling</strong> on <em>input</em> savings is about <strong>10&#215;</strong> (cache read &#8776; 0.1&#215; base input; write &#8776; 1.25&#215; for 5-min TTL or 2&#215; for 1-hour TTL). Your <strong>overall</strong> test cost reduction depends on output tokens and how much of your prompt is cacheable. <a href="https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching">Anthropic</a></p></blockquote><div><hr></div><h2>Quick implementation (TypeScript, Claude Messages API)</h2><pre><code>import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

// 1) Define tools as usual (these are part of the prefix, automatically included in caching)
const tools = [
  {
    name: "click",
    description: "Click a CSS/XPath selector in the browser",
    input_schema: {
      type: "object",
      properties: { selector: { type: "string" } },
      required: ["selector"]
    }
  },
  {
    name: "type_text",
    description: "Type text into a selector",
    input_schema: {
      type: "object",
      properties: { selector: { type: "string" }, text: { type: "string" } },
      required: ["selector", "text"]
    }
  }
];

// 2) Put your long, stable instructions in `system`
// 3) Mark the END of the static prefix with cache_control
const system = [
  { type: "text", text: "You are Bugster, an E2E testing agent. Use tools only. Be terse." },
  { type: "text", text: "&lt;...lots of stable rules / few-shots / DOM policy...&gt;", cache_control: { type: "ephemeral" } }
];

const res = await client.messages.create({
  model: "claude-3-7-sonnet-20250219",
  max_tokens: 512,
  tools,
  system,
  messages: [
    // dynamic part starts AFTER the breakpoint
    { role: "user", content: "Step 14: open the calendar and pick Aug-13." }
  ]
});

// Inspect caching effectiveness:
console.log(res.cache_creation_input_tokens, res.cache_read_input_tokens);
</code></pre><p>Notes:</p><ul><li><p><strong>Order matters conceptually</strong> (cache builds prefix as tools &#8594; system &#8594; messages). You only need the <strong>breakpoint once</strong> at the end of the static block. </p></li><li><p><strong>Pricing multipliers</strong> (5-min TTL): write <strong>1.25&#215;</strong>, read <strong>0.1&#215;</strong> base input. 1-hour TTL: write <strong>2&#215;</strong>. <a href="https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching">Anthropic</a></p></li></ul><div><hr></div><h2>10-minute rollout checklist</h2><ol><li><p><strong>Identify the static prefix</strong>: tool defs, system prompt, stable memory, canonical examples.</p></li><li><p><strong>Place it first</strong>, then add a single <code>cache_control</code> block <strong>at the end</strong>.</p></li><li><p><strong>Keep dynamic content after</strong> the breakpoint.</p></li><li><p><strong>Measure</strong> <code>cache_creation_input_tokens</code> / <code>cache_read_input_tokens</code> and hit-rate.</p></li><li><p><strong>Tune TTL</strong>: 5-min (default) or 1-hour (beta/GA depending on model).</p></li></ol><h2>Wrap-up</h2><p>This wasn&#8217;t &#8220;optimization theater.&#8221; We simply <strong>stopped paying over and over for the same prefix</strong>. If your agent repeats tool specs and instructions each step, prompt caching is likely the <strong>highest-ROI switch</strong> you can flip today.</p>]]></content:encoded></item><item><title><![CDATA[Build fast. Test in parallel.]]></title><description><![CDATA[Why 2025 testing is receipts, not ceremony &#8212; and how we designed Bugster for that.]]></description><link>https://newsletter.bugster.dev/p/build-fast-test-in-parallel</link><guid isPermaLink="false">https://newsletter.bugster.dev/p/build-fast-test-in-parallel</guid><dc:creator><![CDATA[Bugster]]></dc:creator><pubDate>Tue, 12 Aug 2025 21:31:53 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5fedc775-9787-4189-90dc-0ed8e2021919_1564x784.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3cPX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3cPX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png 424w, https://substackcdn.com/image/fetch/$s_!3cPX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png 848w, https://substackcdn.com/image/fetch/$s_!3cPX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png 1272w, https://substackcdn.com/image/fetch/$s_!3cPX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3cPX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png" width="1456" height="1538" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1538,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:286650,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://newsletter.bugster.dev/i/170821387?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3cPX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png 424w, https://substackcdn.com/image/fetch/$s_!3cPX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png 848w, https://substackcdn.com/image/fetch/$s_!3cPX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png 1272w, https://substackcdn.com/image/fetch/$s_!3cPX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1740377-5649-4a68-a832-b25160a29ec1_2912x3076.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>The pace changed.</strong> AI didn&#8217;t just make us type faster&#8212;it <strong>raised feature capacity</strong>. You can sketch a component, wire a route, and have a fresh branch preview in minutes. What <em>didn&#8217;t</em> grow is the review window. The new failure mode isn&#8217;t &#8220;not enough tests&#8221;; it&#8217;s <strong>not having the right signals at the right time</strong>.</p><p><strong>Our stance:</strong> keep a final safety net <strong>and</strong> run testing <strong>in parallel</strong> while you build. Not &#8220;finish &#8594; throw it over the wall.&#8221; Instead, deliver <strong>small bursts of evidence</strong>&#8212;screens, steps, traces&#8212;<em>during</em> the work so decisions are immediate: push forward or fix now.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.bugster.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><ul><li><p><strong>AI/Copilot-era productivity</strong> means more change volume per day; you need signals that keep pace, not a bigger checklist later.</p></li><li><p><strong>Branch previews</strong> are the new review surface; that&#8217;s where evidence should show up, continuously, while the feature is being shaped.</p></li></ul><div><hr></div><h2>&#8220;Signals in parallel&#8221;: the idea we built around</h2><ul><li><p><strong>While you code:</strong> tiny, trustable checks with receipts.</p></li><li><p><strong>When your branch previews:</strong> automation exercises the <em>real</em> app in a browser and posts a clear result with evidence where you review.</p></li><li><p><strong>Before release:</strong> you still keep the last gate&#8212;only now you arrive with confidence.</p></li></ul><p>We built <strong>Bugster</strong> to live in that middle lane: a pragmatic peer that watches changes, <strong>generates and runs</strong> browser checks, performs a <strong>destructive sweep</strong> on changed pages, and leaves <strong>evidence you can act on</strong>&#8212;without turning testing into its own project.</p><div><hr></div><h2>How Bugster fits your day (minimal ceremony)</h2><h3>1) Generate <strong>once</strong> to seed a baseline</h3><p>The first time you set it up, you create a readable base from your app&#8217;s structure:</p><pre><code>bugster init
bugster generate</code></pre><p>This can produce a long, human-readable base of specs that maps to pages and flows. That&#8217;s intentional: you&#8217;ve turned intent into something executable and explainable.</p><h3>2) From then on, it&#8217;s <strong>automated on each change</strong></h3><p>On every branch update/preview, Bugster will:</p><ul><li><p><strong>Select</strong> what matters based on the diff (don&#8217;t run the world).</p></li><li><p><strong>Update or create</strong> specs as the app evolves (no test graveyard).</p></li><li><p><strong>Run in real browsers</strong>, capture screenshots/video, and attach evidence where you review code.</p></li><li><p>Kick off a <strong>destructive agent</strong> to explore changed pages and surface the weird stuff no recipe would cover.</p></li></ul><p>Think of it like a pragmatic teammate: a mix of steady checks plus exploratory curiosity, always current, never naggy.</p><div><hr></div><h2>Vibe coding deserves <strong>vibe testing</strong>&#8212;with receipts</h2><p>&#8220;Vibe coding&#8221; is real&#8212;AI IDEs, quick scaffolds, instant refactors (see Karpathy&#8217;s take here). The risk is shipping on feelings. Our antidote is vibe testing with <strong>teeth</strong>: intuitive and fast, but grounded in evidence.</p><p><strong>Example A &#8212; Riffing a new UI</strong><br>You add a settings dialog. Instead of &#8220;we&#8217;ll test later,&#8221; you keep short loops:</p><ul><li><p>Save work; Bugster runs the relevant browser checks in the background and drops a clip calling out a missing focus trap.</p></li><li><p>Paste the finding into your assistant (Cursor / Claude Code / Copilot), accept the patch, keep riffing.</p></li><li><p>Momentum stays; accessibility is fixed before anyone reviews.</p></li></ul><p><strong>Example B &#8212; The destructive pass</strong><br>Scripts confirm what you <em>expected</em>. Many bugs hide in what you didn&#8217;t. A <strong>destructive sweep</strong> explores changed pages, tries odd combos, records video of failures, and reports errors/UX issues. It&#8217;s a modern cousin of exploratory/monkey testing&#8212;useful, bounded, repeatable. </p><p><strong>Example C &#8212; Tiny backend tweak &#8594; UI ripple</strong><br>You adjust sorting; Bugster updates a couple of checks and the agent stumbles into a pagination edge. You get steps + screenshot where you already review code and fix while the context is still warm.</p><div><hr></div><h2>Guardrails so this stays helpful (not noisy)</h2><ul><li><p>Prefer <strong>few, high-signal checks</strong> that finish in minutes, with screenshots/trace.</p></li><li><p>Focus on <strong>changed</strong> areas; don&#8217;t spray the whole app every time.</p></li><li><p>Review new/updated specs when they&#8217;re proposed; aim for a living baseline, not an archive.</p></li><li><p>Keep a last gate for releases&#8212;your parallel signals mean fewer surprises. If you enforce blocking checks, do it with receipts (GitHub&#8217;s required checks are described here).</p></li></ul><div><hr></div><h3>Try it in ~5 minutes</h3><p><strong>Option A &#8212; Sign up (fastest)</strong></p><ol><li><p>Open: <a href="https://app.bugster.dev/auth/sign-up">https://app.bugster.dev/auth/sign-up</a></p></li><li><p>Connect your GitHub org and pick the Next.js repo.</p></li><li><p>Confirm preview provider and basic settings.</p></li><li><p>Merge the configuration pull request.<br>From then on, each branch/preview runs real-browser checks, keeps tests fresh as the app evolves, and surfaces evidence where you review code.</p></li></ol><p><strong>Option B &#8212; CLI setup (terminal first)</strong></p><ol><li><p>Install the CLI:</p></li></ol><pre><code>curl -sSL https://github.com/Bugsterapp/bugster-cli/releases/latest/download/install.sh | bash -s -- -y</code></pre><ol start="2"><li><p>Seed a baseline in your project:</p></li></ol><pre><code>bugster init
bugster generate
bugster run</code></pre><ol start="3"><li><p>When you want an extra sweep on changed pages:</p></li></ol><pre><code>bugster destructive</code></pre><ol start="4"><li><p>Integrate with GitHub (so bugster runs on every push and pull request):</p></li></ol><pre><code>bugster install --github</code></pre><div><hr></div><p><strong>Bottom line:</strong> Testing that waits until the end is too late; testing that tries to replace your flow is too heavy. Keep the end gate, <strong>and</strong> run testing <strong>in parallel</strong> while you build. Short cycles, real browsers, updated specs, a destructive sweep when needed. That&#8217;s the vision behind Bugster&#8212;and it&#8217;s how we ship fast without breaking trust.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://newsletter.bugster.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Client, Server, or Edge: How to Render Smartly in Next.js]]></title><description><![CDATA[Choosing between client, server, or edge rendering in Next.js isn't about what's "better", it's about what makes sense for your data, UX, and context.]]></description><link>https://newsletter.bugster.dev/p/client-server-or-edge-how-to-render</link><guid isPermaLink="false">https://newsletter.bugster.dev/p/client-server-or-edge-how-to-render</guid><dc:creator><![CDATA[Bugster]]></dc:creator><pubDate>Tue, 05 Aug 2025 20:18:45 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e283bd9e-a989-4d44-bf79-6ec7dd54ccc9_1624x775.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>1. The Problem: Too Many Rendering Options</h2><p>Modern Next.js App Router (13+) is powerful &#8212; and <em>a bit overwhelming</em>.</p><p>Now we deal with:</p><ul><li><p>Server Components vs <code>use client</code></p></li><li><p>Static vs Dynamic rendering with <code>revalidate</code> and cache options</p></li><li><p>Route Handlers and Edge Runtime</p></li><li><p>Middleware for request interception</p></li><li><p>React Suspense, Streaming, Progressive Enhancement</p></li></ul><p>So&#8230; where the hell should you render what?</p><h2>2. Mental Models for Smarter Rendering</h2><p>&#129517; <strong>Model 1: Data Freshness vs Performance</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nKTC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nKTC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png 424w, https://substackcdn.com/image/fetch/$s_!nKTC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png 848w, https://substackcdn.com/image/fetch/$s_!nKTC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!nKTC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nKTC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png" width="1456" height="597" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:597,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:248259,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://newsletter.bugster.dev/i/170201933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nKTC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png 424w, https://substackcdn.com/image/fetch/$s_!nKTC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png 848w, https://substackcdn.com/image/fetch/$s_!nKTC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!nKTC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0f087de-f22f-4902-af41-192fd19a0898_3124x1280.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#129517; <strong>Model 2: Where Does the Data Live?</strong></p><p>Ask yourself: Where is the data I need coming from?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6ZHE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6ZHE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png 424w, https://substackcdn.com/image/fetch/$s_!6ZHE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png 848w, https://substackcdn.com/image/fetch/$s_!6ZHE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!6ZHE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6ZHE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png" width="1456" height="597" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:597,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:265515,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.bugster.dev/i/170201933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6ZHE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png 424w, https://substackcdn.com/image/fetch/$s_!6ZHE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png 848w, https://substackcdn.com/image/fetch/$s_!6ZHE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!6ZHE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdfc05b25-2ef2-4479-9be9-5639ddc15d01_3123x1280.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>&#129517; <strong>Model 3: Request vs Build Time</strong></p><p><strong>Build Time (Static):</strong></p><ul><li><p>Content doesn't change per user</p></li><li><p>Can be pre-generated</p></li><li><p>Examples: marketing pages, documentation</p></li></ul><p><strong>Request Time (Dynamic):</strong></p><ul><li><p>Needs user context (auth, preferences)</p></li><li><p>Data changes frequently</p></li><li><p>Examples: dashboards, user profiles</p></li></ul><h2>3. Real-World Examples</h2><p>&#9989; <strong>Blog Post Page</strong></p><pre><code>// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
  const posts = await fetch('https://api.example.com/posts').then(res =&gt; res.json())
  return posts.map((post) =&gt; ({ slug: post.slug }))
}

export default async function BlogPost({ params }: { params: { slug: string } }) {
  // This runs at build time for static generation
  const post = await fetch(`https://api.example.com/posts/${params.slug}`, {
    next: { revalidate: false } // Static - never revalidate
  }).then(res =&gt; res.json())
  
  return &lt;article&gt;{post.content}&lt;/article&gt;
}</code></pre><p>&#9889; Instant load, great SEO, minimal JS</p><p>&#9989; <strong>Dashboard After Login</strong></p><pre><code>// app/dashboard/page.tsx
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'

export default async function Dashboard() {
  const session = cookies().get('session')
  
  if (!session) {
    redirect('/login')
  }
  
  // This runs on each request
  const userData = await fetch(`https://api.example.com/user/${session.value}`, {
    next: { revalidate: 0 } // Always fresh
  }).then(res =&gt; res.json())
  
  return &lt;div&gt;Welcome {userData.name}&lt;/div&gt;
}</code></pre><p>&#128100; Personalized and secure</p><p>&#9989; <strong>Search Page with Filters</strong></p><pre><code>// app/search/page.tsx
import { SearchResults } from './SearchResults'

export default async function SearchPage({ searchParams }: { 
  searchParams: { q?: string } 
}) {
  // Server-side initial render
  const initialResults = searchParams.q 
    ? await fetch(`https://api.example.com/search?q=${searchParams.q}`).then(res =&gt; res.json())
    : []
  
  return (
    &lt;div&gt;
      {/* Client component for interactive filtering */}
      &lt;SearchResults initialResults={initialResults} /&gt;
    &lt;/div&gt;
  )
}</code></pre><pre><code>// app/search/SearchResults.tsx
'use client'
import { useSearchParams, useRouter } from 'next/navigation'

export function SearchResults({ initialResults }) {
  const searchParams = useSearchParams()
  const router = useRouter()
  
  // Client-side filtering without full page reload
  const handleFilter = (filter) =&gt; {
    const params = new URLSearchParams(searchParams)
    params.set('filter', filter)
    router.push(`/search?${params.toString()}`)
  }
  
  return (
    &lt;div&gt;
      {/* Interactive filters */}
      &lt;button onClick={() =&gt; handleFilter('recent')}&gt;Recent&lt;/button&gt;
      {/* Results */}
    &lt;/div&gt;
  )
}</code></pre><p>&#9989; No flickers, progressive enhancement</p><p>&#9989; <strong>A/B Testing by Location</strong></p><pre><code>// middleware.ts
import { NextRequest, NextResponse } from 'next/server'

export function middleware(request: NextRequest) {
  const country = request.geo?.country || 'US'
  const variant = country === 'US' ? 'A' : 'B'
  
  const response = NextResponse.next()
  response.cookies.set('ab-variant', variant)
  
  return response
}

export const config = {
  matcher: ['/landing/:path*']
}</code></pre><p>&#9889; Fast routing decisions without hitting your server</p><h2>4. Realistic Benchmarks</h2><p><strong>Important</strong>: These numbers vary greatly based on network, region, and content size.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GPOB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GPOB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png 424w, https://substackcdn.com/image/fetch/$s_!GPOB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png 848w, https://substackcdn.com/image/fetch/$s_!GPOB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!GPOB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GPOB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png" width="1456" height="597" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:597,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:239680,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://newsletter.bugster.dev/i/170201933?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GPOB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png 424w, https://substackcdn.com/image/fetch/$s_!GPOB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png 848w, https://substackcdn.com/image/fetch/$s_!GPOB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!GPOB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd73a907d-177f-47ad-bec6-f0b2b17f0c9b_3123x1280.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2>5. Common Mistakes</h2><ul><li><p>&#10060; <strong>Using </strong><code>use client</code><strong> everywhere</strong></p><ul><li><p>Increases bundle size unnecessarily</p></li><li><p>Loses SEO benefits of Server Components</p></li></ul></li><li><p>&#10060; <strong>Fetching in Client Components what could be Server Components</strong></p><ul><li><p>Adds waterfall requests</p></li><li><p>Shows loading states unnecessarily</p></li></ul></li><li><p>&#10060; <strong>Overcomplicating middleware</strong></p><ul><li><p>Keep it simple: geo, auth, redirects only</p></li><li><p>Heavy logic belongs in Route Handlers</p></li></ul></li><li><p>&#10060; <strong>Not understanding hydration boundaries</strong></p><ul><li><p>Server Components don't hydrate</p></li><li><p>Only Client Components need JavaScript on the client</p></li></ul></li></ul><h2>6. Golden Rules</h2><ol><li><p><strong>Default to Server Components when possible</strong></p></li><li><p><strong>Use static rendering for content that doesn't change per user</strong></p></li><li><p><strong>Middleware is for request interception, not business logic</strong></p></li><li><p><strong>Client Components only when you need interactivity or browser APIs</strong></p></li><li><p><strong>Test on slow networks and devices</strong></p></li><li><p><strong>Measure actual user metrics, not synthetic tests</strong></p></li></ol><div><hr></div><h4><strong>Conclusion</strong></h4><p>Stop overthinking it. Server Components by default, Client Components for interactivity, static when possible. Mix strategies within the same page. Measure real metrics, not synthetic ones.</p><p>The best Next.js apps don't use one rendering strategy &#8212; they use the right one for each piece.</p><p>Build fast, ship smart.</p>]]></content:encoded></item><item><title><![CDATA[What We Learned Launching Bugster: How Testing Agents Actually Behave]]></title><description><![CDATA[After shipping Bugster on Product Hunt, we opened signups and saw over 200 companies and teams jump in within 48 hours to assess if Bugster could solve their testing pains.]]></description><link>https://newsletter.bugster.dev/p/what-we-learned-launching-bugster</link><guid isPermaLink="false">https://newsletter.bugster.dev/p/what-we-learned-launching-bugster</guid><dc:creator><![CDATA[Bugster]]></dc:creator><pubDate>Tue, 29 Jul 2025 19:11:38 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0d976052-6fad-4a4f-bbde-f9f41d647eee_482x397.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>After shipping <a href="https://www.bugster.dev/">Bugster</a> on Product Hunt, we opened signups and saw over 200 companies and teams jump in within 48 hours to assess if Bugster could solve their testing pains. Here&#8217;s what the real-world adoption taught us about agent behavior, prompt design, and what it takes to ship a reliable LLM-driven product for developer teams.</p><h2><strong>Context: What is Bugster?</strong></h2><p>Bugster acts as an end-to-end testing agent. It runs in the browser, navigating your app exactly like a real user would, and checks that your critical user flows work as intended&#8212;no more hand-coding flows, just guide the agent and let it do the rest.</p><div><hr></div><h2><strong>Key Takeaways from Early Usage</strong></h2><ol><li><p><strong>Prompt Engineering is Everything</strong><br>Obvious but underappreciated: &#8220;garbage in, garbage out&#8221; applies to LLM-native tools just as much as classic ML. The depth and clarity of user prompts drive quality. Vague prompts yield vague outputs&#8212;users quickly realize this and dive into our docs for guidance.</p></li><li><p><strong>Agent &#8220;Thoughts&#8221; Build Trust</strong><br>Showing the agent&#8217;s reasoning step-by-step provides more confidence than even watching the agent interact live. Chain-of-thought UI isn&#8217;t just for LLM chat: it&#8217;s vital for any agent that&#8217;s making decisions. (See Perplexity, DeepSeek, ChatGPT.)</p></li><li><p><strong>Online Evaluation &amp; Notifications are Critical</strong><br>You need to know, in real time, if things aren&#8217;t going as expected. Our combo of <a href="https://langfuse.com/">Langfuse</a>+<a href="https://www.deepeval.com/">Deepeval</a> powers notifications and instant feedback on agent behavior.</p></li><li><p><strong>ETA is a Must-Have</strong><br>Agents sometimes take minutes, sometimes hours, to complete tasks. Without an estimated completion time, users get frustrated and drop off. Lesson: always show an ETA for long-running tasks.</p></li></ol><div><hr></div><h2><strong>What&#8217;s Unique to Testing Agents?</strong></h2><ul><li><p><strong>Every App is Different</strong><br>Agent performance varies wildly based on your app. Some teams see immediate wins, others hit edge cases. Predicting fit and surfacing likely agent &#8220;compatibility&#8221; remains an open challenge.</p></li><li><p><strong>Solving the Cold Start Problem</strong><br>Users often don&#8217;t know where to begin. We built onboarding flows that recommend what to test first, using usage data&#8212;critical to help teams see value quickly.</p></li><li><p><strong>Single Goal, Single Outcome</strong><br>The agent should focus on one outcome at a time, not try to solve everything at once.</p></li><li><p><strong>Endless Use Cases, Infinite Tools</strong><br>The range of testing tasks is vast&#8212;we&#8217;re already planning to build 100+ specialized &#8220;tools&#8221; for Bugster&#8217;s agent to execute in the future.</p></li></ul><div><hr></div><p>Building and launching LLM agents in the wild isn&#8217;t just about prompt accuracy or infra. It&#8217;s about guidance, transparency, feedback loops, and narrowing the agent&#8217;s focus. In testing, especially, these elements determine whether a team feels safe letting an agent touch their most valuable workflows.</p>]]></content:encoded></item><item><title><![CDATA[LLM API Call or Agent? How Modern AI Gets (and Loses) Its Autonomy]]></title><description><![CDATA[An Engineer&#8217;s Guide to Choosing the Right Approach for Your LLM]]></description><link>https://newsletter.bugster.dev/p/llm-api-call-or-agent-how-modern</link><guid isPermaLink="false">https://newsletter.bugster.dev/p/llm-api-call-or-agent-how-modern</guid><dc:creator><![CDATA[Bugster]]></dc:creator><pubDate>Tue, 29 Jul 2025 19:00:45 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/65cca84f-a7ff-4fcd-bd88-33f55fc1572a_1552x797.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey engineers and founders, let&#8217;s cut through the AI hype. Large Language Models (LLMs) can indeed do amazing things, from drafting emails to managing complex workflows&#8212;but there's a critical choice you&#8217;ll face when building your product: <strong>should you stick to direct API calls, orchestrate workflows through code, or dive into building autonomous agents?</strong></p><p>This edition breaks down these choices with practical insights so you can confidently pick the right architecture and keep shipping fast.</p><h3>TL;DR</h3><ul><li><p><strong>Direct LLM calls:</strong> Perfect for predictable tasks.</p></li><li><p><strong>Orchestrated workflows:</strong> Great for multi-step processes you control.</p></li><li><p><strong>Autonomous agents:</strong> Ideal for open-ended, dynamic problem-solving.</p></li></ul><p>But watch out&#8212;mixing these without clear boundaries can quickly lead to messy code, inflated costs, and brittle user experiences.</p><h2>1. Mental models: choosing your path</h2><p>Think of <strong>mental models</strong> as architectural blueprints for your brain&#8212;compact, reusable sketches that tame complexity and keep you shipping.</p><p>Whenever the project feels fuzzy, reach for a smaller mental model&#8212;not a heavier framework.</p><p>In the context of LLMs, these models guide you to pick the right layer of autonomy&#8212;direct call, orchestrated workflow, or full agent&#8212;without over&#8209;engineering.</p><p>Here&#8217;s a quick guide to understand the landscape:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v1mj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v1mj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png 424w, https://substackcdn.com/image/fetch/$s_!v1mj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png 848w, https://substackcdn.com/image/fetch/$s_!v1mj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png 1272w, https://substackcdn.com/image/fetch/$s_!v1mj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v1mj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png" width="1456" height="660" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:660,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:259761,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://bugsterdev.substack.com/i/169576819?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!v1mj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png 424w, https://substackcdn.com/image/fetch/$s_!v1mj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png 848w, https://substackcdn.com/image/fetch/$s_!v1mj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png 1272w, https://substackcdn.com/image/fetch/$s_!v1mj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06da310f-8986-41f4-99b7-f9be5de33c33_2996x1358.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>2.  Understand the evolution: Single Calls &#8594; Code-Driven Workflows &#8594; Autonomous Agents</h2><p>Every engineering team climbs the same autonomy ladder:</p><ol><li><p><strong>One&#8209;shot LLM calls</strong> &#8211; a single prompt in, single answer out. Great for fast wins like summarization or sentiment tags.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3pmW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3pmW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png 424w, https://substackcdn.com/image/fetch/$s_!3pmW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png 848w, https://substackcdn.com/image/fetch/$s_!3pmW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png 1272w, https://substackcdn.com/image/fetch/$s_!3pmW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3pmW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png" width="384" height="193.84615384615384" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:735,&quot;width&quot;:1456,&quot;resizeWidth&quot;:384,&quot;bytes&quot;:50390,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://bugsterdev.substack.com/i/169576819?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3pmW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png 424w, https://substackcdn.com/image/fetch/$s_!3pmW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png 848w, https://substackcdn.com/image/fetch/$s_!3pmW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png 1272w, https://substackcdn.com/image/fetch/$s_!3pmW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09dbecb0-030c-4ccd-9302-cf0cbafee380_1632x824.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div></li><li><p><strong>Code&#8209;orchestrated workflows</strong> &#8211; you chain several calls together with plain code. Each step tackles a bite&#8209;sized, deterministic task; your glue code owns the flow.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kEws!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kEws!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png 424w, https://substackcdn.com/image/fetch/$s_!kEws!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png 848w, https://substackcdn.com/image/fetch/$s_!kEws!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png 1272w, https://substackcdn.com/image/fetch/$s_!kEws!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kEws!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png" width="486" height="209.62087912087912" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:628,&quot;width&quot;:1456,&quot;resizeWidth&quot;:486,&quot;bytes&quot;:120127,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://bugsterdev.substack.com/i/169576819?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kEws!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png 424w, https://substackcdn.com/image/fetch/$s_!kEws!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png 848w, https://substackcdn.com/image/fetch/$s_!kEws!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png 1272w, https://substackcdn.com/image/fetch/$s_!kEws!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d04d6c2-893d-46fc-b248-13e9a955b382_2658x1146.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div></li><li><p><strong>Autonomous agents</strong> &#8211; when the happy path splinters into too many branches, you hand the steering wheel to the model. It plans, chooses tools, and loops until done.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!I6i8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!I6i8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png 424w, https://substackcdn.com/image/fetch/$s_!I6i8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png 848w, https://substackcdn.com/image/fetch/$s_!I6i8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png 1272w, https://substackcdn.com/image/fetch/$s_!I6i8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!I6i8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png" width="470" height="280.8379120879121" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:870,&quot;width&quot;:1456,&quot;resizeWidth&quot;:470,&quot;bytes&quot;:75732,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://bugsterdev.substack.com/i/169576819?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!I6i8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png 424w, https://substackcdn.com/image/fetch/$s_!I6i8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png 848w, https://substackcdn.com/image/fetch/$s_!I6i8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png 1272w, https://substackcdn.com/image/fetch/$s_!I6i8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88f058e-e6ad-4b71-a515-8e1bb598fc58_1650x986.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li></ol><p>Think of it like transport:</p><ul><li><p><strong>Kick&#8209;scooter (one&#8209;shot):</strong> dead simple, zero maintenance.</p></li><li><p><strong>Manual car (workflow):</strong> more parts, but <em>you</em> still drive.</p></li><li><p><strong>Self&#8209;driving car (agent):</strong> magical when it works, expensive when it doesn&#8217;t.</p></li></ul><p>Choose the scooter when traffic is light, the car for regular commutes, and the self&#8209;driving option only when the journey is too complex to steer manually.</p><p><a href="https://www.youtube.com/watch?v=D7_ipDqhtwk&amp;t">Barry Zhang from Anthropic</a> captures this evolution concisely:</p><ul><li><p>Single LLM calls for quick, deterministic tasks.</p></li><li><p>Code-driven workflows for predictable complexity.</p></li><li><p>Autonomous agents when flexibility and dynamic decision-making are critical.</p></li></ul><div><hr></div><h2>3. So, when does direct calls win</h2><ul><li><p><strong>One&#8209;and&#8209;done language jobs:</strong> <em>"Summarize this doc," "translate to Spanish," "tag the sentiment."</em> One prompt in, answer out, ship it.</p></li><li><p><strong>Straight&#8209;through data plumbing:</strong> You already know the SQL or API shape&#8212;let the model populate parameters, nothing more.</p></li><li><p><strong>Hard latency ceilings:</strong> Sub&#8209;second chat replies, metered mobile apps, edge devices&#8212;no time for multi&#8209;turn deliberation.</p></li><li><p><strong>Audit&#8209;friendly outputs:</strong> Legal templates, medical disclaimers, or anything compliance must rubber&#8209;stamp. Fewer moving parts = fewer surprises.</p><p></p></li></ul><div><hr></div><h2>4. When to let the Agent off the leash</h2><ul><li><p><strong>Messy, branching quests:</strong> You don&#8217;t know the full roadmap upfront&#8212;think <em>&#8220;Plan a month&#8209;long Europe trip under $3k, factoring rail passes and food allergies.&#8221;</em></p></li><li><p><strong>Live tool roulette:</strong> The job could hit ten different APIs, pick databases on the fly, and recover gracefully when half of them time out.</p></li><li><p><strong>Self&#8209;correct &amp; iterate:</strong> Tasks where the model must read, evaluate, retry, and patch its own output&#8212;data cleanup, codebase migrations, literature reviews.</p></li><li><p><strong>Always&#8209;on guardians:</strong> Continuous monitoring, alert triage, or scheduled optimizations where memory and autonomy compound over time.</p></li></ul><blockquote><p>&#127899;&#65039; <strong>Rule of thumb:</strong> If a human PM would need a whiteboard and sticky notes to map the path, an autonomous agent is probably the right sidekick.</p></blockquote><div><hr></div><h2>5. Anti-patterns to avoid</h2><p>Before you reach for the shiny new framework, memorize this wall of shame. These patterns look tempting in the sprint rush, but every one of them shows up later as flaky tests, surprise bills, or &#128293;&#128658; 2&#8239;a.m. PagerDuty pings.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uHMd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uHMd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png 424w, https://substackcdn.com/image/fetch/$s_!uHMd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png 848w, https://substackcdn.com/image/fetch/$s_!uHMd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png 1272w, https://substackcdn.com/image/fetch/$s_!uHMd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uHMd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png" width="1456" height="845" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:845,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:203509,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://bugsterdev.substack.com/i/169576819?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uHMd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png 424w, https://substackcdn.com/image/fetch/$s_!uHMd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png 848w, https://substackcdn.com/image/fetch/$s_!uHMd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png 1272w, https://substackcdn.com/image/fetch/$s_!uHMd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e9830d-9008-4822-879a-111d36a4ff08_1996x1158.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>6. Your LLM design checklist</h2><p>Use this pre&#8209;flight list before every deploy. Skip a box at your own peril.</p><ul><li><p><strong>Define the job in a sentence:</strong> If you can&#8217;t TL;DR the task, you&#8217;re not ready to prompt.</p></li><li><p><strong>Choose the lightest model/tool that works:</strong> Smaller &#8800; worse. Try the budget option first.</p></li><li><p><strong>Map external actions:</strong> &#8804;&#8239;3 well&#8209;known APIs &#8594; direct call. &gt;&#8239;3 or dynamic tool choice &#8594; consider an agent.</p></li><li><p><strong>Set hard limits:</strong> Max tokens, turns, tool invocations, wall time. Automation without guardrails is just auto&#8209;chaos.</p></li><li><p><strong>Make thinking visible:</strong> Log raw prompts, intermediate scratchpads, and final outputs for post&#8209;mortems.</p></li><li><p><strong>Iterate outside&#8209;in:</strong> Start with a working stub, then add autonomy only when the deterministic path buckles.</p></li><li><p><strong>Design for observability:</strong> Dashboards, traces, and real&#8209;time alerts&#8212;so issues surface before users tweet them.</p></li></ul><p>Print it, stick it next to your monitor, and run it like a pre&#8209;flight checklist every time you touch production.</p><p>Don&#8217;t let hype choose for you. Test often, iterate carefully, and maintain clarity in your system&#8217;s logic. Your future self&#8212;and your budget&#8212;will thank you.</p><p>Happy building! &#128640;</p><p></p>]]></content:encoded></item></channel></rss>