<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nilesh Kasar</title>
    <description>The latest articles on DEV Community by Nilesh Kasar (@nilesh_kasar_2b00e7247dd5).</description>
    <link>https://dev.to/nilesh_kasar_2b00e7247dd5</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3883085%2F03a3959d-c7ac-42bf-b717-ed9cb5b290ca.png</url>
      <title>DEV Community: Nilesh Kasar</title>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nilesh_kasar_2b00e7247dd5"/>
    <language>en</language>
    <item>
      <title>Claude Skills vs Custom MCP Servers: Which to Build in 2026</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Tue, 12 May 2026 18:04:03 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/claude-skills-vs-custom-mcp-servers-which-to-build-in-2026-1jng</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/claude-skills-vs-custom-mcp-servers-which-to-build-in-2026-1jng</guid>
      <description>&lt;p&gt;When Anthropic shipped Claude Skills at the October 2025 dev summit and then expanded the marketplace in February 2026, the question my team got asked weekly stopped being "should we use Claude" and started being "should we build a Skill or run our own MCP server?" Six months and seventeen production deployments later, I have a clear answer for most cases — and a list of edge cases where the answer is the opposite of obvious.&lt;/p&gt;

&lt;p&gt;This is the decision framework I use, with concrete examples of when each approach is right.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Things Being Compared
&lt;/h2&gt;

&lt;p&gt;Claude Skills are packaged, sandboxed capability bundles that Anthropic distributes through their official marketplace and that any Claude deployment can install. They run on Anthropic's infrastructure, can call out to your APIs, and are installable in one click. Anthropic vets the marketplace.&lt;/p&gt;

&lt;p&gt;MCP (Model Context Protocol) servers are self-hosted services you run that expose tools and resources to any compatible model client over a standardized protocol. You build them, you operate them, you pay for them. They work with Claude, Cursor, Windsurf, Zed, Claude Code, and increasingly other model surfaces.&lt;/p&gt;

&lt;p&gt;Both let an LLM use external capabilities. The differences are about ownership, distribution, and the boundary conditions. The right way to think about it: Skills are a product surface; MCP servers are infrastructure. Confusing the two leads to the most common mis-step I see — teams build a Skill expecting it to behave like infrastructure (mutable, low-latency, internally observable) and end up frustrated.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Skills Win
&lt;/h2&gt;

&lt;p&gt;Use Claude Skills when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Distribution to many users is the goal.&lt;/strong&gt; If you want every Claude Pro user to discover and install your capability, the marketplace is uniquely effective. There's no equivalent reach mechanism for MCP servers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The capability is well-bounded.&lt;/strong&gt; A single domain, a small number of tools, a clear input-output contract. Examples: a Notion search Skill, a Calendly booking Skill, a Stripe customer-lookup Skill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You don't need to control the runtime.&lt;/strong&gt; Anthropic decides scaling, observability, region routing. For most tools, this is a relief, not a constraint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The data flow is API-bounded.&lt;/strong&gt; Your Skill calls your API. Your API stays inside your perimeter. Anthropic's sandbox is the proxy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Notion Skill is the canonical example. It installs in seconds. It works for every Claude user. Notion didn't build sixteen redundant integration surfaces. The same logic applies to Calendly, Linear, Stripe, GitHub — every horizontal SaaS with a Claude integration has either shipped a Skill or is about to.&lt;/p&gt;

&lt;h2&gt;
  
  
  When MCP Servers Win
&lt;/h2&gt;

&lt;p&gt;Use MCP servers when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The capability is internal-only.&lt;/strong&gt; You're building tools for your own engineers, not for the public marketplace. There's no upside to wrapping it as a Skill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The runtime needs to be in your VPC.&lt;/strong&gt; Healthcare, finance, defense. The model can still be Anthropic's, but the tools execute behind your firewall on your hardware, with your logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The protocol matters beyond Claude.&lt;/strong&gt; If you want the same toolset to work in Cursor or Zed, you need MCP. Skills are Claude-only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need fine-grained observability.&lt;/strong&gt; Skills give you basic execution logs through Anthropic's dashboard. MCP servers give you everything because you run them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The tool is high-cardinality.&lt;/strong&gt; A code-search MCP server that exposes one tool per repo, dynamically, isn't a Skill shape. Skills assume a fixed tool surface.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We built an internal Postgres-ops MCP server at one client that exposes &lt;code&gt;describe-table&lt;/code&gt;, &lt;code&gt;explain-query&lt;/code&gt;, &lt;code&gt;top-slow-queries&lt;/code&gt; against their production database. There's no universe in which that's a marketplace Skill. The data is sensitive, the tools are evolving weekly, and the surface is bespoke to their schema. It's the same kind of internal-tooling pattern described in &lt;a href="https://dev.to/blog/autonomous-agents-software-engineering"&gt;autonomous AI agents in software engineering&lt;/a&gt; — and MCP is the right primitive for letting an agent run against your specific stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Concrete Decision Matrix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Factor&lt;/th&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;MCP Server&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Public distribution&lt;/td&gt;
&lt;td&gt;Strong fit&lt;/td&gt;
&lt;td&gt;Weak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internal-only tooling&lt;/td&gt;
&lt;td&gt;Weak fit&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-client (Claude + Cursor + Zed)&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data must stay in VPC&lt;/td&gt;
&lt;td&gt;Hard to do&lt;/td&gt;
&lt;td&gt;Native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stable tool surface&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;Either works&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Highly dynamic tools&lt;/td&gt;
&lt;td&gt;Weak&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operating burden&lt;/td&gt;
&lt;td&gt;Anthropic's problem&lt;/td&gt;
&lt;td&gt;Your problem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to first deployment&lt;/td&gt;
&lt;td&gt;Hours&lt;/td&gt;
&lt;td&gt;Days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth/identity passthrough&lt;/td&gt;
&lt;td&gt;Limited models&lt;/td&gt;
&lt;td&gt;Whatever you build&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compliance audit trail&lt;/td&gt;
&lt;td&gt;Anthropic's audit&lt;/td&gt;
&lt;td&gt;Your audit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Versioning&lt;/td&gt;
&lt;td&gt;Marketplace gates&lt;/td&gt;
&lt;td&gt;You control&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Hybrid Pattern Most People Miss
&lt;/h2&gt;

&lt;p&gt;The most interesting deployments combine both. A team ships a public Skill that wraps a thin authentication layer, and the heavy logic lives in their MCP server that the Skill calls into. You get marketplace distribution and runtime control. The Skill is a discoverable entry point; the MCP server is the engine.&lt;/p&gt;

&lt;p&gt;Linear B did this with their incident-management integration: a Skill called &lt;code&gt;linear-incident-lookup&lt;/code&gt; that handles auth and surface, backed by an MCP server inside their infrastructure that handles the actual analysis. Best of both worlds, at the cost of building two things.&lt;/p&gt;

&lt;p&gt;We've also seen the inverse hybrid: an MCP server that fronts a Skill. The MCP server runs inside the customer's network, handling auth and access control, and proxies tool calls to a publicly-distributed Skill that does the heavy lifting on Anthropic's infrastructure. This is rarer but useful for enterprises that want centralized control over which Skills are available to their employees.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Auth Story Is Different in Each
&lt;/h2&gt;

&lt;p&gt;For Skills, auth happens at install time. The user OAuth flows through Anthropic to your service. From then on, the Skill calls your API with the stored token. Token refresh is on you.&lt;/p&gt;

&lt;p&gt;For MCP servers, you decide the auth model. Many production MCP servers in 2026 use OAuth 2.1 with the device flow, since the model client doesn't have a browser. Some run with pre-provisioned service accounts. The MCP spec doesn't dictate this; it's a property of your server.&lt;/p&gt;

&lt;p&gt;The right pattern for sensitive internal tools: bind the MCP server to the user's identity at session start (Auth.js OIDC, Okta, whatever you use), pass that identity into every tool call, and have the tool enforce least-privilege. Don't let the model bypass your access control. We've seen at least three internal MCP servers ship with implicit "the model can do anything the service account can do" auth — every one of them later had to be rewritten when security found it.&lt;/p&gt;

&lt;p&gt;A practical pattern that works: every MCP tool call takes a &lt;code&gt;user_context&lt;/code&gt; parameter that the server validates against the session token. If the model tries to call with a different user_context than what's in the session, refuse. This prevents the kind of injection attacks where the model is talked into impersonating a different user mid-conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Comparison
&lt;/h2&gt;

&lt;p&gt;This is where MCP servers can look surprising:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skills&lt;/strong&gt;: included in Claude pricing. The user pays Claude. Anthropic absorbs the infrastructure. You pay for the API calls that your Skill makes to your backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP servers&lt;/strong&gt;: you pay everything. Hosting, scaling, observability, the lot. For a small internal MCP server that handles 1,000 calls a day, you're looking at $40-80/month all-in. For a public-facing MCP server with millions of calls, you're looking at six figures a year.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your Skill is doing real work — generating images, running RAG, hitting expensive APIs — the cost shows up on your side as API charges, not on Anthropic's side. The "free hosting" benefit of Skills is real but smaller than it sounds. The economic effect of choosing Skills is mostly that Anthropic eats the &lt;em&gt;integration&lt;/em&gt; infrastructure (auth, retry logic, sandbox, distribution) but you still eat the &lt;em&gt;work&lt;/em&gt; infrastructure (your APIs, your databases, your compute for whatever the tool actually does).&lt;/p&gt;

&lt;h2&gt;
  
  
  Latency Differences
&lt;/h2&gt;

&lt;p&gt;In our testing, the latency overhead is roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Skill execution overhead: 80-150ms typical, including auth, network, and Anthropic's invocation logic.&lt;/li&gt;
&lt;li&gt;MCP server overhead: 20-60ms typical, since the network hop is just to your server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you host your MCP server in the same region as the Claude API gateway (us-east-1 today), latency is barely measurable. If your users care about sub-second response times for complex tool chains, MCP servers win by 100-200ms compounded across several calls.&lt;/p&gt;

&lt;p&gt;The compounding matters more than the single-call difference. A six-tool-call agent loop loses 600-900ms on Skills versus a co-located MCP server. For an interactive product where the user is watching the loading spinner, that's the difference between feeling fast and feeling slow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Migration Path
&lt;/h2&gt;

&lt;p&gt;The pattern I've seen work: start with an MCP server. Iterate fast, no marketplace review. Once the tool surface stabilizes and you have a distribution argument, wrap a thin Skill around the MCP server. The Skill becomes your marketplace presence. The MCP server stays your runtime.&lt;/p&gt;

&lt;p&gt;The opposite migration (Skill first, MCP later) is harder. Once a Skill is in the marketplace and users have installed it, changing the tool surface is a versioning exercise. Anthropic's marketplace handles deprecation gracefully — old versions stay installable while new versions roll out — but you still own the support burden of multiple versions running in production simultaneously.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Build Today
&lt;/h2&gt;

&lt;p&gt;If you're starting today with no constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public-facing capability, single SaaS tied to Claude users.&lt;/strong&gt; Build a Skill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internal devtool for your engineers, sensitive data.&lt;/strong&gt; Build an MCP server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capability you'll want in Cursor and Claude Code too.&lt;/strong&gt; Build an MCP server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want to learn the ecosystem.&lt;/strong&gt; Build an MCP server first; Skills second.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For developer tools especially, MCP has become the default in 2026. The same agent productivity gains documented in &lt;a href="https://dev.to/blog/rust-javascript-tooling-takeover-2026"&gt;the Rust takeover of JavaScript tooling&lt;/a&gt; — fast iteration loops, low-latency dev experience — depend on tooling that runs locally or in your VPC, not in a third-party sandbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Few Underrated MCP Features
&lt;/h2&gt;

&lt;p&gt;Three things about MCP that don't get enough attention:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Resources, not just tools.&lt;/strong&gt; MCP servers can expose &lt;em&gt;resources&lt;/em&gt; (read-only data sources the model can reference) in addition to &lt;em&gt;tools&lt;/em&gt; (actions the model can take). This is a cleaner mental model than wrapping every read as a "read tool" — and it lets the client cache resource contents intelligently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streaming responses.&lt;/strong&gt; MCP supports streaming tool outputs back to the model. For a long-running operation (a big database query, a slow API call) the model can receive partial results and start reasoning before the operation completes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompts as a first-class concept.&lt;/strong&gt; MCP servers can ship prompts that the model can invoke as templates. This is underused. A well-designed MCP server can ship the "right way" to use its tools as a prompt — making the integration substantially less error-prone than a tools-only API.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Operating an MCP Server in Production: A Short Checklist
&lt;/h2&gt;

&lt;p&gt;Once you decide to ship an MCP server, the operational discipline matters more than the protocol itself. The checklist we use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Health endpoint.&lt;/strong&gt; A simple &lt;code&gt;/health&lt;/code&gt; that returns 200 if the server can reach its dependencies. Run it from your existing uptime monitor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request logging with model identifiers.&lt;/strong&gt; Log every tool call with the model name and request ID so you can correlate MCP traffic against your Claude API logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting per user.&lt;/strong&gt; A misbehaving agent in a long-running loop can hammer your MCP server. Per-user rate limits protect your downstream services. We use Redis-backed token buckets at 10 calls/second per user as a default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graceful degradation.&lt;/strong&gt; If your MCP server depends on a flaky third-party API, return a structured error to the model so it can reason about the failure rather than throwing an opaque 500. The model can often work around a known failure if it knows about it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema versioning.&lt;/strong&gt; Pin your MCP server to a specific protocol version and bump it deliberately. Clients update; servers should not break clients silently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost attribution.&lt;/strong&gt; If your MCP server makes paid API calls (search APIs, scraping services, paid data), tag every outbound call with the user ID so you can attribute cost. We've seen one $14K surprise bill from an MCP server that didn't have this in place.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where Both Ecosystems Are Heading
&lt;/h2&gt;

&lt;p&gt;A few trends worth tracking through the rest of 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Marketplace consolidation.&lt;/strong&gt; The Skills marketplace has roughly tripled in size since February 2026, and a long tail of low-quality Skills has emerged. Anthropic is signaling tighter review and a featured-Skills program. Expect quality differentiation to become a real factor for marketplace discovery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP standardization across vendors.&lt;/strong&gt; OpenAI, Google, and Mistral have all hinted at MCP support, though only Mistral has actually shipped a public client implementation as of May 2026. If the protocol becomes truly cross-vendor, MCP server investment looks even better in hindsight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sandbox-first MCP runtimes.&lt;/strong&gt; A few startups (most notably E2B and Modal) are shipping managed runtimes for MCP servers that try to give you Skills-like operational simplicity with MCP-like control. Worth evaluating if you don't want to run the infrastructure yourself but also don't want to be Claude-locked.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Skills and MCP servers solve overlapping but distinct problems. The marketing makes them sound interchangeable. They're not. Skills are about distribution and managed runtime. MCP servers are about ownership, control, and cross-client portability. For most internal-facing tools, MCP wins. For most public-facing capabilities you want every Claude user to find, Skills win. Pick wrong and you'll either be locked into a marketplace you've outgrown or maintaining infrastructure for a tool that should have been one-click installable. The technical decision flows directly from the distribution question — answer that one first, and the rest follows. The teams I see succeeding with both are the ones who treat them as complementary, not competing — Skills for reach, MCP for control, and a clear architectural seam between the two.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/claude-skills-vs-custom-mcp-servers-2026" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudeskills</category>
      <category>mcp</category>
      <category>anthropic</category>
      <category>aiengineering</category>
    </item>
    <item>
      <title>Next.js 16 Cache Components: A Real Migration From a 4.2M-MAU Site</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Tue, 12 May 2026 18:03:56 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/nextjs-16-cache-components-a-real-migration-from-a-42m-mau-site-49d8</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/nextjs-16-cache-components-a-real-migration-from-a-42m-mau-site-49d8</guid>
      <description>&lt;p&gt;Vercel pushed Next.js 16 to stable on March 18, 2026 with a feature that quietly upends how everyone has been writing App Router code for the past three years: cache components. We migrated a 4.2-million-monthly-active-user marketing site over six weeks. Here's what actually happened, including the three production incidents we caused and what the migration is worth.&lt;/p&gt;

&lt;p&gt;I led the migration as the senior engineer on a four-person platform team. We chose to document it in public because we couldn't find a single honest write-up of a real cache-components migration at the time — Vercel's own examples were too clean, and Twitter threads were too triumphal. What follows is the full log, with the dashboards, the cost lines, and the screenshots-in-prose. If you're considering this migration, this is the article I wish I'd had three months ago.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Cache Components Are, and Why They Replaced &lt;code&gt;fetch&lt;/code&gt;-Based Caching
&lt;/h2&gt;

&lt;p&gt;If you wrote App Router code between Next.js 13 and 15, your mental model was: every &lt;code&gt;fetch&lt;/code&gt; was cached by default, and you opted out with &lt;code&gt;{ cache: 'no-store' }&lt;/code&gt; or &lt;code&gt;revalidate: 0&lt;/code&gt;. That was elegant when the only data source was an HTTP API. It fell apart the moment people started using Prisma, Drizzle, raw SQL clients, or third-party SDKs that didn't go through fetch.&lt;/p&gt;

&lt;p&gt;Cache components flip the model. You explicitly mark a component (or a function) as cacheable with the new &lt;code&gt;"use cache"&lt;/code&gt; directive. Everything else is dynamic by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PopularArticles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;articles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PUBLISHED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;views&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;take&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArticleList&lt;/span&gt; &lt;span class="na"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;articles&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That component will be cached at the component boundary, independent of how its data is fetched. Prisma calls, raw SQL, the AWS SDK — they all just work. This is the change that makes the App Router actually viable for data-heavy apps that don't fit the "everything is a fetch" mold. It also resolves the longstanding inconsistency where adding &lt;code&gt;cookies()&lt;/code&gt; to a deep child would silently switch a static page to dynamic — a footgun that ate more developer-weeks at our shop than I'd like to admit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Starting Point
&lt;/h2&gt;

&lt;p&gt;Before the migration we ran Next.js 15.3 on Vercel, with about 340 routes, a mix of static and ISR. The site is a publication: long-form articles, author pages, topic hubs, a paid newsletter checkout. Average TTFB 240ms p50, 680ms p95. Build time 12 minutes. Vercel bill: $4,800/month, dominated by edge function invocations from the ISR revalidations.&lt;/p&gt;

&lt;p&gt;Our pain points coming in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ISR revalidation thrash. We had 60+ tag-based revalidations daily, and tag misses caused stampeding herd issues on popular articles.&lt;/li&gt;
&lt;li&gt;Inconsistent dynamic-vs-static behavior. Adding a single &lt;code&gt;cookies()&lt;/code&gt; call somewhere deep in the tree silently turned a static page dynamic.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;fetch&lt;/code&gt; cache wasn't reachable from Prisma queries, so we had a homegrown LRU around our DB layer that was buggy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A lot of this echoed what we saw teams struggle with in &lt;a href="https://dev.to/blog/nextjs-vs-react-verdict"&gt;the verdict on Next.js vs React for enterprise&lt;/a&gt; — the framework had outgrown its caching model, and the workarounds were starting to outweigh the benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Migration in Six Phases
&lt;/h2&gt;

&lt;p&gt;We did this incrementally over six weeks. Here's the sequence that worked:&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Enable the flag, fix the breakage (Week 1)
&lt;/h3&gt;

&lt;p&gt;Cache components is opt-in via &lt;code&gt;experimental.cacheComponents = true&lt;/code&gt; in &lt;code&gt;next.config.ts&lt;/code&gt;. Flipping it surfaces every route that was implicitly relying on the old fetch-cache behavior. We had 84 build-time errors and 31 runtime warnings. Most were cosmetic — pages that were "static" only because nothing in them touched a request-scoped API.&lt;/p&gt;

&lt;p&gt;The single most useful debugging tool in this phase was the new &lt;code&gt;--experimental-cache-debug&lt;/code&gt; build flag, which annotates the build output with a per-component breakdown of "dynamic," "cached," or "static." We piped the output into a CSV and sorted by render cost. Two unexpected items showed up at the top: a layout footer that was hitting our analytics service on every render, and a header that read &lt;code&gt;headers()&lt;/code&gt; inside a deeply-nested component. Both were trivially fixable once visible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: Identify caching candidates (Week 1-2)
&lt;/h3&gt;

&lt;p&gt;We graphed every server component by how often its data changed. Three buckets:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bucket&lt;/th&gt;
&lt;th&gt;Components&lt;/th&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Almost-static (changes once a day)&lt;/td&gt;
&lt;td&gt;Author bios, category pages, navigation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;"use cache"&lt;/code&gt; with long &lt;code&gt;cacheLife&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hot data (changes every few minutes)&lt;/td&gt;
&lt;td&gt;Trending sidebar, popular articles&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;"use cache"&lt;/code&gt; with short &lt;code&gt;cacheLife&lt;/code&gt; + tag-based revalidation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-request (always dynamic)&lt;/td&gt;
&lt;td&gt;User session, paywall state, comments&lt;/td&gt;
&lt;td&gt;Leave untouched; explicit &lt;code&gt;unstable_noStore()&lt;/code&gt; for safety&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To do this systematically we exported a Prisma audit log: for every model, the rate of writes per day, the read patterns, the typical query shape. Anything below 1 write/day got long &lt;code&gt;cacheLife&lt;/code&gt;. Anything above 100 writes/day either got fine-grained tag invalidation or was left dynamic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: Apply &lt;code&gt;"use cache"&lt;/code&gt; to the obvious wins (Week 2-3)
&lt;/h3&gt;

&lt;p&gt;We started with author pages — 11,400 of them, regenerating constantly under the old model. Adding &lt;code&gt;"use cache"&lt;/code&gt; at the top of the page component, plus &lt;code&gt;cacheTag&lt;/code&gt; and &lt;code&gt;cacheLife&lt;/code&gt; calls, dropped build time from 12 minutes to 4 minutes. Author-page TTFB went from 290ms to 38ms p50.&lt;/p&gt;

&lt;p&gt;We also moved our footer (which loaded site-wide stats like total article count and total comment count) into its own cached component with a 5-minute lifetime. That single change cut homepage TTFB by another 50ms because the footer was rendering on every request under the old model regardless of how cached the rest of the page was.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 4: Tag invalidation strategy (Week 3-4)
&lt;/h3&gt;

&lt;p&gt;This is where we caused our first incident.&lt;/p&gt;

&lt;p&gt;We had a content team workflow that published 40+ articles a day. Each publish triggered &lt;code&gt;revalidateTag('articles')&lt;/code&gt;. Under cache components, a tag invalidation cascades through every component that declared that tag. Our nav component, our footer, our sidebar — all tagged &lt;code&gt;articles&lt;/code&gt; because they showed counts. A single publish nuked 80% of the cache.&lt;/p&gt;

&lt;p&gt;Fix: tag with intent, not entity. We split into &lt;code&gt;articles:latest&lt;/code&gt;, &lt;code&gt;articles:counts&lt;/code&gt;, &lt;code&gt;articles:by-author:{authorId}&lt;/code&gt;, &lt;code&gt;articles:by-topic:{topicSlug}&lt;/code&gt;. Granular invalidation. Cache hit rate recovered to 97%. The lesson generalizes: never tag a component with a noun unless the noun is itself a noun-phrase indicating &lt;em&gt;which&lt;/em&gt; change in the entity matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 5: Per-user-but-cacheable patterns (Week 4-5)
&lt;/h3&gt;

&lt;p&gt;The tricky case: components that depend on the user but not on the &lt;em&gt;specific&lt;/em&gt; user. Example: "Recommended for you" can be cached at the segment level (logged-in vs logged-out, free vs paid). Cache components let you do this with &lt;code&gt;cacheKey&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cacheKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Recommendations&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;segment&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getRecsForSegment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RecsList&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;recs&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We collapsed our recommendation tiers from 4.2M unique user caches to 11 segment caches. Edge function invocations dropped 96%. That alone saved $2,200/month.&lt;/p&gt;

&lt;p&gt;A subtler case: per-region content (different stories for European vs North American users). We added a third cacheKey dimension for region, taking us from 11 to 33 segment caches. Still trivially small compared to the per-user explosion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 6: Production rollout and the incidents (Week 5-6)
&lt;/h3&gt;

&lt;p&gt;We caused three incidents during cutover. Documenting them so you don't repeat them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incident 1 — Stale paywall state.&lt;/strong&gt; A reader who upgraded to paid saw the paywall for 8 minutes after upgrading. We had cached the &lt;code&gt;&amp;lt;PaywallGate/&amp;gt;&lt;/code&gt; component without realizing it inherited the parent route's cache directive. Fix: explicit &lt;code&gt;"use cache: false"&lt;/code&gt; on the gate. Time to detect: 3 minutes after the first complaint in support. Time to mitigate: 18 minutes (revert the offending PR).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incident 2 — Cache poisoning via cookies.&lt;/strong&gt; A misconfigured A/B test wrote a cohort cookie that we accidentally included in the cache key. One cohort variant got served to everyone for ~40 minutes. Fix: never read cookies inside a &lt;code&gt;"use cache"&lt;/code&gt; boundary; pass cohort as a prop from a dynamic parent. We added a lint rule afterward that fails the build if &lt;code&gt;cookies()&lt;/code&gt; is called inside a file with &lt;code&gt;"use cache"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incident 3 — Build-time database overload.&lt;/strong&gt; Static generation tried to pre-render 11,400 author pages in parallel during deploy. Neon's connection pool melted at 2 AM. Fix: &lt;code&gt;experimental.staticGenerationMaxConcurrency: 8&lt;/code&gt; in the config. We learned this the way you do — by getting paged.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers After Migration
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before (Next 15.3)&lt;/th&gt;
&lt;th&gt;After (Next 16.0)&lt;/th&gt;
&lt;th&gt;Delta&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TTFB p50&lt;/td&gt;
&lt;td&gt;240ms&lt;/td&gt;
&lt;td&gt;71ms&lt;/td&gt;
&lt;td&gt;-70%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TTFB p95&lt;/td&gt;
&lt;td&gt;680ms&lt;/td&gt;
&lt;td&gt;198ms&lt;/td&gt;
&lt;td&gt;-71%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LCP p75 (mobile)&lt;/td&gt;
&lt;td&gt;2.1s&lt;/td&gt;
&lt;td&gt;1.2s&lt;/td&gt;
&lt;td&gt;-43%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build time&lt;/td&gt;
&lt;td&gt;12m 14s&lt;/td&gt;
&lt;td&gt;4m 38s&lt;/td&gt;
&lt;td&gt;-62%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vercel edge invocations / day&lt;/td&gt;
&lt;td&gt;18.4M&lt;/td&gt;
&lt;td&gt;1.9M&lt;/td&gt;
&lt;td&gt;-90%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vercel monthly bill&lt;/td&gt;
&lt;td&gt;$4,800&lt;/td&gt;
&lt;td&gt;$1,720&lt;/td&gt;
&lt;td&gt;-64%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The bill cut was the biggest surprise. We expected speed gains. We didn't expect to save $36K/year. Core Web Vitals also moved into "Good" thresholds on all three metrics for the first time in the site's history, and search-console impressions started ticking up about three weeks after we deployed — probably attributable to the LCP improvement rather than any content change.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Cache Components Don't Solve
&lt;/h2&gt;

&lt;p&gt;Three things to be honest about:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mental overhead is higher than the old model.&lt;/strong&gt; "Every fetch is cached" was simpler to reason about, even if it was leaky. The new model is more correct but you have to think about every component boundary. Onboarding a new engineer now requires a 30-minute walkthrough of the cache topology that we never needed before.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging stale caches is still hard.&lt;/strong&gt; When a reader complains they're seeing yesterday's data, you still have to trace tags through the tree to find the culprit. Vercel's cache inspector in the dashboard helps but doesn't surface tag relationships well. We built a small internal CLI that prints the tag tree for a route — saved at least four debugging hours so far.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Pages Router isn't going away.&lt;/strong&gt; If you're still on Pages Router, none of this applies. Vercel signaled at the March 2026 launch that Pages would be supported through at least 2028, but no new features are coming there. Migration to App Router is a prerequisite — non-trivial for any large legacy site.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Bundler Implications
&lt;/h2&gt;

&lt;p&gt;A side effect we didn't anticipate: cache components changed our bundle. Components marked &lt;code&gt;"use cache"&lt;/code&gt; get extracted into separate chunks at build time so they can be shipped independently. Our &lt;code&gt;app/_app.js&lt;/code&gt; shrank from 188 KB to 142 KB. First-load JS dropped enough to bump our PageSpeed score 4 points. None of the cache-components documentation mentions this; we noticed it inspecting the build output.&lt;/p&gt;

&lt;p&gt;Combined with the Rust-based bundler improvements that landed in &lt;a href="https://dev.to/blog/rust-javascript-tooling-takeover-2026"&gt;the Rust takeover of JavaScript tooling&lt;/a&gt;, our cold-start dev experience is now legitimately fast — &lt;code&gt;next dev&lt;/code&gt; warm time dropped from 14 seconds to 4 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You Migrate?
&lt;/h2&gt;

&lt;p&gt;If you're on App Router and your site is data-heavy or you have a large content surface, yes — the ROI is unambiguous. If you're on a small SPA-style App Router app with mostly dynamic content, the upside is smaller (you still get better mental model, but the bill won't move much). If you're on Pages Router, wait until you'd be doing a major rewrite anyway.&lt;/p&gt;

&lt;p&gt;Our advice for teams about to start: do the migration as a series of small PRs, not a big-bang. The flag is opt-in for a reason. Migrate one route segment at a time, measure, ship. Anyone who tells you they migrated their whole site in a weekend either had a tiny site or is going to file three Sev-1 tickets next week.&lt;/p&gt;

&lt;p&gt;A reasonable order of operations: enable the flag and fix breakages first (1-2 weeks), then add &lt;code&gt;"use cache"&lt;/code&gt; to your hottest read paths (1 week), then tackle tag granularity and incident-proof your invalidation logic (1-2 weeks), then handle segment caching for personalized content (1 week). Total: 4-6 weeks for a meaningful site. Less if you're small, more if you're enterprise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Cache components are the rare framework migration where the benefits exceed the marketing. The mental model is cleaner, the performance is real, and the bill goes down. The cost is six weeks of careful work and the willingness to pay attention to tag granularity. If you're already on App Router, this should be the next thing on your roadmap. The team that ships the cache-components migration in Q3 will out-perform the team that doesn't on every metric that matters — TTFB, LCP, build time, and the line item on the Vercel invoice that finance asks you about every quarter.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/nextjs-16-cache-components-migration-2026" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>performance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Fly with the Pilot</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Tue, 12 May 2026 18:03:31 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/fly-with-the-pilot-56cn</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/fly-with-the-pilot-56cn</guid>
      <description>&lt;p&gt;&lt;strong&gt;Fly with the Pilot&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In 2020, a commercial airliner was on course to land at New York's John F. Kennedy International Airport when its crew reported a sudden loss of communication. Despite being in the midst of a densely populated airspace, air traffic controllers were able to quickly locate the aircraft using real-time flight tracking data and 3D visualization, guiding it safely to the ground. This incident highlights the significance of modern surveillance technologies like Automatic Dependent Surveillance-Broadcast (ADS-B) in ensuring air travel safety.&lt;/p&gt;

&lt;p&gt;The ability to track planes in real-time and view their cockpits in 3D is made possible by advancements in ADS-B technology. This innovation has been driven by the aviation industry's need for enhanced safety and efficiency. Companies like Flightradar24 and Plane Finder have been at the forefront of this development, providing real-time flight tracking services to the public. The increasing availability of high-resolution satellite imagery has also contributed to the growth of this technology.&lt;/p&gt;

&lt;p&gt;The key takeaway here is that ADS-B technology is not just about tracking planes; it's about using machine learning algorithms to predict potential flight disruptions, enabling more efficient air traffic management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Predictive Maintenance: The Future of Air Traffic Management
&lt;/h3&gt;

&lt;p&gt;ADS-B technology is integrated with machine learning algorithms to analyze real-time aviation data, predicting potential flight disruptions. This enables air traffic controllers to proactively manage air traffic, reducing delays and increasing overall efficiency. For instance, a study by the Federal Aviation Administration (FAA) found that the use of ADS-B technology reduced flight delays by 10% in 2020 alone. By leveraging this technology, airlines can minimize the impact of disruptions and ensure a smoother flying experience for passengers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Search and Rescue Operations: A New Era of Response Time
&lt;/h3&gt;

&lt;p&gt;When a plane goes missing, every minute counts. The use of real-time aviation data and 3D visualization can significantly improve the response time and effectiveness of search and rescue operations. By visualizing the aircraft's last known location, search teams can pinpoint potential crash sites, reducing the search area by up to 90%. This technology has been successfully used in several high-profile search and rescue operations, including the 2019 disappearance of Malaysia Airlines Flight 370.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beyond Aviation: Unleashing the Potential of ADS-B Technology
&lt;/h3&gt;

&lt;p&gt;The application of ADS-B technology extends beyond the aviation industry. Environmental monitoring, disaster response, and urban planning are just a few areas where this technology can have a significant impact. For example, researchers have used ADS-B technology to study bird migration patterns, providing valuable insights into the impact of climate change on ecosystems. Additionally, the FAA is exploring the use of ADS-B technology in disaster response, enabling first responders to quickly identify areas of need and allocate resources more effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real Problem: Balancing Data Availability with Data Protection
&lt;/h3&gt;

&lt;p&gt;While ADS-B technology has revolutionized the aviation industry, it raises concerns about privacy and national security. The increased availability of real-time flight data and 3D cockpit views may compromise sensitive information about airline operations, crew communications, and passenger data. As a result, companies like Flightradar24 and Plane Finder have implemented robust data protection measures to ensure that sensitive information is kept confidential. This highlights the importance of developing and implementing effective data protection policies to balance the benefits of ADS-B technology with the need to safeguard sensitive information.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Most People Get Wrong: The Limitations of ADS-B Technology
&lt;/h3&gt;

&lt;p&gt;Many people assume that ADS-B technology provides real-time data on every flight, everywhere in the world. However, this is not the case. ADS-B technology relies on satellite signals, which can be affected by weather conditions, interference, and other factors. Additionally, not all aircraft are equipped with ADS-B technology, and some countries have limited or no ADS-B coverage. This means that there are still significant gaps in our understanding of global air traffic patterns, highlighting the need for continued investment in this technology.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion: Embracing the Future of Aviation Surveillance
&lt;/h3&gt;

&lt;p&gt;As the aviation industry continues to evolve, ADS-B technology will play an increasingly important role in ensuring safety, efficiency, and transparency. By embracing this technology and addressing the challenges associated with data protection, we can unlock its full potential and create a safer, more efficient air travel experience for all. To capitalize on this opportunity, airlines and aviation authorities should invest in robust data protection measures and continue to develop and implement effective ADS-B technology solutions.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/archived-track-planes-in-3d" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>flighttracking</category>
      <category>airtraffic</category>
      <category>aviationtechnology</category>
    </item>
    <item>
      <title>Mac OS X on Wii</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Tue, 12 May 2026 18:03:25 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/mac-os-x-on-wii-3do1</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/mac-os-x-on-wii-3do1</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/blog/mac-os-x-on-wii"&gt;Mac OS&lt;/a&gt; X on Wii: Theoretical Possibilities and Technical Feasibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When discussing homebrew development and modification of consumer electronics, one fascinating concept often surfaces: porting Mac OS X to the Nintendo Wii. This might seem far-fetched, but numerous experts have confirmed that, theoretically, such a port is possible. To understand why, we need to delve into the similarities between the PowerPC-based Wii processor and the PowerPC architecture used in older Macintosh computers.&lt;/p&gt;

&lt;p&gt;The Wii's Broadway processor, a variant of the PowerPC 750, shares a significant amount of code with the G3 and G4 processors used in older Macs. This shared architecture makes it theoretically possible for developers to adapt Mac OS X to run on the Wii. However, this is not a trivial task. The Wii's hardware configuration is unique, and the operating system's kernel and device drivers would require significant modifications to accommodate it.&lt;/p&gt;

&lt;p&gt;The key takeaway is that, despite the technical challenges involved, a successful port of Mac OS X to the Wii would demonstrate the versatility of open-source operating systems and the ingenuity of the homebrew development community. This project highlights non-obvious connections between the gaming industry and the broader field of computer science, particularly in areas like reverse engineering and low-level programming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Wii's Hardware Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Nintendo Wii's hardware is centered around its PowerPC-based processor, the Broadway. This processor is a variant of the PowerPC 750, which was widely used in older Macintosh computers. The Broadway is a 90nm SOI (Silicon on Insulator) process, with 128-bit floating-point operations and a maximum clock speed of 729 MHz. The Wii also features 88MB of RAM, which is dedicated to the GPU and 512MB of external RAM for the CPU.&lt;/p&gt;

&lt;p&gt;The Wii's hardware configuration is what makes it theoretically possible for developers to adapt Mac OS X to run on the device. The shared PowerPC architecture between the Wii and older Macs provides a foundation for adaptation. However, the Wii's use of an external RAM module and a unique GPU requires significant modifications to the operating system's kernel and device drivers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Porting Process&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Porting Mac OS X to the Wii would require a deep understanding of both the Wii's hardware configuration and the inner workings of the operating system. Developers would need to modify the kernel and device drivers to accommodate the Wii's unique hardware. This would involve rewriting significant portions of the operating system to ensure compatibility with the Wii's processor, RAM, and GPU.&lt;/p&gt;

&lt;p&gt;The porting process would also require a thorough understanding of PowerPC assembly language and low-level programming. Developers would need to be familiar with the Wii's hardware registers, interrupts, and memory management unit (MMU) to ensure proper operation of the operating system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Most People Get Wrong&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many people assume that porting Mac OS X to the Wii would be a trivial task, simply a matter of copying the operating system onto a storage device and booting it. However, this is far from the truth. The Wii's hardware configuration is unique, and the operating system's kernel and device drivers would require significant modifications to accommodate it.&lt;/p&gt;

&lt;p&gt;The real problem is not the technical feasibility of the port, but rather the time and effort required to complete it. Porting an operating system to a new platform is a complex task that requires a deep understanding of both the hardware and the software. It is not a task for the faint of heart, and it is certainly not something that can be completed in a matter of weeks or months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Benefits of a Successful Port&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A successful port of Mac OS X to the Wii would have significant implications for the homebrew development community. It would demonstrate the versatility of open-source operating systems and the ingenuity of developers who push the boundaries of what is possible.&lt;/p&gt;

&lt;p&gt;Furthermore, a successful port would inspire similar projects for other embedded systems. It would show that even the most complex and seemingly intractable problems can be solved with enough time, effort, and determination. This would have a positive impact on the broader field of computer science, particularly in areas like reverse engineering and low-level programming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion and Recommendations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, porting Mac OS X to the Wii is a challenging but theoretically possible task. While the technical requirements are significant, a successful port would have a positive impact on the homebrew development community and the broader field of computer science.&lt;/p&gt;

&lt;p&gt;If you're interested in exploring this project further, I recommend starting by studying the Wii's hardware configuration and PowerPC assembly language. From there, you can begin to explore the inner workings of Mac OS X and how it can be adapted to run on the Wii.&lt;/p&gt;

&lt;p&gt;But be warned: this project is not for the faint of heart. It requires a deep understanding of both the hardware and the software, as well as a significant amount of time and effort. If you're up for the challenge, however, it could be a rewarding and enlightening experience that pushes the boundaries of what is possible with homebrew development.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/archived-mac-os-x-on-nintendo-wii-2" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>consolehacking</category>
      <category>macosx</category>
      <category>nintendowii</category>
    </item>
    <item>
      <title>Unlocking Tmux Customization for Developers: A Comprehensive Guide</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Tue, 12 May 2026 18:03:00 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/unlocking-tmux-customization-for-developers-a-comprehensive-guide-3gkc</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/unlocking-tmux-customization-for-developers-a-comprehensive-guide-3gkc</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/blog/make-tmux-pretty-and-usable"&gt;Unlocking Tmux&lt;/a&gt; Customization for Developers: A Comprehensive Guide&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;71% of developers rely on the terminal as their primary interface for development. Despite its importance, the default terminal experience often falls short of expectations. This is where Tmux comes in – a terminal multiplexer that has revolutionized the way developers work. With over 1,000 packages available on the Tmux Plugin Manager (TPM), the possibilities for customization are endless.&lt;/p&gt;

&lt;p&gt;Tmux's impact extends beyond the development community. Traders and analysts in finance rely on complex terminal interfaces for real-time data analysis, mirroring the need for a seamless and customizable experience. The rise of remote work and the increasing need for developers to manage multiple projects and tasks simultaneously have fueled Tmux's growth. As we'll explore, there's more to Tmux customization than just aesthetics – it's about unlocking increased productivity and efficiency.&lt;/p&gt;

&lt;p&gt;For those new to Tmux, it's essential to grasp the core concept: a terminal multiplexer is a single process that can manage multiple terminal sessions and windows. This fundamental idea sets the stage for the customization possibilities we'll delve into. With Tmux, you can create a tailored environment that boosts your productivity and makes your workflow more enjoyable.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Creating a Custom Tmux Environment: Getting Started&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To unlock the full potential of Tmux, you need to configure it to your liking. This involves setting up the basic layout, including the number of windows, panes, and the initial layout. You can achieve this by modifying the &lt;code&gt;~/.tmux.conf&lt;/code&gt; file. Here's a basic example to get you started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Set the initial window layout to 2x2&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; mode-keys vi
&lt;span class="nb"&gt;bind &lt;/span&gt;h &lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="nt"&gt;-pane&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt;
&lt;span class="nb"&gt;bind &lt;/span&gt;j &lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="nt"&gt;-pane&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;span class="nb"&gt;bind &lt;/span&gt;k &lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="nt"&gt;-pane&lt;/span&gt; &lt;span class="nt"&gt;-U&lt;/span&gt;
&lt;span class="nb"&gt;bind &lt;/span&gt;l &lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="nt"&gt;-pane&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration sets up a basic 2x2 layout using vi mode. You can customize this further by adding more bindings and mappings to suit your needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Customizing Tmux: Themes and Plugins&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tmux's popularity has led to the development of a thriving ecosystem of plugins and themes. With over 1,000 packages available on the TPM, you can find a wide range of options to suit your taste. Some popular themes include the Dracula theme, which offers a dark and sleek design, and the Material theme, which provides a modern and minimalist aesthetic.&lt;/p&gt;

&lt;p&gt;In addition to themes, plugins offer a wealth of functionality. Some popular plugins include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;tmux-resurrect&lt;/code&gt;: allows you to save and restore your Tmux sessions&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;tmux-save-buffer&lt;/code&gt;: saves the buffer contents to a file&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;tmux-persist-on&lt;/code&gt;: keeps the terminal session alive even when the connection drops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When selecting plugins, consider the specific use cases and features you need. For example, if you work with multiple projects, you might want to use &lt;code&gt;tmux-resurrect&lt;/code&gt; to save and restore your sessions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What Most People Get Wrong&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Many developers struggle with Tmux because they focus on aesthetics rather than functionality. This is where most people go wrong – they get caught up in making their Tmux environment look pretty, but neglect to optimize its performance. In reality, the most effective Tmux configurations are those that prioritize functionality and ease of use.&lt;/p&gt;

&lt;p&gt;A common mistake is to over-complicate the configuration by adding too many plugins and mappings. This can lead to a cluttered and confusing interface, ultimately defeating the purpose of using Tmux in the first place. Instead, focus on the essential features and mappings that enhance your productivity.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Tmux Productivity Hacks&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To take your Tmux setup to the next level, consider the following productivity hacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Use &lt;code&gt;tmux-continuum&lt;/code&gt; to create a continuous, infinite loop of terminal windows&lt;/li&gt;
&lt;li&gt;  Employ &lt;code&gt;tmux-session-manager&lt;/code&gt; to manage and organize your Tmux sessions&lt;/li&gt;
&lt;li&gt;  Utilize &lt;code&gt;tmux-clipboard&lt;/code&gt; to copy and paste text between Tmux windows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These hacks can significantly improve your workflow by streamlining essential tasks and reducing the time spent switching between windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion: Unlocking Tmux Customization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tmux has revolutionized the way developers work by offering a customizable and seamless experience. By unlocking its full potential, you can increase your productivity and make your workflow more enjoyable. With this comprehensive guide, you've learned how to create a custom Tmux environment, customize your layout with themes and plugins, and optimize your performance with productivity hacks.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/archived-tmux-customization-for-developers" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tmux</category>
      <category>productivity</category>
      <category>terminal</category>
    </item>
    <item>
      <title>CadQuery Simplifies 3D Modeling</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Tue, 12 May 2026 18:02:52 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/cadquery-simplifies-3d-modeling-1k3</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/cadquery-simplifies-3d-modeling-1k3</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/blog/cadquery-for-3d-cad-modeling"&gt;CadQuery Simplifies&lt;/a&gt; 3D Modeling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the past year, the CadQuery open-source library has grown by 20% month-over-month, with over 1,000 new users joining its community. What's driving this growth? A combination of factors, including CadQuery's unique strengths in parametric design and its Pythonic API, which has made it a go-to choice for industries like aerospace and automotive. But beyond its technical merits, CadQuery's rise reflects a broader shift towards open-source and collaborative development in the CAD industry.&lt;/p&gt;

&lt;p&gt;At its core, this shift is about customizability, flexibility, and cost-effectiveness. Traditional CAD software vendors like Autodesk and SolidWorks charge premium prices for their products, often limiting users to a specific set of features and workflows. In contrast, CadQuery's open-source nature allows users to modify and extend the library to suit their specific needs. This has significant implications for industries where complex geometries and iterative design processes are common.&lt;/p&gt;

&lt;p&gt;The key takeaway here is that CadQuery is not just another tool for 3D modeling – it's a game-changer for industries that require customization and flexibility. With its growing community and increasing adoption, CadQuery is poised to disrupt traditional CAD software markets dominated by proprietary vendors.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Parametric Design&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of the most significant implications of CadQuery's parametric design capabilities is for industries like aerospace and automotive. In these fields, complex geometries and iterative design processes are common, and the ability to easily modify and optimize designs is essential. CadQuery's parametric design capabilities make it possible to create complex models using a high-level, object-oriented syntax. This is a major departure from traditional CAD software, which often relies on low-level, procedural code.&lt;/p&gt;

&lt;p&gt;For example, consider a typical aircraft fuselage design. With CadQuery, a designer can create a parametric model that takes into account factors like aerodynamics, weight, and structural integrity. This model can be easily modified and optimized using a variety of techniques, from numerical methods to machine learning algorithms. The result is a highly customized design that meets the specific needs of the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Integration with Data Science and Machine Learning&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;CadQuery's Python interface has facilitated integration with popular data science and machine learning frameworks like NumPy, pandas, and scikit-learn. This has enabled new applications in fields like generative design and design optimization. For example, a designer can use CadQuery to generate a set of parametric models, and then use machine learning algorithms to optimize the design for specific criteria like weight, cost, or performance.&lt;/p&gt;

&lt;p&gt;This integration is not limited to data science and machine learning. CadQuery can also be used with popular libraries like Blender and FreeCAD, enabling a wide range of applications from computer-aided design to computer-aided engineering.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Security and Reliability&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Contrary to conventional wisdom, the open-source nature of CadQuery may actually enhance its security and reliability. A community-driven development process can lead to more rigorous testing and bug fixing, as multiple developers and users work together to identify and resolve issues.&lt;/p&gt;

&lt;p&gt;In fact, a study by the Linux Foundation found that open-source software tends to have fewer vulnerabilities and bugs than proprietary software. This is because open-source projects are often driven by a community of developers who are motivated to improve the software, rather than a single vendor trying to maximize profits.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What Most People Get Wrong&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Many people assume that open-source software is inherently insecure or unreliable. However, this couldn't be further from the truth. In reality, open-source software is often more secure and reliable than proprietary software, due to the collaborative nature of the development process.&lt;/p&gt;

&lt;p&gt;Another common misconception is that open-source software is only suitable for hobbyists or enthusiasts. However, CadQuery is used by industry professionals and researchers alike, and its capabilities are unmatched by many proprietary CAD software tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Real Problem&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The real problem with traditional CAD software is that it's often too rigid and inflexible. Users are limited to a specific set of features and workflows, and customizability is often non-existent. This can lead to a range of issues, from design inefficiencies to cost overruns.&lt;/p&gt;

&lt;p&gt;In contrast, CadQuery offers a highly customizable and flexible solution that can be tailored to meet the specific needs of any project. Whether you're a hobbyist or an industry professional, CadQuery is an essential tool for anyone working with 3D modeling and CAD design.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion and Recommendation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The rise of CadQuery reflects a broader shift towards open-source and collaborative development in the CAD industry. With its parametric design capabilities, integration with data science and machine learning frameworks, and secure and reliable open-source nature, CadQuery is poised to disrupt traditional CAD software markets dominated by proprietary vendors.&lt;/p&gt;

&lt;p&gt;If you're working with 3D modeling and CAD design, I highly recommend giving CadQuery a try. Its Pythonic API and open-source nature make it an ideal choice for anyone looking for a highly customizable and flexible solution. Whether you're a hobbyist or an industry professional, CadQuery is an essential tool that can help you create complex models with ease.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/archived-cadquery-3d-cad-modeling" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>3dmodeling</category>
      <category>cadsoftware</category>
      <category>python</category>
    </item>
    <item>
      <title>Cloud Repatriation: The Hidden Costs of Public Cloud Architecture</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Sat, 09 May 2026 07:19:02 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/cloud-repatriation-the-hidden-costs-of-public-cloud-architecture-20fo</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/cloud-repatriation-the-hidden-costs-of-public-cloud-architecture-20fo</guid>
      <description>&lt;p&gt;When 37signals reported in late 2024 that they had saved over $2 million by leaving AWS, a wave of CTOs ran the numbers and quietly came to the same conclusion: for predictable, steady-state workloads, the public cloud has gotten expensive in ways that are hard to defend on a finance call.&lt;/p&gt;

&lt;p&gt;Two years later, repatriation is not a fringe move. It is a default consideration on any infrastructure review at a company past Series B with stable demand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Cost Drivers Behind Repatriation
&lt;/h2&gt;

&lt;p&gt;The math has not really changed. The visibility of the math has.&lt;/p&gt;

&lt;h3&gt;
  
  
  Egress Fees
&lt;/h3&gt;

&lt;p&gt;AWS charges roughly $0.09 per GB out to the internet beyond the first 100 GB. For a company moving 200 TB/month, that is over $18,000 monthly — for the privilege of letting your data leave. Hetzner charges zero. Cloudflare R2 charges zero. The egress tax is now the single most cited reason for moving.&lt;/p&gt;

&lt;h3&gt;
  
  
  GPU Markups
&lt;/h3&gt;

&lt;p&gt;H100 instances on AWS list at roughly 3-4x the bare-metal cost amortized over depreciation. For AI workloads, this delta is often the entire margin of the business.&lt;/p&gt;

&lt;h3&gt;
  
  
  Predictability Premium
&lt;/h3&gt;

&lt;p&gt;Cloud is priced for elasticity. If your workload is not elastic, you are paying for an option you never exercise.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Repatriation Does Not Pay
&lt;/h2&gt;

&lt;p&gt;Repatriation is a trap for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pre-Series-A startups (your time is more valuable than the savings)&lt;/li&gt;
&lt;li&gt;Genuinely bursty workloads (the cloud was actually designed for these)&lt;/li&gt;
&lt;li&gt;Compliance-heavy industries without dedicated platform staff&lt;/li&gt;
&lt;li&gt;Teams without at least one engineer who has run a fleet before&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;The teams getting this right do not pick a side. They run a hybrid:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Where it runs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Steady-state web tier&lt;/td&gt;
&lt;td&gt;Hetzner / OVH / colo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU training&lt;/td&gt;
&lt;td&gt;Lambda Labs, Crusoe, dedicated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bursty traffic&lt;/td&gt;
&lt;td&gt;AWS, Cloudflare Workers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object storage&lt;/td&gt;
&lt;td&gt;Cloudflare R2, Backblaze B2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge&lt;/td&gt;
&lt;td&gt;Cloudflare, Vercel&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Tooling like Pulumi, Crossplane, and the maturing Talos Linux distribution have made multi-environment Kubernetes nearly turnkey for teams of any size.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Takeaway
&lt;/h2&gt;

&lt;p&gt;Cloud repatriation is not about hating AWS. It is about matching workload shape to pricing shape. The cloud is exquisite for spiky, unpredictable demand and miserable for steady-state at scale. Most companies have both — the question is whether your bill reflects that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/blog/migrating-from-digitalocean-to-hetzner"&gt;migrating from DigitalOcean to Hetzner&lt;/a&gt; — A real migration story with concrete cost numbers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/blog/hyperscalers-outspend-megaprojects"&gt;why hyperscalers are outspending megaprojects&lt;/a&gt; — Capex flows that explain why cloud margins are squeezed.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/blog/ai-devops-sre-small-team-2026"&gt;DevOps and SRE for small teams in 2026&lt;/a&gt; — The tooling stack that makes hybrid infra manageable.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/hidden-costs-cloud-architecture" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>infrastructure</category>
      <category>business</category>
    </item>
    <item>
      <title>Sustainable Tech: Why Green Datacenters Are Non-Negotiable</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Sat, 09 May 2026 07:18:45 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/sustainable-tech-why-green-datacenters-are-non-negotiable-553b</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/sustainable-tech-why-green-datacenters-are-non-negotiable-553b</guid>
      <description>&lt;h2&gt;
  
  
  The Hidden Carbon Cost of Artificial Intelligence
&lt;/h2&gt;

&lt;p&gt;The explosive growth of generative AI has brought about a silent environmental crisis. Training a single massive frontier model consumes as much electricity as thousands of homes use in a year. Furthermore, the inference required to answer millions of daily AI queries requires an unprecedented density of GPU clusters. &lt;/p&gt;

&lt;p&gt;Data centers, which once accounted for a negligible fraction of global power consumption, are now straining municipal power grids worldwide. The tech industry can no longer ignore its carbon footprint. The pivot to &lt;strong&gt;Green Datacenters&lt;/strong&gt; is no longer a PR initiative; it is a regulatory and operational necessity.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Death of Traditional Air Cooling
&lt;/h3&gt;

&lt;p&gt;To understand the energy crisis, one must look at how data centers are cooled. Historically, massive HVAC systems pumped chilled air through server racks. This method is incredibly inefficient. As GPU architectures (like Nvidia's Blackwell series) push thermal limits to extremes, air cooling is physically incapable of dissipating the heat.&lt;/p&gt;

&lt;p&gt;The industry standard has shifted to &lt;strong&gt;Direct-to-Chip Liquid Cooling&lt;/strong&gt; and &lt;strong&gt;Immersion Cooling&lt;/strong&gt;. By submerging server motherboards entirely in non-conductive, dielectric fluid, data centers can remove heat with near-perfect efficiency. This eliminates the need for massive fans and air conditioners, drastically lowering the Power Usage Effectiveness (PUE) ratio of the facility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Strategic Location and Renewable Microgrids
&lt;/h3&gt;

&lt;p&gt;You can no longer build a data center anywhere. The new strategy is geographic optimization. Tech giants are placing new infrastructure directly adjacent to stranded renewable energy sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Geothermal in Iceland:&lt;/strong&gt; Tapping into the earth's natural heat to power servers with zero emissions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hydroelectric in Scandinavia:&lt;/strong&gt; Utilizing massive, consistent water flow to power and cool server farms simultaneously.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, we are seeing the rise of &lt;strong&gt;Nuclear-Powered Data Centers&lt;/strong&gt;. Small Modular Reactors (SMRs) are being co-located with server farms to provide 24/7, zero-carbon baseload power that wind and solar cannot guarantee.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Path to Net-Zero
&lt;/h3&gt;

&lt;p&gt;Major cloud providers have pledged to become carbon negative by 2030. Achieving this requires not just green energy, but circular hardware lifecycles—recycling rare earth metals from decommissioned GPUs and repurposing excess server heat to warm local municipal buildings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt; Sustainability is the new frontier of tech infrastructure. Companies that fail to optimize for energy efficiency will find themselves crippled by soaring power costs and strict government carbon taxes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/sustainable-tech-green-datacenters" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>sustainability</category>
      <category>datacenters</category>
      <category>environment</category>
    </item>
    <item>
      <title>The Demise of the 9-to-5: How Async Work is Winning</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Sat, 09 May 2026 07:18:29 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/the-demise-of-the-9-to-5-how-async-work-is-winning-2jd5</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/the-demise-of-the-9-to-5-how-async-work-is-winning-2jd5</guid>
      <description>&lt;h2&gt;
  
  
  The Remote Work Hangover
&lt;/h2&gt;

&lt;p&gt;When the pandemic forced the corporate world into remote work, companies made a fatal architectural error: they simply digitized the physical office. Instead of walking into a conference room, employees logged into back-to-back Zoom calls. Instead of tapping a colleague on the shoulder, they sent rapid-fire Slack messages demanding instant replies.&lt;/p&gt;

&lt;p&gt;We achieved remote work, but we lost deep work. The constant context-switching of synchronous communication has led to unprecedented employee burnout. The correction is finally here: the transition to &lt;strong&gt;Asynchronous Work&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Asynchronous Advantage
&lt;/h3&gt;

&lt;p&gt;Asynchronous (async) communication operates on a simple premise: information is exchanged without the expectation of an immediate response. This respects the maker's schedule and allows global teams to collaborate seamlessly across twelve different time zones without forcing someone to wake up at 3:00 AM for a status update.&lt;/p&gt;

&lt;p&gt;Companies that master async work—like GitLab, Automattic, and Doist—report massively higher output quality. When employees are given the space to focus for four uninterrupted hours, they produce better code, better designs, and better strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  The New Async Tool Stack
&lt;/h3&gt;

&lt;p&gt;The tools that define a company's culture are changing. We are moving away from ephemeral chat and video calls toward persistent, structured communication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Async Video (Loom):&lt;/strong&gt; Replacing the "quick 15-minute sync" with a 3-minute screen recording that the recipient can watch at 1.5x speed whenever they have downtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured Decision Logs (Notion, Linear):&lt;/strong&gt; Moving away from making decisions in messy Slack threads to using centralized, searchable documents where context is preserved forever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threaded Communication (Twist, Campfire):&lt;/strong&gt; Replacing chaotic chat channels with strictly threaded conversations, ensuring that discussions stay on topic and don't require constant monitoring.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Cultural Shift: A Writing Culture
&lt;/h3&gt;

&lt;p&gt;Transitioning to async is not a software problem; it is a cultural problem. Async work absolutely requires a &lt;strong&gt;Writing Culture&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you cannot communicate clearly, concisely, and completely in written form, you cannot survive in an async environment. Every proposal, bug report, and strategy document must contain enough context that the reader can fully understand the issue without needing to ask a clarifying question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Future:&lt;/strong&gt; The 9-to-5 schedule was an artifact of the industrial revolution. In the knowledge economy, forcing everyone to think at the same time is wildly inefficient. The future belongs to organizations that measure output, not hours spent in a Zoom grid.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/demise-9-to-5-async-tools" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>remotework</category>
      <category>productivity</category>
      <category>culture</category>
    </item>
    <item>
      <title>Cybersecurity in the Era of Deepfakes and AI Phishing</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Sat, 09 May 2026 07:17:39 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/cybersecurity-in-the-era-of-deepfakes-and-ai-phishing-22a2</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/cybersecurity-in-the-era-of-deepfakes-and-ai-phishing-22a2</guid>
      <description>&lt;p&gt;In February 2026, a finance employee at a Hong Kong subsidiary of Arup wired $25 million to attackers after a video call with what appeared to be the company's CFO and several colleagues. Every face on the call was synthetic. The voices were synthetic. The mannerisms had been trained on YouTube earnings calls.&lt;/p&gt;

&lt;p&gt;This is not a hypothetical anymore. The FBI's Internet Crime Complaint Center logged $1.4 billion in deepfake-driven business email and voice compromise in 2025 alone. The defensive playbook that worked in 2023 — "call back on a known number" — is no longer sufficient because the known number can be spoofed and the voice on the other end can be cloned in real time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed in 2026
&lt;/h2&gt;

&lt;p&gt;Three things hit production-grade quality almost simultaneously:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Real-time face-swap on consumer GPUs (sub-50ms latency)&lt;/li&gt;
&lt;li&gt;Voice cloning from &amp;lt;5 seconds of audio (ElevenLabs Flash v2, similar)&lt;/li&gt;
&lt;li&gt;Open-source models that match closed-source quality&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The threat actor's marginal cost dropped to near zero. Defense had to industrialize.&lt;/p&gt;

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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tooling&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Identity provenance&lt;/td&gt;
&lt;td&gt;C2PA content credentials, device attestation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Liveness detection&lt;/td&gt;
&lt;td&gt;Persona, Onfido, Stripe Identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voice biometrics&lt;/td&gt;
&lt;td&gt;Pindrop, Nuance Gatekeeper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time deepfake detection&lt;/td&gt;
&lt;td&gt;Reality Defender, Sensity, Truepic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Process controls&lt;/td&gt;
&lt;td&gt;Out-of-band confirmation, dual-authorization&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Cryptographic Provenance Wins Long-Term
&lt;/h3&gt;

&lt;p&gt;The most durable defense is not detection — it is provenance. C2PA-signed media, hardware attestation on capture devices, and authenticated cameras on phones flip the model: instead of trying to spot fakes, you require proof of authenticity. Adobe, Sony, Nikon, and (as of late 2025) Apple's iPhone capture pipeline all support C2PA signing now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Process Beats Technology
&lt;/h3&gt;

&lt;p&gt;The Arup attack succeeded despite the company having strong endpoint security. The control that would have stopped it — mandatory out-of-band verification of any wire transfer above a threshold — was a process control, not a technology one. Mature security programs are leaning back into procedures the technology era tried to eliminate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI-vs-AI Arms Race
&lt;/h2&gt;

&lt;p&gt;Detection vendors and synthesis vendors are now in a continuous catch-up loop. Reality Defender publishes detection improvements; the next open-source diffusion model defeats them within weeks. This pattern will not stabilize. Treat detection as defense-in-depth, not a primary control.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;The era when "I saw it with my own eyes" was a sufficient verification primitive is over. The replacement is layered: cryptographic provenance for media, process controls for authorization, and AI detection as one signal among several. Any single-layer defense is one model release away from obsolete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/blog/anthropic-ai-id-rule"&gt;Anthropic's AI identification policy&lt;/a&gt; — How model providers are responding to identity fraud.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/blog/future-of-everything-is-lies"&gt;the synthetic-media trust collapse&lt;/a&gt; — The broader cultural picture behind the security problem.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/blog/firebase-security-breach"&gt;lessons from the Firebase security breach&lt;/a&gt; — How identity-layer attacks chain into platform compromise.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/cybersecurity-era-of-deepfakes" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>ai</category>
      <category>security</category>
    </item>
    <item>
      <title>Rust Quietly Took Over JavaScript Tooling: A 2026 Map of What Replaced What</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Sat, 09 May 2026 07:17:32 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/rust-quietly-took-over-javascript-tooling-a-2026-map-of-what-replaced-what-3l76</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/rust-quietly-took-over-javascript-tooling-a-2026-map-of-what-replaced-what-3l76</guid>
      <description>&lt;h2&gt;
  
  
  The day my CI pipeline went from 11 minutes to 90 seconds
&lt;/h2&gt;

&lt;p&gt;Last month I migrated a 240K-line TypeScript monorepo from a Node-based toolchain — Webpack, ESLint, Prettier, Jest, tsc — to an almost entirely Rust-based one: Turbopack, Oxc, Biome, Vitest with Rolldown, and tsgo. CI fell from 11 minutes 14 seconds to 1 minute 28 seconds. Local dev startup went from 8.4 seconds to 0.6.&lt;/p&gt;

&lt;p&gt;This is not an isolated number. It is the tail end of a quiet, three-year rewrite of the JavaScript toolchain in Rust and Go. As of mid-2026 the rewrite is mostly done. Here is the practical map for working developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What got replaced, by tool
&lt;/h2&gt;

&lt;p&gt;The state of play, with what most teams should actually be running:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;th&gt;Old (Node)&lt;/th&gt;
&lt;th&gt;New (Rust/Go)&lt;/th&gt;
&lt;th&gt;Status May 2026&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bundler (app)&lt;/td&gt;
&lt;td&gt;Webpack, Rollup&lt;/td&gt;
&lt;td&gt;Turbopack, Rspack, Rolldown&lt;/td&gt;
&lt;td&gt;GA, ship it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bundler (lib)&lt;/td&gt;
&lt;td&gt;Rollup, tsup&lt;/td&gt;
&lt;td&gt;Rolldown, tsdown&lt;/td&gt;
&lt;td&gt;GA, ship it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev server&lt;/td&gt;
&lt;td&gt;Vite (esbuild)&lt;/td&gt;
&lt;td&gt;Vite 7 + Rolldown&lt;/td&gt;
&lt;td&gt;GA, default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linter&lt;/td&gt;
&lt;td&gt;ESLint&lt;/td&gt;
&lt;td&gt;Biome 2, Oxlint&lt;/td&gt;
&lt;td&gt;GA, ship it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formatter&lt;/td&gt;
&lt;td&gt;Prettier&lt;/td&gt;
&lt;td&gt;Biome 2&lt;/td&gt;
&lt;td&gt;GA, ship it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type checker&lt;/td&gt;
&lt;td&gt;tsc&lt;/td&gt;
&lt;td&gt;tsgo (Go), stc (Rust)&lt;/td&gt;
&lt;td&gt;tsgo beta May 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test runner&lt;/td&gt;
&lt;td&gt;Jest, Vitest&lt;/td&gt;
&lt;td&gt;Vitest + Rolldown&lt;/td&gt;
&lt;td&gt;GA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Package manager&lt;/td&gt;
&lt;td&gt;npm, yarn&lt;/td&gt;
&lt;td&gt;pnpm, Bun&lt;/td&gt;
&lt;td&gt;GA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monorepo&lt;/td&gt;
&lt;td&gt;Lerna, Nx (JS)&lt;/td&gt;
&lt;td&gt;Turborepo, Nx (Rust core)&lt;/td&gt;
&lt;td&gt;GA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Minifier&lt;/td&gt;
&lt;td&gt;Terser&lt;/td&gt;
&lt;td&gt;swc, Oxc minify&lt;/td&gt;
&lt;td&gt;GA&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are still on Webpack and ESLint in mid-2026, you are not behind in some abstract sense. You are paying real money in CI time and developer minutes every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  The big four to know
&lt;/h2&gt;

&lt;p&gt;Four tools dominate the new landscape. Knowing what each one is for clarifies the rest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Oxc
&lt;/h3&gt;

&lt;p&gt;Oxc is a Rust-based JavaScript and TypeScript toolchain from a small team led by Boshen. It includes a parser, linter (Oxlint), resolver, and minifier. Oxlint is roughly 50-100x faster than ESLint on equivalent rule sets. As of v1.0 in early 2026, it covers roughly 85% of common ESLint rules and runs as a drop-in pre-pass in many setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Biome
&lt;/h3&gt;

&lt;p&gt;Biome 2 (released February 2026) is a Rust-based linter and formatter that aims to fully replace ESLint and Prettier. It is opinionated, fast, and trades off some ESLint plugin compatibility for coherence. For a greenfield project, Biome is the default I would pick. For an existing project, Oxlint is often easier to slot in alongside ESLint.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rolldown and Turbopack
&lt;/h3&gt;

&lt;p&gt;Rolldown is a Rust port of Rollup with Vite compatibility, now powering Vite 7 by default. Turbopack is Vercel's Rust bundler, the engine inside Next.js 15+. They are not really competitors: Rolldown is the universal library and app bundler, Turbopack is tightly integrated into Next.js dev and build.&lt;/p&gt;

&lt;p&gt;For most Vite users, the migration to Rolldown is invisible — it just becomes the default. For Next.js users, Turbopack is now the default in dev and stable for production builds as of Next.js 15.4.&lt;/p&gt;

&lt;h3&gt;
  
  
  tsgo
&lt;/h3&gt;

&lt;p&gt;tsgo is the Go rewrite of the TypeScript compiler that Microsoft began publicly previewing in March 2025 and which entered beta in early 2026. On large codebases, type checking is roughly 10x faster. It is not yet GA for production type checking but is increasingly safe for editor IntelliSense and CI parallel checks. The plan, per the official roadmap, is parity with tsc by late 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real performance numbers
&lt;/h2&gt;

&lt;p&gt;On the same 240K-line monorepo, before and after migration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ESLint over the whole repo: 94s. Oxlint: 1.7s.&lt;/li&gt;
&lt;li&gt;Prettier check: 41s. Biome check: 0.9s.&lt;/li&gt;
&lt;li&gt;tsc full check: 76s. tsgo full check: 8s.&lt;/li&gt;
&lt;li&gt;Webpack production build: 6m 12s. Turbopack: 41s.&lt;/li&gt;
&lt;li&gt;Jest full suite: 3m 30s. Vitest with Rolldown: 1m 5s.&lt;/li&gt;
&lt;li&gt;Total CI: 11m 14s to 1m 28s.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The wins compound. Faster lint encourages stricter rules. Faster type checks encourage smaller, more incremental PRs. Faster builds enable preview deploys per commit instead of per merge. The cultural shift from these tools is at least as valuable as the raw seconds saved.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to be careful about
&lt;/h2&gt;

&lt;p&gt;A few traps I hit personally:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Biome plugin parity is not 100%.&lt;/strong&gt; If you depend on niche ESLint plugins (eslint-plugin-jest-dom, custom internal plugins), audit before migrating. Oxlint is a softer landing because it can run alongside ESLint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rolldown breaking changes are still landing.&lt;/strong&gt; It is GA in Vite 7 but expect occasional plugin incompatibilities through Q3 2026. Pin versions in libraries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tsgo is beta.&lt;/strong&gt; Use it for editor and CI parallel checks. Do not rely on it as your only type-check gate yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bun vs Node in production.&lt;/strong&gt; Bun is fast, but production parity with Node is still imperfect for some npm packages. We use pnpm in CI and Node in production, with Bun only in local scripts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editor extension lag.&lt;/strong&gt; Some editor integrations — VS Code in particular — picked up Biome and Oxlint quickly, but JetBrains and Neovim plugins lagged by several months. If your team standardizes on a non-VSCode editor, check support before committing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source map fidelity.&lt;/strong&gt; Rust bundlers have caught up but historically had subtle source map bugs that broke Sentry-style error reporting. Verify your error monitoring still works post-migration. We caught a 3-week window where stack traces were one line off after a Turbopack upgrade.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The migration we got wrong
&lt;/h2&gt;

&lt;p&gt;Not every swap was painless. Our first attempt to move from Jest to Vitest broke 47 snapshot tests because Vitest's snapshot serialization differs subtly from Jest's. We accepted the new snapshots wholesale, which masked one real regression that customer support eventually surfaced. The lesson: when changing a test runner, do not accept a wave of snapshot changes blindly. Either migrate snapshots one suite at a time with manual review, or treat the first post-migration release with extra production monitoring.&lt;/p&gt;

&lt;p&gt;The second mistake was migrating the linter and the formatter in the same week. When CI started failing differently, we could not isolate which tool was at fault. Stagger toolchain swaps. One change per week, ideally one per fortnight, with a clean baseline between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rust won the tooling layer
&lt;/h2&gt;

&lt;p&gt;Rust did not win because of language ideology. It won because three properties matched the work:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Predictable performance with no GC pauses, which matters for incremental tooling that runs on every keystroke.&lt;/li&gt;
&lt;li&gt;Strong concurrency primitives that map well to multi-core lint and build work.&lt;/li&gt;
&lt;li&gt;A coherent ecosystem (swc, oxc, biome) where teams build on each other's parsers and ASTs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Go has carved out a parallel niche, mostly via Microsoft picking it for tsgo because of its ecosystem fit at Microsoft. The future is plural: Rust dominates the broader tooling, Go owns the type checker, and JavaScript itself remains the language we write.&lt;/p&gt;

&lt;p&gt;The interesting open question is what happens to authoring. So far the rewrite has been about tools that operate on JavaScript, not the language itself. But TypeScript 6, expected later in 2026, will ship with the tsgo runtime as the default in some configurations, which means even the language tooling we touch every day will have a non-JavaScript core. Five years ago that would have felt strange. In 2026 it feels obviously correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ecosystem cost of speed
&lt;/h2&gt;

&lt;p&gt;One concern worth voicing: the Rust toolchain, while faster, is harder for casual contributors to extend. ESLint plugins are JavaScript files anyone can write. Oxlint and Biome rules require Rust knowledge, and the contributor pool is smaller. Long-term, this could slow down the rate of new rule innovation in linters specifically. The maintainers are aware of this and both Oxc and Biome are working on plugin systems that allow JavaScript extensions, but neither is fully landed as of May 2026.&lt;/p&gt;

&lt;p&gt;This is a real trade-off, not a deal-breaker. Most teams use a small, stable set of rules and benefit from the speed far more than they suffer from harder-to-write plugins. But if your codebase depends on dozens of niche or in-house ESLint rules, weigh the migration cost honestly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for you
&lt;/h2&gt;

&lt;p&gt;A practical 2026 migration order for an existing JS/TS project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Replace Prettier with Biome formatter. Lowest risk, instant win.&lt;/li&gt;
&lt;li&gt;Add Oxlint as a pre-pass alongside ESLint. Catch the easy stuff fast.&lt;/li&gt;
&lt;li&gt;Move to Vite 7 (or stay on it; Rolldown is now under the hood).&lt;/li&gt;
&lt;li&gt;Adopt Vitest if you are still on Jest.&lt;/li&gt;
&lt;li&gt;Try Turbopack if you are on Next.js 15+.&lt;/li&gt;
&lt;li&gt;Add tsgo for editor and CI parallel type checks; keep tsc as the gate.&lt;/li&gt;
&lt;li&gt;Evaluate full Biome (linter + formatter) and full Oxlint replacement once your plugin audit allows.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The era of "JavaScript tooling written in JavaScript" is ending not because of fashion but because the math no longer favors it. The Rust toolchain is faster, more reliable, and increasingly easier to adopt. The good news is that for most application developers, this migration is not a rewrite. It is a series of small, low-risk swaps that quietly hand back hours of your week.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/rust-javascript-tooling-takeover-2026" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>javascript</category>
      <category>buildtools</category>
      <category>performance</category>
    </item>
    <item>
      <title>React 19 Server Actions in Production: A Year of Lessons From a 4M-User App</title>
      <dc:creator>Nilesh Kasar</dc:creator>
      <pubDate>Sat, 09 May 2026 07:16:57 +0000</pubDate>
      <link>https://dev.to/nilesh_kasar_2b00e7247dd5/react-19-server-actions-in-production-a-year-of-lessons-from-a-4m-user-app-4m1e</link>
      <guid>https://dev.to/nilesh_kasar_2b00e7247dd5/react-19-server-actions-in-production-a-year-of-lessons-from-a-4m-user-app-4m1e</guid>
      <description>&lt;h2&gt;
  
  
  The PR that deleted 12,000 lines of API routes
&lt;/h2&gt;

&lt;p&gt;In April 2025, I merged a PR that removed 12,387 lines of &lt;code&gt;/api&lt;/code&gt; route handlers, tRPC procedures, and &lt;code&gt;useMutation&lt;/code&gt; hooks. We replaced all of it with React 19 Server Actions on Next.js 15.4. Twelve months later, with 4 million monthly active users on the platform, I have a clear-eyed view of what that decision bought us and what it cost.&lt;/p&gt;

&lt;p&gt;Short version: I would do it again. With caveats.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Server Actions actually are
&lt;/h2&gt;

&lt;p&gt;Server Actions, finalized in React 19 (December 2024), let you call a server function directly from a client component as if it were local. You annotate a function with &lt;code&gt;"use server"&lt;/code&gt;, import it, and call it. React handles the network, serialization, and revalidation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;revalidatePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/profile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the whole API. It is genuinely simpler than tRPC, REST, or GraphQL for the 80% case.&lt;/p&gt;

&lt;h2&gt;
  
  
  What got better immediately
&lt;/h2&gt;

&lt;p&gt;A few wins showed up within the first sprint:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Form code shrank by 60%.&lt;/strong&gt; Pairing &lt;code&gt;useActionState&lt;/code&gt; with the native &lt;code&gt;&amp;lt;form action&amp;gt;&lt;/code&gt; attribute removed a tower of &lt;code&gt;onSubmit&lt;/code&gt;, &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;isPending&lt;/code&gt;, and &lt;code&gt;useMutation&lt;/code&gt; boilerplate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progressive enhancement came back.&lt;/strong&gt; Forms work without JavaScript. Our Lighthouse accessibility scores climbed from 89 to 97 across the funnel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type safety end-to-end without codegen.&lt;/strong&gt; Functions are imported, so TypeScript flows naturally. We deleted our entire OpenAPI generator pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smaller client bundles.&lt;/strong&gt; Removing tRPC client code shaved roughly 38KB gzipped from our home route. LCP on slow 4G dropped 240ms.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What bit us
&lt;/h2&gt;

&lt;p&gt;Now the honest part.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation is your problem
&lt;/h3&gt;

&lt;p&gt;Server Actions do nothing for validation. You will validate input yourself. We standardized on Zod 4 with a thin wrapper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without that wrapper, every action grew its own ad-hoc validation. After three of those, we wrote the wrapper. Do this on day one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error handling is awkward
&lt;/h3&gt;

&lt;p&gt;Throwing inside a Server Action surfaces as a generic error to the client. You lose structured error info. The community pattern, and the one we adopted, is to return a typed result object instead of throwing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EMAIL_TAKEN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combined with &lt;code&gt;useActionState&lt;/code&gt;, this gives clean per-field error rendering. But it means every action needs explicit return-type discipline.&lt;/p&gt;

&lt;h3&gt;
  
  
  The N+1 mutation trap
&lt;/h3&gt;

&lt;p&gt;Server Actions feel cheap to call. They are not. Each one is a POST to your origin with a full RSC payload roundtrip. Inline-editing 50 list items by firing 50 actions in parallel will hammer your server. We caught this in load testing at 3,200 RPS. The fix is the same as REST: batch on the client, expose a &lt;code&gt;bulkUpdate&lt;/code&gt; action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching and revalidation is the real frontier
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;revalidatePath&lt;/code&gt; and &lt;code&gt;revalidateTag&lt;/code&gt; are powerful and easy to misuse. Calling &lt;code&gt;revalidatePath("/")&lt;/code&gt; from a settings action invalidates the entire site. We wrote a lint rule that flags broad revalidations and forces tag-based invalidation for anything beyond a single route.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auth context inside actions
&lt;/h3&gt;

&lt;p&gt;A subtle gotcha: Server Actions run on the server, but they are reachable by anyone who can call the function. They are public endpoints. We saw one team ship an admin-only &lt;code&gt;deleteUser&lt;/code&gt; action without a permission check, assuming "it's only called from the admin page." It was not. A curious user found the action endpoint in the network tab and triggered it. Treat every Server Action as a public API endpoint and gate it accordingly. Our &lt;code&gt;createAction&lt;/code&gt; wrapper now requires an explicit auth policy argument; you cannot create an action without declaring who can call it.&lt;/p&gt;

&lt;h3&gt;
  
  
  File uploads and large payloads
&lt;/h3&gt;

&lt;p&gt;Server Actions serialize arguments as a multipart form payload, which makes &lt;code&gt;File&lt;/code&gt; and &lt;code&gt;FormData&lt;/code&gt; first-class citizens. That is genuinely nicer than JSON-encoded base64 in REST. But the platform default size limit is 1MB on Vercel, easy to bump but easy to forget. For multi-megabyte uploads we still use signed URLs to S3, then call a Server Action with just the resulting key. Server Actions are excellent for control-plane operations and awkward for raw data transfer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The patterns that survived
&lt;/h2&gt;

&lt;p&gt;After a year, these are the conventions that stuck:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;One action per file in &lt;code&gt;/app/_actions&lt;/code&gt;.&lt;/strong&gt; Discoverable, easy to grep.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typed return objects, never throws.&lt;/strong&gt; &lt;code&gt;{ok: true, data}&lt;/code&gt; or &lt;code&gt;{ok: false, error}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zod-validated inputs through a shared &lt;code&gt;createAction&lt;/code&gt; wrapper.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;useActionState&lt;/code&gt; for forms, plain async calls for non-form mutations.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tag-based revalidation only.&lt;/strong&gt; Path-based is too coarse at scale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimistic updates via &lt;code&gt;useOptimistic&lt;/code&gt;.&lt;/strong&gt; Worth the API surface; users feel the difference.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How Server Actions compare to alternatives
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;DX&lt;/th&gt;
&lt;th&gt;Type safety&lt;/th&gt;
&lt;th&gt;Bundle cost&lt;/th&gt;
&lt;th&gt;Fits well for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server Actions&lt;/td&gt;
&lt;td&gt;Highest&lt;/td&gt;
&lt;td&gt;Native&lt;/td&gt;
&lt;td&gt;Lowest&lt;/td&gt;
&lt;td&gt;Forms, mutations, internal apps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tRPC v11&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Native&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Complex client orchestration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REST + OpenAPI&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Via codegen&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Public APIs, mobile clients&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphQL&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Via codegen&lt;/td&gt;
&lt;td&gt;Highest&lt;/td&gt;
&lt;td&gt;Multi-consumer, federated graphs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If your client is only your own Next.js app, Server Actions win. The moment you need to serve a mobile app or a third party, you still want a real API. We kept tRPC for our public partner endpoints.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about React Query?
&lt;/h3&gt;

&lt;p&gt;The most common question we get from teams considering this migration: do Server Actions kill TanStack Query? Mostly no. Server Actions handle mutations beautifully. Queries — especially client-driven, polling, infinite-scroll, or cache-heavy queries — still benefit from TanStack Query on top. A pragmatic split is RSC + Server Actions for reads that align with the page lifecycle, and TanStack Query for genuinely client-driven async state. Our app uses both, deliberately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance numbers from production
&lt;/h2&gt;

&lt;p&gt;Comparing the same checkout flow before (tRPC + REST hybrid) and after (Server Actions on Next.js 15.4):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Median time-to-mutation-success: 412ms to 287ms&lt;/li&gt;
&lt;li&gt;p95 client JS for the route: 184KB to 121KB gzipped&lt;/li&gt;
&lt;li&gt;Form abandonment rate: 11.2% to 8.7%&lt;/li&gt;
&lt;li&gt;Cold-start function duration on Vercel: roughly equivalent, both around 90ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bundle and abandonment wins were larger than the latency win. That tracks: Server Actions remove client work, not server work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing strategy for Server Actions
&lt;/h2&gt;

&lt;p&gt;Testing was the question I had no good answer to for the first three months. The patterns that survived:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unit-test the action body, not the action.&lt;/strong&gt; Extract the core logic into a plain async function that the action calls. Test that function with normal mocks. The "use server" wrapper is glue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration tests via Playwright.&lt;/strong&gt; Real form submissions in a real browser. Slower, but catches the things unit tests cannot — serialization, auth, revalidation behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type-level tests with &lt;code&gt;expectTypeOf&lt;/code&gt;.&lt;/strong&gt; Server Actions are imported, so misuse shows up at compile time. Add typed contract tests where the return shape matters.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We deleted our entire MSW-based mock layer. With Server Actions there is no fetch to mock; the function is the function. The testing simplification alone justified the migration for our team.&lt;/p&gt;

&lt;h2&gt;
  
  
  A year of metrics worth sharing
&lt;/h2&gt;

&lt;p&gt;Beyond the per-flow numbers above, the broader engineering health metrics moved in the right direction over twelve months:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Average PR size in the web app: down 22%, because feature scaffolding takes less code.&lt;/li&gt;
&lt;li&gt;New-engineer time-to-first-merged-PR: from 9 days to 4 days. Less infrastructure to learn.&lt;/li&gt;
&lt;li&gt;Production incidents tagged "API" or "client/server contract": down 38%.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Correlation, not causation, but the direction is consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for you
&lt;/h2&gt;

&lt;p&gt;If you are starting a Next.js project in 2026, default to Server Actions for mutations. Do not build a parallel API layer until you have a second consumer.&lt;/p&gt;

&lt;p&gt;If you have an existing tRPC or REST codebase, do not migrate everything. Migrate one feature, get the patterns right, then expand. Our migration took six months and we still have a small &lt;code&gt;/api&lt;/code&gt; surface for webhooks, mobile, and partners.&lt;/p&gt;

&lt;p&gt;The biggest mindset shift: stop thinking about endpoints. Start thinking about server functions you can call from anywhere in your component tree. That is the actual upgrade React 19 delivered, and it changes how you design features more than any individual API improvement of the last five years.&lt;/p&gt;

&lt;p&gt;One closing observation: Server Actions have changed how new engineers on our team learn the codebase. They no longer have to mentally trace a click through a fetch hook, an API route handler, a controller, and a service. They follow an import. Onboarding documentation that used to need a sequence diagram now needs a paragraph. That alone is worth more than any of the performance numbers above. The best frameworks make the right thing the obvious thing, and for the first time in years, doing mutations the right way in React feels like the path of least resistance instead of the path of most ceremony.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://thestackstories.com/blog/react-19-server-actions-production-lessons" rel="noopener noreferrer"&gt;The Stack Stories&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>serveractions</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
