<?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: Mittal Technologies</title>
    <description>The latest articles on DEV Community by Mittal Technologies (@mittal_technologies).</description>
    <link>https://dev.to/mittal_technologies</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3888395%2F6dcf366c-b332-40ff-9b07-dddcf1445cdf.png</url>
      <title>DEV Community: Mittal Technologies</title>
      <link>https://dev.to/mittal_technologies</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mittal_technologies"/>
    <language>en</language>
    <item>
      <title>How AI Search and LLMs Are Changing Front-End Development</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Mon, 22 Jun 2026 11:55:27 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/how-ai-search-and-llms-are-changing-front-end-development-402g</link>
      <guid>https://dev.to/mittal_technologies/how-ai-search-and-llms-are-changing-front-end-development-402g</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2mgc4y0zk54bgfhcuota.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2mgc4y0zk54bgfhcuota.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Spent most of last week debugging a hydration mismatch that turned out to be invisible to humans but apparently a nightmare for the LLM crawler trying to parse our client's product pages. How AI search and LLMs are changing front-end development isn't some abstract industry trend piece for me right now, it's literally what I was staring at in devtools at 11pm on a Tuesday. So, this is less theory, more "here's what's actually breaking and what's actually working."&lt;/p&gt;

&lt;p&gt;The short version: front-end decisions that used to be purely UX or performance concerns now have a third stakeholder nobody asked for, language models trying to extract structured meaning from your rendered DOM. And a lot of patterns we've leaned on for years (heavy client-side rendering, infinite scroll, content gated behind interaction) are quietly working against that goal even when they work fine for human users.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Client-side rendering is becoming a liability, not just a tradeoff&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We've all had the SSR-vs-CSR debate a hundred times, usually framed around initial load performance and SEO crawlability. That debate got sharper recently. A lot of LLM-based crawlers and AI Overview-style systems either don't execute JavaScript reliably, or they do it inconsistently enough that content rendered purely client-side gets missed, truncated, or misattributed entirely.&lt;/p&gt;

&lt;p&gt;If you're shipping a heavy SPA for a marketing or content-driven site in 2026, you're basically betting that every crawler in your traffic mix executes JS perfectly and waits long enough to do it. That's not a safe bet anymore. Server-side rendering or static generation for anything content-critical isn't optional polish at this point, it's closer to a baseline requirement if visibility matters at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Semantic HTML matters more than it have in years&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Funny enough, a skill a lot of us treated as a "nice to have, accessibility nerds care about this" thing is suddenly load-bearing again. Proper use of &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h1&amp;gt;-&amp;lt;h6&amp;gt;&lt;/code&gt; hierarchy, &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;address&amp;gt;&lt;/code&gt;, these aren't just accessibility wins anymore, they're literally how extraction models figure out what's the main content versus what's chrome, nav, or boilerplate.&lt;/p&gt;

&lt;p&gt;I've started treating semantic structure as close to a contract with the parsing layer now. Div soup with everything styled via utility classes and zero semantic meaning still renders fine visually, but it's handing the crawler a pile of unlabeled boxes and hoping it guesses right. It guesses wrong more often than you'd think.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Schema markup stopped being optional SEO homework&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Structured data used to feel like a checkbox SEO consultants asked for and devs grudgingly implemented. Now it's doing real work feeding AI systems clean, unambiguous facts they don't have to infer from messy markup. FAQ schema, Product schema, Article schema with clear author and date fields, these give extraction models a shortcut straight to ground truth instead of forcing them to parse rendered text and hope for accuracy.&lt;/p&gt;

&lt;p&gt;If your build pipeline doesn't already validate structured data automatically (we use a simple schema validation step in CI now, catches a surprising number of regressions), it's worth adding. Schema silently breaking after a component refactor is an easy thing to miss until your visibility quietly drops for reasons nobody can immediately explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Performance budgets need to account for a crawler's patience, not just a user's&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We already optimize for Core Web Vitals because users bounce on slow pages. Turns out a lot of crawling and extraction systems have their own patience thresholds too, and they're not always generous. Heavy bundles, late-loading critical content, render-blocking scripts delaying meaningful paint, all of this risks the crawler giving up or grabbing an incomplete snapshot of the page before everything's actually rendered.&lt;/p&gt;

&lt;p&gt;Lazy loading is still good practice for images below the fold, obviously, but I'd push back on lazy-loading anything that's core textual content just to shave milliseconds off initial paint. That tradeoff used to be purely about user experience. Now it's also a visibility tradeoff, and it's not always worth it depending on what that content actually is.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Component architecture and content separation&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One pattern that's paid off for us: keeping content genuinely separate from presentational logic wherever possible, rather than interpolating critical text deep inside conditional rendering trees that only resolve after multiple client-side states settle. Content that depends on three nested loading states before it appears is fragile for crawlers in the same way it's fragile for users on a bad connection. Treat them as overlapping problems, because increasingly, they are.&lt;/p&gt;

&lt;p&gt;This is also where design and dev need to actually talk to each other early instead of design handing off a Figma file and disappearing. A few projects we've inherited recently came from a &lt;a href="https://mittaltechnologies.com/service/development" rel="noopener noreferrer"&gt;website designing company in Ludhiana&lt;/a&gt; that clearly hadn't accounted for how their layout decisions would translate into rendering order once a frontend team actually built it out, and we ended up restructuring component hierarchy just to fix extraction issues that design alone created upstream.&lt;/p&gt;

&lt;p&gt;On the UX side specifically, this is partly why &lt;a href="https://mittaltechnologies.com/service/development" rel="noopener noreferrer"&gt;UI UX designing in Ludhiana&lt;/a&gt; work needs to bake in "what does this look like with JS disabled or partially loaded" as a real review step now, not an edge case nobody bothers checking until something breaks in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Hydration mismatches are a bigger deal than they used to be&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Back to that bug I mentioned at the top, because it's a good concrete example of the kind of thing that's now silently worth more than just a console warning. Our mismatch was caused by a date formatted differently on the server versus the client due to a time zone default difference, nothing exotic. Visually, nobody would have noticed, the text just flickered for a frame and corrected itself. But when we checked how that specific page was being represented in an AI summary, the extracted date was wrong, pulled from whichever render pass happened to win the race on that particular crawl.&lt;/p&gt;

&lt;p&gt;That's the kind of bug that used to live purely in the "annoying but cosmetic" bucket. Now it's a content accuracy bug too, just one layer removed from where most teams would think to look for it. Worth adding hydration consistency checks to your test suite if you haven't already, especially for anything date, price, or stock-status related, since those are exactly the fields most likely to get extracted and quoted directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Streaming and partial hydration need a second look&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A lot of teams reached for streaming SSR and partial hydration patterns purely for perceived performance wins, and they're still good for that. But it's worth specifically testing what a crawler sees if it grabs a snapshot mid-stream, before everything's settled. If your critical content streams last while skeleton placeholders render first, you might be performing great for Core Web Vitals while still handing an incomplete page to anything that doesn't wait around for the full stream to resolve.&lt;/p&gt;

&lt;p&gt;We started running a simple check as part of our deploy process, fetching each key route with JS disabled and skimming the raw HTML for the actual content fields we care about being extractable. Cheap to set up, and it's caught a handful of regressions other monitoring missed entirely, because Lighthouse and most performance tooling don't actually check for this specific failure mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Where this leaves front-end teams practically&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;None of this means throwing out modern frameworks or going back to static HTML for everything, that's not realistic and honestly not necessary. It means being more deliberate about what's rendered server-side versus client-side, taking semantic markup seriously again, keeping structured data validated and current, and treating crawler patience as a real constraint alongside user patience. A lot of teams I talk to are quietly retrofitting these practices into existing codebases rather than rebuilding from scratch, and that's a perfectly reasonable path if a full rewrite isn't on the table.&lt;/p&gt;

&lt;p&gt;If you're working with an external team on a content-heavy or e-commerce front end right now, it's worth explicitly asking how they're handling AI crawler accessibility, because a surprising number of agencies and a &lt;a href="https://mittaltechnologies.com/service/development" rel="noopener noreferrer"&gt;website development company Ludhiana&lt;/a&gt;, businesses haven't fully updated their default stack assumptions yet. The ones that have are increasingly easy to spot by how clean their rendered output looks with JS disabled.&lt;/p&gt;

&lt;p&gt;For teams evaluating partners for this kind of work, solid &lt;a href="https://mittaltechnologies.com/service/development" rel="noopener noreferrer"&gt;web development services in Ludhiana&lt;/a&gt; now typically include SSR/SSG defaults for content pages, automated schema validation, and semantic-first component design as standard practice rather than an upsell, which is honestly where the whole industry needs to land.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>frontend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The New Cybersecurity Challenge: Managing AI Tools Inside Organizations</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Fri, 19 Jun 2026 09:27:16 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/the-new-cybersecurity-challenge-managing-ai-tools-inside-organizations-45c9</link>
      <guid>https://dev.to/mittal_technologies/the-new-cybersecurity-challenge-managing-ai-tools-inside-organizations-45c9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa6etvkinr438x716zk4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa6etvkinr438x716zk4h.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Let's be real for a second, every team I talk to right now is using some combination of AI tools nobody officially approved. ChatGPT for drafting emails, an AI code assistant plugged straight into someone's IDE, a random Chrome extension that "summarizes" meeting notes by quietly reading everything on the page. None of this got a security review. Most of it got adopted because it genuinely makes work faster, and honestly, who's going to say no to that in 2026?&lt;/p&gt;

&lt;p&gt;But here's the uncomfortable part nobody wants to slow down and talk about. Every one of those tools is a new data pathway out of your organization, and most companies have zero visibility into what's actually leaving through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Long Tail Reality: Shadow AI Usage Is Already Inside Your Org Right Now&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There's a term for this now, shadow AI, basically the AI equivalent of shadow IT from a decade ago. Employees pasting client data into a chatbot to "summarize this faster." Developers feeding proprietary code into an AI assistant for a quick fix, without thinking about where that snippet actually goes or how it might be used to train future models. Marketing teams uploading customer lists into some AI tool that promised better targeting.&lt;/p&gt;

&lt;p&gt;None of these people are being malicious. They're being efficient. That's exactly what makes this hard to manage, you can't just tell people, "stop using AI tools," that ship has sailed and frankly trying to ban it outright usually just pushes usage further underground, where you have even less visibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Traditional Security Policies Don't Cover This&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Most existing security policies were written with a pretty narrow idea of "data leaving the company," think email attachments, USB drives, maybe cloud storage links. AI tools don't fit cleanly into any of those categories. You're not sending a file, you're typing text into a box, and that box might be logging, storing, or even training on what you just typed, depending on the tool's data policy (which, let's be honest, almost nobody reads in full).&lt;/p&gt;

&lt;p&gt;This is a genuinely new category of risk, and it needs its own conversation, not just an addendum tacked onto an old data handling policy from five years ago. A team offering real &lt;a href="https://mittaltechnologies.com/service/cybersecurity" rel="noopener noreferrer"&gt;cybersecurity services in Ludhiana&lt;/a&gt; in 2026 should already be having this exact conversation with clients, because it's becoming one of the most common blind spots in otherwise decent security setups.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Specific Risks Worth Actually Worrying About&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A few patterns keep showing up. Developers pasting API keys or credentials into AI chat windows while debugging, completely forgetting that text doesn't just disappear once they hit enter. Customer support staff copying entire support tickets, sometimes containing personal details, into an AI tool to "write a better response." Internal documents, sometimes containing strategy or financial details, getting uploaded for quick summarization.&lt;/p&gt;

&lt;p&gt;Browser extensions are a sneaky one too. Plenty of "AI-powered" extensions request broad page access, meaning they can technically read anything open in that browser tab, including internal dashboards or admin panels. Most employees install these without a second thought because the install button is right there and the value proposition sounds harmless.&lt;/p&gt;

&lt;p&gt;If your organization handles any kind of sensitive client information, this is exactly the gap that proper &lt;a href="https://mittaltechnologies.com/service/cybersecurity" rel="noopener noreferrer"&gt;data protection services Ludhiana&lt;/a&gt; need to start covering, not as an afterthought, but as a core part of how data policy gets written going forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Actually Helps, Practically Speaking&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Outright bans rarely work, like I mentioned. What tends to work better is clear, specific guidance, not a thirty-page policy document nobody reads, but a short, practical list. Don't paste credentials or API keys into any AI tool, period. Don't upload documents containing customer PII without checking the tool's data retention policy first. Use enterprise versions of AI tools where data isn't used for training, rather than free consumer versions, whenever the tool is being used for anything work related.&lt;/p&gt;

&lt;p&gt;Logging and visibility matter too. A lot of organizations genuinely don't know which AI tools are even in use across departments. Just running an internal audit, asking teams directly what they're using, surfaces more than people expect, usually in a slightly alarming way the first time it's done.&lt;/p&gt;

&lt;p&gt;This is honestly becoming standard practice for any decent &lt;a href="https://mittaltechnologies.com/service/cybersecurity" rel="noopener noreferrer"&gt;cybersecurity company in Ludhiana&lt;/a&gt; working with growing businesses, building the AI usage conversation into a broader security review instead of treating it as some separate, futuristic concern. It's not futuristic anymore, it's just Tuesday.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Where This Is Heading&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;AI tooling inside organizations isn't slowing down, if anything it's accelerating, and the gap between adoption speed and policy speed is only going to widen unless someone deliberately closes it. The businesses that get ahead of this aren't the ones banning AI outright, they're the ones building sensible, specific guardrails early, before a careless paste into a chat window turns into a much bigger headache than anyone expected from something that felt this routine.&lt;/p&gt;

&lt;p&gt;If your team's web infrastructure was built a while back, this is also a good moment to loop in your website development company partner to review how AI tools might be interacting with your actual production environment, not just employee laptops. The risk surface is bigger than most teams initially assume.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>cybersecurity</category>
      <category>webdev</category>
      <category>devto</category>
    </item>
    <item>
      <title>Search Engines Are Becoming Answer Engines: Here's What Developers Need to Change</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Thu, 18 Jun 2026 11:48:33 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/search-engines-are-becoming-answer-engines-heres-what-developers-need-to-change-3ph4</link>
      <guid>https://dev.to/mittal_technologies/search-engines-are-becoming-answer-engines-heres-what-developers-need-to-change-3ph4</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkemi279gshttclp5cqnc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkemi279gshttclp5cqnc.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
I've been writing code for client websites for a while now, and somewhere in the last year or so, a question started creeping into nearly every project kickoff call that never used to come up: "Will this work with AI search?" My first reaction, honestly, was mild annoyance, another acronym, another thing to bolt onto an already long requirements list. But after digging into how AI Overviews, Perplexity, and ChatGPT's browsing actually extract and cite information from websites, I realized this isn't a marketing buzzword problem. It's an engineering problem, and a fair number of devs I've talked to haven't fully clocked that yet.&lt;/p&gt;

&lt;p&gt;Search engines used to send people to your page so they could find an answer themselves. Increasingly, they're extracting the answer directly and serving it without a click ever happening. That shift changes what "good" technical SEO and site architecture actually look like under the hood, and it's worth us as developers paying attention before our clients or product managers come asking why traffic dropped and we have no answer ready.&lt;/p&gt;

&lt;p&gt;What's interesting is how little of this actually requires new tooling. It's mostly about taking habits we already knew were "best practice" and treating them as genuinely non-negotiable instead of nice-to-haves we'd skip when a deadline got tight. The pressure used to come from Lighthouse scores and accessibility audits. Now there's a second, slightly less forgiving judge in the room, a crawler that needs to extract a clean answer in a fraction of a second, with no patience for a messy DOM.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Semantic HTML Isn't Optional Anymore, It's Load-Bearing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I'll be the first to admit I've been guilty of div-soup in past projects, wrapping everything in generic containers and styling my way to something that looks right, while the underlying markup tells a crawler basically nothing about structure or meaning. That habit is becoming actively expensive now. AI crawlers, much like accessibility tools, lean heavily on proper semantic structure, &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;, properly nested headings, &lt;code&gt;&amp;lt;dl&amp;gt;&lt;/code&gt; for actual definition pairs instead of three stacked divs pretending to be one, to figure out what a page is actually about and which part of it directly answers a given question.&lt;/p&gt;

&lt;p&gt;If your heading hierarchy is a mess, skipping from h1 straight to h4 because it "looked right" in the design, you're not just creating an accessibility problem anymore. You're making it measurably harder for an AI model to extract a clean, citable answer from your content, which means your client's actual answer to a real question never gets surfaced, even if the content itself is genuinely good.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Structured Data Stopped Being a Nice-to-Have a While Ago&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I used to treat schema markup as something you add at the end of a project if there's time left in the sprint, mostly for the rich snippet star ratings. That's a mistake now. FAQ schema, HowTo schema, Article schema with clear &lt;code&gt;author&lt;/code&gt; and &lt;code&gt;datePublished&lt;/code&gt; properties, these aren't decoration, they're explicit machine-readable signals that tell an AI exactly what type of content it's looking at and how confident it can be in citing it.&lt;/p&gt;

&lt;p&gt;I started baking schema generation into the initial build phase instead of treating it as an afterthought, and honestly, it barely added any real development time once it's part of the standard component templates. If you're advising clients or stakeholders on this, this is genuinely one of the highest-leverage, lowest-effort changes a dev team can make, and it overlaps heavily with the kind of foundational work that solid &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;SEO services in Ludhiana&lt;/a&gt; teams have been pushing for years, just with a slightly different end consumer now, a model instead of purely a search algorithm.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Performance Still Matters, Maybe More Than Before&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here's something I didn't expect going into this, page speed and render behavior matter just as much for AI crawlability as they ever did for traditional SEO, possibly more, because a lot of these crawlers operate on tighter time and resource budgets than Googlebot historically has. A heavy client-side-rendered React app that needs a full hydration cycle before any meaningful content appears in the DOM is genuinely risky here. If the crawler grabs a snapshot before your content has rendered, it sees nothing. Empty &lt;code&gt;&amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;. Functionally invisible.&lt;br&gt;
Server-side rendering or static generation for content-heavy pages isn't just a performance best practice at this point, it's closer to a prerequisite if you want a page to have any shot at being parsed and cited reliably. I've started pushing back harder in project planning when a client wants a heavily client-rendered marketing site purely for aesthetic flexibility, because the tradeoff is becoming clearer the more data I look at.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;llms.txt and the Weird New Frontier of "Crawler Etiquette"&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There's a newer convention floating around, llms.txt, sitting alongside the classic robots.txt, meant to give AI crawlers explicit guidance on what content is fair game to reference and what isn't. It's not universally adopted or even fully standardized yet, and I wouldn't bet a project deadline on every AI crawler respecting it consistently. But it's cheap to implement and costs nothing to add as a forward-looking signal, so I've started including a basic version in new builds anyway. Worst case, it does nothing yet. Best case, it quietly becomes load-bearing infrastructure in two years and we're glad we didn't have to retrofit it.&lt;/p&gt;

&lt;p&gt;It's a markdown file, sitting at the root of the domain, basically describing in plain language what the site is and pointing to the pages worth paying attention to. Takes maybe twenty minutes to draft properly for most small-to-mid-sized sites. I've started treating it the same way I treat a basic sitemap.xml, not something I expect to move mountains on its own, but a small, low-cost signal that costs almost nothing to add and might genuinely matter down the line.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Information Architecture Is a Dev Concern Too, Not Just a Design One&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I used to think of sitemap structure and navigation depth as primarily a design or content problem, something to leave to whoever was handling UX. I don't think that anymore. How deep content sits in your folder structure, how your internal linking connects related pages, whether your URL patterns are predictable or a mess of query parameters, these all directly affect how easily a crawler can map your site's structure and figure out which pages deserve more weight. This is genuinely where close collaboration with whoever's handling &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;UI UX designing in Ludhiana&lt;/a&gt; for a project pays off, because a clean information architecture benefits the crawler and the human visitor at the same time, for basically the same underlying reasons. It's one of those rare cases where doing right by the user and doing right by the machine point in the exact same direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What I'm Actually Telling Clients and Teams Now&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The practical shift isn't dramatic, which is honestly a relief. It's mostly about discipline, clean semantic markup instead of div-soup, schema baked into the build process from day one instead of bolted on later, server-rendered content for anything meant to actually answer a question, and reasonable crawler signals sitting alongside the usual robots.txt. None of this requires reinventing how we build sites. It requires taking technical SEO seriously again, the way we maybe got a little lazy about once frameworks made everything feel "fast enough" for users even when it wasn't structured well enough for machines trying to parse it.&lt;/p&gt;

&lt;p&gt;If you're working with a &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;website development company Ludhiana&lt;/a&gt; clients expect this kind of forward-thinking technical foundation, this stuff needs to be part of the conversation from the architecture phase, not patched in after launch when someone notices traffic dipping and asks why. Retrofitting semantic structure into a sprawling legacy codebase is a genuinely painful, multi-sprint slog. Building it from day one costs almost nothing extra, and frankly, it's the same advice I'd give to any &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;website designing company in Ludhiana&lt;/a&gt;, handing off a build to a client without flagging this upfront.&lt;/p&gt;

&lt;p&gt;I don't think we're heading toward some dramatic reinvention of how the web gets built. I think we're heading toward a world where the corners we've been cutting for years, sloppy markup, lazy schema, render-blocking JS bloat, finally have a visible, measurable cost attached to them again. Which, honestly, might just be a good thing for the web in general, AI search aside.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>development</category>
      <category>seo</category>
    </item>
    <item>
      <title>I Looked at the Source Code of 20 Small Business Sites in India. Same Mistake, Every Single Time</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Wed, 17 Jun 2026 11:17:43 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/i-looked-at-the-source-code-of-20-small-business-sites-in-india-same-mistake-every-single-time-28df</link>
      <guid>https://dev.to/mittal_technologies/i-looked-at-the-source-code-of-20-small-business-sites-in-india-same-mistake-every-single-time-28df</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fev7fsge8q1iei8noaisa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fev7fsge8q1iei8noaisa.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
Okay so this started as a mildly procrastinatory rabbit hole and turned into something I think is actually worth writing up properly. I was bored one evening, opened dev tools on a local bakery's site I'd ordered from, and just... kept going. Twenty sites later, mostly small businesses around Punjab, salons, clinics, a couple of consultancies, a furniture shop, I noticed the exact same root issue showing up in roughly 17 out of 20 of them. Not a design issue. A code issue. And it's one that's genuinely easy to fix once you know to look for it, which is what bugs me most about it.&lt;/p&gt;

&lt;p&gt;The pattern: unoptimized, uncompressed images being served at full resolution regardless of viewport, with zero lazy loading, and in a few cases, the same hero image being loaded twice because of a CSS background-image declaration stacked on top of an actual &lt;a href="" class="article-body-image-wrapper"&gt;&lt;img&gt;&lt;/a&gt; tag doing the same job. One site was loading a 4.2MB PNG as a hero banner. On mobile. Over what was, in my test, a throttled 4G connection. That's not a minor inefficiency, that's borderline hostile to anyone not on fiber.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Why This Keeps Happening&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;My theory, having poked around enough of these codebases, is that most of these sites were built fast, by freelancers or small agencies working off a fixed quote, optimizing for "client approves design in the demo" rather than "site performs well in production six months later." Nobody's malicious here, I want to be clear. It's just that image optimization is the kind of thing that's invisible in a quick screen-share demo and very visible in a Lighthouse audit, and clients rarely ask for the latter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- what I found, repeatedly --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background-image: url('hero-banner-full-res.png')"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"hero-banner-full-res.png"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two requests for the same asset, no &lt;code&gt;srcset&lt;/code&gt;, no responsive sizing, empty alt text on top of it which is its own accessibility and SEO problem. I'm not picking on any specific dev here, this exact pattern showed up across sites clearly built by different people, which tells me it's systemic rather than one bad freelancer's habit.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Fix Isn't Hard, Which Is the Annoying Part&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is genuinely a few hours of work, not a rebuild. Proper &lt;code&gt;srcset&lt;/code&gt; with multiple resolutions, WebP with a fallback, lazy loading via the native &lt;code&gt;loading="lazy"&lt;/code&gt; attribute which has decent support now and doesn't even require a JS library for the basic case anymore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; 
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"hero-banner-800.webp"&lt;/span&gt; 
  &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"hero-banner-400.webp 400w, hero-banner-800.webp 800w, hero-banner-1200.webp 1200w"&lt;/span&gt;
  &lt;span class="na"&gt;sizes=&lt;/span&gt;&lt;span class="s"&gt;"(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"&lt;/span&gt;
  &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Custom furniture showroom interior in Ludhiana"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That one change alone, across the sites where I actually got to test before/after on a real deploy, dropped Largest Contentful Paint by anywhere from 1.5 to nearly 4 seconds depending on how bad the original asset was. For context, Google's own Core Web Vitals guidance treats anything over 2.5 seconds LCP as needing improvement, and several of these sites were sitting at 6+ seconds. That's not a borderline case. That's a site actively working against itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Second Pattern: No Structured Data, Anywhere&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This one's less about performance and more about missed opportunity. Of the 20 sites, exactly 3 had any JSON-LD structured data at all. Not "good" structured data, just any. No &lt;code&gt;LocalBusiness&lt;/code&gt;, no &lt;code&gt;Organization&lt;/code&gt;, nothing telling Google explicitly what kind of business this is, where it's located, what hours it operates. Which means these businesses are relying entirely on Google's text-parsing inference to figure out what they are, instead of just telling it directly in a format it explicitly prefers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"LocalBusiness"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[Business Name]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PostalAddress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"addressLocality"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ludhiana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"addressRegion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Punjab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"addressCountry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IN"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"openingHoursSpecification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OpeningHoursSpecification"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dayOfWeek"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Monday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Tuesday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Wednesday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Thursday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Friday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Saturday"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"opens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"09:30"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"closes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18:30"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't complicated to add and yet almost nobody bothers, probably because it produces no visible change in the browser, so it's easy to deprioritize when you're racing toward a launch deadline. It's the kind of thing that pays off slowly and invisibly, which makes it exactly the kind of thing that gets skipped under time pressure.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why I'm Writing This Up Here Specifically&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I think there's a slightly underappreciated gap between how dev-focused communities talk about performance, Lighthouse scores, Core Web Vitals, bundle sizes, all the stuff we obsess over for our own side projects and how that knowledge actually trickles down to the small business sites that make up a huge chunk of the actual web. Plenty of small business owners hire whoever's cheapest or most available locally, get a site that looks fine in a demo, and have genuinely no way of knowing whether the underlying code is solid or held together with duct tape, because they're not developers and shouldn't be expected to check.&lt;/p&gt;

&lt;p&gt;If you're a dev who occasionally takes on small business client work, or you know someone who does, this is worth treating as a checklist rather than an afterthought: image optimization, basic structured data, an actual mobile-first responsive approach rather than a shrunk desktop layout, and a quick Lighthouse pass before calling anything "done." None of this is advanced. It's just consistently skipped, and the businesses paying for these sites have no way of catching it themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Third Pattern: Nobody's Actually Touched These Sites Post-Launch&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This one's less a code smell and more something you can infer from git-blame-style archaeology, except most of these sites don't even have proper version control, just FTP'd files sitting on a server somewhere. Looking at last-modified timestamps on assets and reading through commented-out code that clearly belonged to an earlier iteration of the design, it's pretty obvious most of these sites got built once and then never touched again. No dependency updates, no revisiting the Lighthouse score after launch, nothing.&lt;/p&gt;

&lt;p&gt;This tracks with something I've heard repeated by people doing actual &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;SEO services in Ludhiana&lt;/a&gt; work seriously: a huge percentage of small business sites in this market get treated as one-time deliverables rather than living assets that need periodic technical attention. Which makes sense from a freelancer's incentive structure, you get paid once for the build, there's no ongoing retainer pulling you back to revisit performance regressions or accumulating cruft. But it does mean a meaningful chunk of small business sites are quietly decaying, performance-wise, just from accumulated neglect rather than any single dramatic failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why I Think This Is an Industry-Wide Blind Spot, Not Just a Local One&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I want to be careful not to make this sound like it's uniquely a Punjab thing or an India thing, because I genuinely don't think it is. I think this is just what happens anywhere small business web development gets commoditized into fixed-price, fast-turnaround projects without a feedback loop built in. The closest analogy I can think of is contractors who'll build you a house that looks great on handover day but cut corners on the wiring because nobody's going to open the walls and check for another decade.&lt;/p&gt;

&lt;p&gt;That said, this is exactly the gap that good &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;website designing company in Ludhiana&lt;/a&gt; outfits who actually care about retention and reputation tend to close, because repeat business and referrals depend on the site still working well a year or two later, not just looking polished at handover. The economics shift when a business depends on long-term client relationships instead of one-off project fees, and you can usually tell the difference just by reading the markup, honestly, without ever meeting the team that built it.&lt;/p&gt;

&lt;p&gt;For what it's worth, the better-performing sites in my sample of 20, the 3 with structured data, faster load times, and the works, tended to be the ones built by teams that clearly treated this as ongoing technical work rather than a one-time design delivery. A few were built by a Ludhiana-based outfit, &lt;strong&gt;Mittal Technologies&lt;/strong&gt;, and the difference in how those sites were structured under the hood versus the rest of the sample was honestly pretty noticeable once you started actually reading the markup instead of just looking at the rendered page.&lt;/p&gt;

&lt;p&gt;If you're building for small business clients, or you're a small business owner trying to evaluate whether your own dev did right by you, treat the stuff that's invisible in a demo with at least as much seriousness as the stuff that gets applause in one. The applause fades. The Lighthouse score doesn't lie to anyone six months later.&lt;/p&gt;

</description>
      <category>git</category>
      <category>coding</category>
      <category>design</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Building Features, Start Building Habits: A Developer's Honest Take on Retention-First Architecture</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Tue, 16 Jun 2026 11:02:29 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/stop-building-features-start-building-habits-a-developers-honest-take-on-retention-first-4ilg</link>
      <guid>https://dev.to/mittal_technologies/stop-building-features-start-building-habits-a-developers-honest-take-on-retention-first-4ilg</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvzvm1ks18zw7i2aqtpzm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvzvm1ks18zw7i2aqtpzm.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Here's a thing I've noticed across a lot of mobile projects: the conversation about user retention happens after the app is built. In post-mortems. In "why are Day-30 numbers terrible" Slack threads. In the panicked pivot meetings six months after launch.&lt;/p&gt;

&lt;p&gt;And every time, the same root cause: retention wasn't designed for. It was hoped for.&lt;/p&gt;

&lt;p&gt;I want to make the case that retention is an architectural decision, not a marketing one. And that if you're not thinking about it before you write your first model, you're going to end up in the same post-mortem conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Habit Loop Problem&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;BJ Fogg's work on tiny habits and Nir Eyal's Hook Model have been cited so many times that most product people can recite them in their sleep. Cue, routine, reward. Trigger, action, variable reward, investment. Everyone knows the theory. Very few apps actually architect for it.&lt;/p&gt;

&lt;p&gt;What does that mean at the code level? A few things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Variable reward requires unpredictability.&lt;/strong&gt; If your app delivers exactly the same experience every time, same content, same layout, same interaction, users don't develop the slightly compulsive return behavior that characterizes truly sticky apps. The model for this isn't random content (which is chaotic), it's fresh content on a reliable schedule. Your data layer needs to support surfacing genuinely new things without requiring a full content refresh every session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Investment compounds with good data models.&lt;/strong&gt; In the Hook Model, "investment" refers to the user putting something of value into the app, customization, data, history, connections, that makes it more valuable to them over time. This isn't magic. It's database design. Are you storing user preferences in a way that meaningfully improves future sessions? Is personalization genuinely dynamic or just a username in the header?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The trigger layer needs to be event-driven, not scheduled.&lt;/strong&gt; Push notifications sent on a timer ("open our app!") are how you get uninstalled. Push notifications triggered by actual meaningful events in your system ("someone replied to your comment," "your order changed status," "you're on a 7-day streak") are how you get re-engagement. This requires your backend to emit events that the notification layer can respond to, not a cron job.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What Retention-First Architecture Actually Looks Like&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let me get specific, because "design for retention" is the kind of advice that sounds useful and isn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design your core loop first, then build features around it.&lt;/strong&gt; The core loop is the sequence of actions that your most retained users take repeatedly. For a task manager, it might be: add task → complete task → feel good → add more tasks. Every feature decision should be evaluated against whether it strengthens or distracts from this loop.&lt;/p&gt;

&lt;p&gt;This means some features that seem obviously useful get cut at the planning stage. Not because they're bad ideas, but because they add complexity without strengthening the loop. The discipline of maintaining a tight core loop is harder than it sounds when stakeholders keep adding "just one more thing."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instrument your state machine.&lt;/strong&gt; Every significant UI state a user can be in, onboarding, active, inactive, churned, re-engaged, should be tracked as a formal state with defined transitions. Not in analytics (though analytics too), but in your data model. When you know that users who hit a specific state at Day 3 have a 70% chance of churning, you can build interventions that fire at that exact point. You can't do this if you're treating user engagement as an analytics question rather than an architectural one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build the empty states with as much care as the full states.&lt;/strong&gt; New users have no data. No history, no connections, no content. Most apps treat this as a temporary condition to be endured. The apps that retain well treat the empty state as a critical product moment, the time when you have to demonstrate value without relying on the user's own content to do it. What do you show a new user in your social feed before they follow anyone? What does a new user's dashboard show before they've logged any data? These aren't edge cases, they're the first impression for every new user, forever.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Metrics That Actually Tell You If You're Getting This Right&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Day-1, Day-7, Day-30 retention. Everyone tracks these. They're necessary but not sufficient.&lt;/p&gt;

&lt;p&gt;The metric I find more revealing is &lt;strong&gt;time-to-core-action&lt;/strong&gt;, how long after install does a new user complete the primary action your app is built for? For a habit tracker, that's logging their first habit. For a social app, that's their first meaningful interaction. For a productivity tool, that's creating their first item. The shorter this is, the better your long-term retention tends to be.&lt;/p&gt;

&lt;p&gt;The other one worth tracking: &lt;strong&gt;session-initiated-by-notification rate.&lt;/strong&gt; What percentage of sessions start because a user proactively opened your app vs. because a push notification or other trigger brought them back? If the number skews heavily toward triggered sessions, you're relying on reminders rather than genuine habit formation. If users are opening your app without being reminded, you've built something that's become part of their routine. That's the goal.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;A Note on the Tools Side&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;React Native with Zustand + React Query&lt;/strong&gt; is a fairly clean setup for retention-oriented state management, Zustand for local UI state, React Query for server state with sensible caching that makes return sessions feel fast. &lt;strong&gt;Flutter's&lt;/strong&gt; provider pattern works similarly if you're in that ecosystem.&lt;/p&gt;

&lt;p&gt;For the event-driven notification layer, &lt;strong&gt;OneSignal&lt;/strong&gt; still has the best combination of capability and reasonable pricing at indie/small team scale. If you're building something with complex notification logic, it's worth investing in the journey builder rather than just the broadcast tool.&lt;/p&gt;

&lt;p&gt;For instrumentation, &lt;strong&gt;Mixpanel&lt;/strong&gt; with properly named events (noun_verb format, please, &lt;code&gt;habit_created&lt;/code&gt; not &lt;code&gt;click_button_3&lt;/code&gt;) gives you the funnel visibility to actually see where your retention loop is breaking down.&lt;/p&gt;

&lt;p&gt;The backlink goes here naturally: if you want a team that thinks about these architectural decisions before the first sprint, rather than after the first post-mortem, &lt;a href="https://mittaltechnologies.com/service/mobiledevelopment" rel="noopener noreferrer"&gt;mobile development done properly&lt;/a&gt; starts with these conversations.&lt;/p&gt;

&lt;p&gt;Drop your thoughts below. Curious what core loop patterns others are designing around, especially in non-consumer contexts like B2B tools and field service apps where habit formation is a harder problem.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>mobile</category>
      <category>ux</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Micro-Frontend Architecture Is Solving the Wrong Problem for Most Teams</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Mon, 15 Jun 2026 11:57:01 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/micro-frontend-architecture-is-solving-the-wrong-problem-for-most-teams-bi4</link>
      <guid>https://dev.to/mittal_technologies/micro-frontend-architecture-is-solving-the-wrong-problem-for-most-teams-bi4</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwld6tnqug89zs3itmytw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwld6tnqug89zs3itmytw.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Let me say something that might be slightly unpopular in certain frontend engineering circles: micro-frontends are genuinely useful, and they're also being adopted by teams that have absolutely no business adopting them.&lt;/p&gt;

&lt;p&gt;I've seen this pattern enough times that it feels worth writing about. A team of eight or twelve developers decides their frontend is getting unwieldy. Someone brings up micro-frontends. It gets discussed, it sounds compelling, and six months later they're dealing with a fragmented codebase, inconsistent UI, three different versions of their design system running simultaneously, and a user experience that's visibly seamed at the boundaries between different team-owned sections.&lt;/p&gt;

&lt;p&gt;And the users? They just know something feels off. They can't articulate it. But the transitions are slightly different in different parts of the app. The loading behavior is inconsistent. A font is somehow slightly different in one section. The whole thing feels like it was built by several different companies that never talked to each other. Because, in a sense, it was.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The actual problem micro-frontends solve (and the conditions where that problem exists)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Micro-frontend architecture makes genuine sense for a specific scenario: large organizations where multiple independent teams need to own, deploy, and iterate on different parts of a large frontend application without coordinating with each other. Think of a company where the checkout team and the product catalog team and the user account team are all 20+ people, all shipping independently, and the coupling cost of a monolithic frontend has become a real operational bottleneck.&lt;/p&gt;

&lt;p&gt;In that scenario, the tradeoffs are worth it. You accept some UX consistency overhead, you invest in a shared design system team, you build proper communication protocols between microfrontends, and you get meaningful team autonomy and deployment independence in return.&lt;/p&gt;

&lt;p&gt;The problem is that this specific scenario applies to maybe 5% of the teams adopting micro-frontends. The rest are adopting them because the idea sounds sophisticated, or because their engineering blog feed is full of how Zalando and DAZN did it, or because "monolith" has been made to sound like a dirty word.&lt;/p&gt;

&lt;p&gt;For a team of eight developers, building separate micro-frontends almost always creates more coordination overhead than it removes. You're now managing shared dependencies, version conflicts, cross-app communication, shell application routing, and consistent styling across independently deployed applications. With eight people. Who probably also needs to build features.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The UX consequences nobody talks about&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The seams in a micro-frontend implementation are where the user experience often degrades visibly. Here's what that actually looks like in practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loading state fragmentation.&lt;/strong&gt; Each microfrontend typically manages its own loading states. So as a user navigates through the application, they might see a full-page spinner in one section and skeleton loaders in another, or nothing at all in a third. There's no unified loading experience because there's no unified state management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design system drift.&lt;/strong&gt; Even when teams start with the same design system, divergence happens. Team A upgrades to v3.2 of your shared component library. Team B is on v2.8 and doesn't have time to upgrade this quarter. Team C forked a component two months ago because they needed a custom behavior. Six months later, you have three visually-similar-but-subtly-different versions of your primary button across the same product. Users don't consciously notice this, but it creates a vague sense of untrustworthiness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Client-side routing inconsistencies.&lt;/strong&gt; URL structure, transition animations, back-button behavior, all of these need to be carefully coordinated in a micro-frontend setup, and they often aren't. The result is navigation that works differently depending on which "zone" of the app you're in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance isolation that hurts global performance.&lt;/strong&gt; Each microfrontend loading its own framework bundle is the obvious one, if you have five React apps on the same page, you're potentially loading React five times (module federation helps here but introduces its own complexity). But less obvious is how harder it becomes to do meaningful performance optimization across the whole user journey when you don't have a unified view of what's loading and when.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What teams should actually do instead (most of the time)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before reaching for micro-frontends, there are usually several intermediate steps that give you most of the team-autonomy benefits with far less UX cost:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modular monolith with strong ownership conventions.&lt;/strong&gt; Your frontend can be a single deployable unit while still having strong internal module boundaries. Different teams own different modules, there are clear API contracts between them, but they're deployed together and share a runtime. This works extremely well up to a pretty large scale if you're disciplined about boundaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feature flags for independent deployment cadences.&lt;/strong&gt; A lot of the "we need micro-frontends for independent deployment" argument goes away if you can ship features independently behind flags within a monolithic deploy. Tools like LaunchDarkly or Unleash make this accessible even for smaller teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A dedicated design system team before anything else.&lt;/strong&gt; If UI consistency is your real problem and it often is, the solution isn't architecture. It's investing in a proper design system with a dedicated owner. A well-maintained component library used across the app solves most visual consistency problems and doesn't require splitting your frontend.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;When to actually use micro-frontends&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To be fair: there are real use cases.&lt;/p&gt;

&lt;p&gt;If you're integrating a legacy system into a newer product and can't rewrite everything at once, micro-frontends let you wrap legacy sections without rebuilding them from scratch. Genuinely useful.&lt;/p&gt;

&lt;p&gt;If you have a partner or acquisition whose frontend you need to embed in your product, keeping it as an isolated micro-frontend makes more sense than trying to merge codebases.&lt;/p&gt;

&lt;p&gt;If you have 15+ frontend developers across genuinely autonomous product teams shipping multiple times a day independently, the coordination benefits start to outweigh the costs.&lt;/p&gt;

&lt;p&gt;The heuristic I'd apply: if you have to convince yourself that your situation fits the micro-frontend use case, it probably doesn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;A note on backend-for-frontend patterns and where they help&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One thing that does scale well alongside micro-frontends or really, any frontend architecture, is the Backend-for-Frontend (BFF) pattern. Having a dedicated API layer per client (mobile, web, third-party) that aggregates and shapes data for that specific client significantly reduces the coordination problems between frontend and backend teams.&lt;/p&gt;

&lt;p&gt;This is an area where having an experienced development partner matters. Getting the API architecture right from the beginning, building the kind of BFF or API gateway patterns that support frontend teams without creating bottlenecks, is something that teams like &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;Mittal Technologies&lt;/a&gt; think about as part of the broader architecture conversation, not as an afterthought.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The actual question to ask before any architecture decision&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here's the thing about architecture decisions in general, not just micro-frontends: the right question isn't "what does this make possible?" It's "what problem does this solve that we actually have right now?"&lt;/p&gt;

&lt;p&gt;Good architecture is usually boring from the outside. It's the thing that lets the team move fast, keeps the product consistent, and doesn't create surprises. It's not the thing that gets you a speaking slot at a frontend conference.&lt;/p&gt;

&lt;p&gt;If your current architecture is a monolith that works, ships reliably, and doesn't cause significant team coordination problems, maybe just leave it alone. Or modularize it carefully. But don't refactor toward micro-frontends because the architecture blog posts made it sound like that's what serious engineering teams do.&lt;/p&gt;

&lt;p&gt;The most sophisticated engineering decision you can make is often the simpler one.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this resonated with you, drop a comment, curious how many teams have actually gone through a micro-frontend adoption and come out the other side thinking it was worth it. Honest accounts are hard to find.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ux</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built the Same App With and Without AI Coding Tools: The Difference Was Embarrassing</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Fri, 12 Jun 2026 11:46:44 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/i-built-the-same-app-with-and-without-ai-coding-tools-the-difference-was-embarrassing-4pnp</link>
      <guid>https://dev.to/mittal_technologies/i-built-the-same-app-with-and-without-ai-coding-tools-the-difference-was-embarrassing-4pnp</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F37xhfmpxiri33d17x3c9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F37xhfmpxiri33d17x3c9.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
A few months back I got into a conversation with a colleague who was skeptical about AI coding tools, not dismissive, actually skeptical, which is a different thing. His argument was essentially: the productivity gains are real in demos but overstated in actual production development, where the complexity lives in the system design and the debugging, not in the typing.&lt;/p&gt;

&lt;p&gt;I thought he had a point. So, I did something slightly ridiculous: I built the same small application twice. First without any AI coding assistance, just me, my editor, documentation, and Stack Overflow like it's 2019. Then with AI tools integrated throughout, Cursor for code generation, Claude for architecture discussions and debugging, Copilot for the repetitive scaffolding.&lt;/p&gt;

&lt;p&gt;The project was a task management API with a React frontend. Nothing novel. A user authentication system, a PostgreSQL database, CRUD operations for tasks with filtering and tagging, and a basic dashboard. The kind of thing a mid-level developer could build competently. I kept detailed time logs for both builds.&lt;/p&gt;

&lt;p&gt;Here's what I found, and I want to be honest about the nuances rather than just giving you the headline number.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The Setup: What the App Actually Required to Build&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To be useful as a comparison, the spec needed to be fixed between both builds. Same feature set, same tech stack, same quality bar. No cutting corners in the AI-assisted build to make the comparison look better.&lt;/p&gt;

&lt;p&gt;Tech stack: Node.js with Express, PostgreSQL with Prisma ORM, React with TypeScript on the frontend, JWT authentication, deployed to a simple VPS. Testing: unit tests for core business logic with Jest, basic integration tests for the API endpoints. About 60 API routes total, with the frontend dashboard consuming them.&lt;/p&gt;

&lt;p&gt;I've built things like this dozens of times. I know the patterns well. This wasn't a case of AI helping me figure out something unfamiliar, it was AI helping me do something I already knew how to do. Which I thought would minimize the advantage. I was wrong about that.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Build 1: Without AI Tools - Time Breakdown and Where I Actually Spent Hours&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Total time: 47 hours over 9 days. Here's roughly where it went.&lt;br&gt;
Project scaffolding and configuration: 3.5 hours. Setting up the project structure, configuring TypeScript, setting up the ORM, writing the initial Docker Compose file. This stuff is tedious and I know it well, which means I do it quickly, but it's still time.&lt;/p&gt;

&lt;p&gt;Authentication system: 6 hours. Writing the middleware, the JWT handling, the refresh token logic, the password hashing, the validation. This is one of those areas where I'm careful because the cost of getting it wrong is high, so I moved slowly.&lt;/p&gt;

&lt;p&gt;Database schema and migrations: 2.5 hours. Schema design was quick because I've done these enough times. Migrations took longer than they should have because of one relationship I kept getting wrong.&lt;/p&gt;

&lt;p&gt;API routes, the bulk of the work: 18 hours. Sixty routes with proper error handling, input validation, and some of them with non-trivial business logic. The repetition is real but not completely mechanical, each endpoint has edge cases.&lt;/p&gt;

&lt;p&gt;Frontend: 12 hours. React with TypeScript, state management, the dashboard components. This is where I enjoy myself more, but it's also where I spent the most time debugging.&lt;/p&gt;

&lt;p&gt;Testing: 5 hours. Writing tests after the fact, which is not the way I prefer to work but was consistent between both builds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Auth middleware — I wrote this from scratch in Build 1// ~45 minutes to get right with edge casesexport const authenticate = async (req, res, next) =&amp;gt; {  const token = req.headers.authorization?.split(' ')[1];  if (!token) return res.status(401).json({ error: 'No token' });  try {    const decoded = jwt.verify(token, process.env.JWT_SECRET);    req.user = await prisma.user.findUnique({ where: { id: decoded.userId } });    if (!req.user) return res.status(401).json({ error: 'User not found' });    next();  } catch (err) {    return res.status(401).json({ error: 'Invalid token' });  }};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Build 2: With AI Coding Tools - What I Used and How I Actually Used It&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Total time: 21 hours over 4 days. Before I explain how, let me be specific about what AI assistance I used and how.&lt;/p&gt;

&lt;p&gt;I used Cursor as my primary editor with AI code completion enabled. For anything architectural or complex, I used Claude in a separate window for discussion and longer code generation. I used GitHub Copilot for autocomplete on repetitive patterns. I did not paste the generated code without reading it. Every function that touched authentication, database queries, or user data got a deliberate review before I moved on.&lt;/p&gt;

&lt;p&gt;Scaffolding and configuration: 45 minutes. I described the project structure I wanted, got a reasonable starting point, and adjusted a few things. The Docker Compose file took about 8 minutes total.&lt;/p&gt;

&lt;p&gt;Authentication system: 1.5 hours. I generated the initial implementation, reviewed it carefully (this is where I found two issues, a missing token expiry checks and a subtle timing attack vulnerability in the password comparison that used == instead of crypto.timingSafeEqual), fixed both, then moved on. Finding those issues would have been equally important without AI help, but I got to the review stage much faster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// AI generated this — I caught the timing attack issue// Wrong version (AI's first output):if (storedHash == inputHash) { ... }  // vulnerable// Corrected version after review:const isValid = crypto.timingSafeEqual(  Buffer.from(storedHash),  Buffer.from(inputHash));if (isValid) { ... }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;API routes: 7 hours, down from 18. This is the biggest single gain. For standard CRUD endpoints with input validation and error handling, I generated the boilerplate, reviewed the logic, added the edge cases, and moved on. The repetitive structure of sixty similar-but-not-identical endpoints is exactly where AI assistance multiplies productivity.&lt;/p&gt;

&lt;p&gt;Frontend: 7.5 hours, down from 12. TypeScript component scaffolding, basic state management patterns, hook implementations, the AI did the structural work, and I did the design and logic decisions.&lt;/p&gt;

&lt;p&gt;Testing: 3 hours. Generating test structure and basic test cases for common paths, then writing the edge case tests myself. The AI is good at test boilerplate and obvious happy-path tests. Less reliable on edge cases that require understanding your specific business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Real Numbers and What They Actually Mean&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;47 hours versus 21 hours. A 55% reduction in development time. My skeptical colleague's specific objection was that the gains disappear in production-quality work. My experience was the opposite, the gains were larger in production-quality work than in the kind of clean demos I'd seen, precisely because production work has so much structured boilerplate that AI handles well.&lt;/p&gt;

&lt;p&gt;But here's the nuance: the code quality was roughly equivalent between both builds, and that's because I reviewed everything. If I hadn't reviewed the AI output, the second build would have shipped with two security issues and probably a handful of logic errors I caught on review. The productivity gain is real only if it doesn't come at the cost of the review process.&lt;/p&gt;

&lt;p&gt;The areas where AI assistance helped least: debugging runtime errors, especially anything environment specific. Designing the data model, I tried to delegate this and got back something technically functional but not well-suited to how I needed to query the data. Anything requiring me to hold significant system context in my head simultaneously.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Where This Matters for Real Teams and Real Projects&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A solo developer or small team working on a well-scoped application will see productivity gains in the range I saw, maybe 40-60% on implementation time if they're disciplined about how they use AI assistance and don't skip the review process.&lt;/p&gt;

&lt;p&gt;The gains compress on more complex systems. When the challenge is not 'implement this pattern' but 'design the right architecture for this constraint set,' AI tools are useful discussion partners but not time multipliers in the same way. The 10x productivity claims you see in social media are for the kind of work that's already fast, not the kind of work that's genuinely hard.&lt;/p&gt;

&lt;p&gt;There's also a class of production system, the ones with real scale requirements, complex integrations, security surface areas that need proper review, and maintenance teams who need to understand every part of the codebase, where AI-assisted development gets you to a prototype efficiently and then you need experienced engineers to take it further. &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;Mittal Technologies&lt;/a&gt; is the kind of team you bring in when the system has grown past what AI-assisted solo development can carry cleanly. The handoff from prototype to production-grade software is a real transition and having people who've made that transition across many different systems is the difference between a codebase you can maintain and one that becomes technical debt.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AI coding tools have made me faster at the things I was already good at. They haven't changed what I need to know, what I need to review, or what requires genuine engineering judgment. That's both a limitation and, honestly, the right way for this technology to work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;FAQs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Which AI coding tool is actually the best for professional development?&lt;/strong&gt;&lt;br&gt;
Cursor has become my primary editor integration, the context-aware generation within the editor is more useful for day-to-day work than context-switching to a separate chat interface. Claude is my go-to for architecture discussions and longer code generation tasks where I want to think through the approach before implementation. The right combination depends on your workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does AI-generated code need to be reviewed differently than human-written code?&lt;/strong&gt;&lt;br&gt;
Yes, with an important qualifier. AI-generated code should be reviewed at least as carefully as code from a junior developer, not because it's worse on average, but because the failure modes are different. AI code tends to be syntactically clean and structurally sensible while sometimes missing subtle security, performance, or logical issues that require domain knowledge to catch. Treat it as a first draft that needs a thorough review, not as production-ready output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does using AI tools make you a worse developer over time?&lt;/strong&gt;&lt;br&gt;
This is the question I think about the most. My current view: if you use AI to avoid understanding what the code does, yes, potentially. If you use it to move faster through things you already understand, and you still do the review, design, and debugging work yourself. No, you probably get better because you're exposed to more patterns and spend more time on the hard parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How should I log time spent with AI tools for client billing?&lt;/strong&gt;&lt;br&gt;
Bill for your expertise and judgment, not for keystrokes. If AI tools reduce your implementation time but the design, review, and quality assurance is still yours, the value you're delivering hasn't changed. Many developers are having this conversation with clients explicitly and finding that honesty about AI use is better received than they expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are AI coding tools reliable for security-critical code?&lt;/strong&gt;&lt;br&gt;
Unreliable enough to require thorough review. In my experiment, the AI produced two security issues in authentication code that would have shipped if I hadn't caught them on review. Both were subtle. Neither was obvious from reading the code quickly. Security-critical code should always be reviewed by someone with security knowledge, regardless of how it was generated.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>coding</category>
      <category>frontend</category>
      <category>api</category>
    </item>
    <item>
      <title>AI Agents vs Traditional Automation: What's the Difference?</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Thu, 11 Jun 2026 09:05:22 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/ai-agents-vs-traditional-automation-whats-the-difference-n7e</link>
      <guid>https://dev.to/mittal_technologies/ai-agents-vs-traditional-automation-whats-the-difference-n7e</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wp03y0zjujj4jsbgo0x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wp03y0zjujj4jsbgo0x.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
If you've been building software for more than a few years, you've probably already worked with some form of traditional automation, cron jobs, Zapier flows, rule-based scripts, RPA (Robotic Process Automation) bots. They work. They're predictable. And for a long time, they were the ceiling of what "automation" meant in a business context.&lt;/p&gt;

&lt;p&gt;Then AI agents showed up. And a lot of developers are now trying to figure out: is this just automation with better marketing? Or is there something genuinely different here?&lt;/p&gt;

&lt;p&gt;The honest answer is there's something genuinely different. But it's not magic, and it matters to understand where the difference actually is.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Traditional Automation Rules-Based, Deterministic, Bounded&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Traditional automation is based on explicit instructions. You specify the trigger, the condition, and the action. If X happens and Y is true, do Z.&lt;/p&gt;

&lt;p&gt;This is powerful for well-defined, repetitive processes. A script that runs nightly to pull data from an API, transform it, and load it into a database? Perfect use case. A workflow that sends a Slack notification when a GitHub PR is merged? Exactly what traditional automation was built for.&lt;/p&gt;

&lt;p&gt;The characteristics that define it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic:&lt;/strong&gt; given the same input, it always produces the same output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Brittle to edge cases:&lt;/strong&gt; if the input doesn't match the expected format, it breaks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manually defined logic:&lt;/strong&gt; every decision branch has to be written explicitly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No context awareness:&lt;/strong&gt; it doesn't "understand" what it's doing, just executes the instructions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Classic RPA (tools like UiPath or Automation Anywhere) extended this to UI-level automation, mimicking mouse clicks and keystrokes to automate legacy systems. Useful, but fragile whenever the UI changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;AI Agents: Goal-Oriented, Adaptive, Context-Aware&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;An AI Agent works on a different model. Rather than a fixed set of instructions, it is given a goal and then figures out how to reach that goal. It can plan multi-step sequences, it can use external tools, it can handle unexpected inputs, and it can adapt if something goes wrong mid-task.&lt;/p&gt;

&lt;p&gt;The technical architecture matters here. A typical AI agent setup involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;LLM&lt;/strong&gt; (large language model) as the reasoning core&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool definitions&lt;/strong&gt; function the agent can call (search the web, query a database, send an API request, write a file)&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;memory layer&lt;/strong&gt; short-term context within a session, sometimes persistent long-term memory&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;orchestration loop&lt;/strong&gt; the agent reasons about what to do next, calls a tool, observes the result, and decides on the next step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a simplified example. A traditional automation to handle a customer support ticket might:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check if the keyword matches a category&lt;/li&gt;
&lt;li&gt;Route to the right queue&lt;/li&gt;
&lt;li&gt;Send an acknowledgment email&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An AI agent handling the same workflow might:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the ticket and understand the actual issue (not just match keywords)&lt;/li&gt;
&lt;li&gt;Check the customer's order history and account status via API&lt;/li&gt;
&lt;li&gt;Draft a personalized response&lt;/li&gt;
&lt;li&gt;Escalate to a human if confidence is below a threshold&lt;/li&gt;
&lt;li&gt;Log a summary in the CRM&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Same outcome. Completely different mechanism. The agent is reasoning, not just executing.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Where Traditional Automation Still Wins&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This isn't an "AI agents replace everything" argument. Traditional automation is often the right tool.&lt;/p&gt;

&lt;p&gt;When your process is completely deterministic, highly repetitive, and the inputs are clean and structured, a well-written script or RPA bot will outperform an AI agent on reliability, cost, and speed. You don't need an LLM to parse a CSV and insert rows into a database.&lt;/p&gt;

&lt;p&gt;The cost/reliability tradeoff also matters. AI agents introduce non-determinism. The same input might produce slightly different outputs across runs. For workflows where consistency is paramount (financial reconciliation, compliance logging), that's a real concern. Traditional automation is more auditable and testable in conventional ways.&lt;/p&gt;

&lt;p&gt;And infrastructure-wise, AI agents are heavier. API calls to LLMs aren't free. Token costs add up. Traditional automation is cheaper to run at scale for simple repetitive tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Where AI Agents Win Decisively&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The gap opens up where traditional automation would require thousands of manually coded rules or would simply break on edge cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processing unstructured inputs (emails, documents, images, voice)&lt;/li&gt;
&lt;li&gt;Tasks that require judgment or multi-step reasoning&lt;/li&gt;
&lt;li&gt;Workflows that involve ambiguity, context, or variable paths&lt;/li&gt;
&lt;li&gt;Anything requiring natural language understanding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A practical test: if describing the automation logic requires paragraphs rather than flowchart boxes, you probably want an agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Architecture Pattern in 2026&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;What most sophisticated engineering teams are building right now is a hybrid system, traditional automation handles the structured, deterministic layers; AI agents handle the unstructured, judgment-heavy parts. They hand off to each other.&lt;/p&gt;

&lt;p&gt;A database update triggered by an event → traditional automation. Interpreting a customer complaint email and deciding how to route it → AI agent. Logging the agent's decision → traditional automation again.&lt;/p&gt;

&lt;p&gt;The companies building real-world AI agent infrastructure and the teams supporting that build, are the ones combining these two worlds intelligently. If you're working on enterprise automation or AI integration, it's worth connecting with teams that have experience across both patterns. &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;Mittal Technologies&lt;/a&gt; builds custom AI-powered automation solutions that bridge exactly this gap, practical systems, not just demos.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Bottom Line for Developers&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Traditional automation is a hammer. Excellent for nails. AI agents are more like having a junior engineer, capable of handling novel situations, but requiring clear goals, good tooling, and appropriate oversight.&lt;/p&gt;

&lt;p&gt;The decision framework is simple enough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deterministic, structured, high-volume → traditional automation&lt;/li&gt;
&lt;li&gt;Judgment-heavy, unstructured, variable paths → AI agent&lt;/li&gt;
&lt;li&gt;Complex enterprise workflows → probably both&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither is going away. Understanding the tradeoffs is what separates good systems design from overengineered ones.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rpa</category>
      <category>api</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>AI Coding Assistants vs Junior Developers: What Actually Happens in Real Projects?</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Tue, 09 Jun 2026 09:14:44 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/ai-coding-assistants-vs-junior-developers-what-actually-happens-in-real-projects-1lcl</link>
      <guid>https://dev.to/mittal_technologies/ai-coding-assistants-vs-junior-developers-what-actually-happens-in-real-projects-1lcl</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzn171h7bm7vnpoh0sr7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzn171h7bm7vnpoh0sr7d.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
There's a debate happening in a lot of engineering teams right now that's rarely said out loud in retrospectives or sprint reviews but comes up constantly in 1:1s and Slack DMs: &lt;em&gt;do we still need to hire junior developers?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It's not a comfortable question to ask. It feels a bit like asking whether interns are worth the onboarding effort. But the reason it keeps surfacing is that AI coding assistants have gotten genuinely, noticeably better at the kinds of tasks that used to be the natural entry point for a junior dev.&lt;/p&gt;

&lt;p&gt;Let me walk through what I've actually seen happen, not theory, not vendor marketing, but real project dynamics.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;What AI Coding Assistants Actually Do Well (and Where They Quietly Fall Apart)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The honest answer is they're excellent at a surprising number of things, and genuinely unreliable at a different set of things. The problem is that the failure modes aren't always obvious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where they're strong:&lt;/strong&gt;&lt;br&gt;
Boilerplate generation. Give a coding assistant a clear spec for a CRUD endpoint and it'll output something functional, correctly structured, and reasonably idiomatic in most modern languages. What used to take a junior dev half a day might take 20 minutes including review.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;javascript&lt;/span&gt;
&lt;span class="c1"&gt;// Ask Copilot or Cursor for a basic Express route with validation&lt;/span&gt;
&lt;span class="c1"&gt;// You'll typically get something like this, working first try:&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validationResult&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express-validator&lt;/span&gt;&lt;span class="dl"&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;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isEmail&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;normalizeEmail&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;notEmpty&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validationResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEmpty&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// actual logic here&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's a genuinely useful output. Not just as a starting point, often as the actual implementation, assuming your validation needs are standard.&lt;/p&gt;

&lt;p&gt;Debugging known patterns. "This error is happening, here's the stack trace and the code around it." For error patterns that exist in training data, which is the most common error, AI assistants can diagnose and suggest fixes faster than a junior dev Googling the error message.&lt;/p&gt;

&lt;p&gt;Writing tests. Give it a function and ask for unit tests. For pure functions with clear input-output contracts, it's surprisingly capable. Edge cases are hit or miss, but the happy path coverage is reliable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where they fall apart:&lt;/strong&gt;&lt;br&gt;
System-level understanding. An AI assistant doesn't know your codebase beyond what's in the current context window. It doesn't know the architectural decision you made six months ago that means you can't just use a standard library approach here. It doesn't know that the service it's recommending you call is rate-limited in production and you've had incidents because of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt;
&lt;span class="c1"&gt;# Copilot will happily suggest something like this
# without knowing that rate_limit_wrapper is already failing in prod
&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_user_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;external_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# will suggest the direct call
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# What actually needs to happen:
&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_user_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;rate_limiter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;acquire&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;  &lt;span class="c1"&gt;# context-specific wrapper your team built
&lt;/span&gt;        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;external_api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Judgment calls. When there are three reasonable ways to approach a problem and the right choice depends on factors like team velocity, tech debt priorities, or a coming architectural change, an AI assistant will pick one and seem confident. That confidence is often misplaced.&lt;/p&gt;

&lt;p&gt;Code review in any meaningful sense. It can check syntax and flag obvious issues, but it won't tell you, "this approach will cause problems when we hit 10x scale" or "this is inconsistent with how we handle auth elsewhere in the system."&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;So, What Does a Junior Developer Actually Bring?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here's where the question gets more nuanced. The junior developer who was mainly writing boilerplate CRUD endpoints and fixing simple bugs, that role has genuinely shrunk. That's a real shift and it's not going to reverse.&lt;/p&gt;

&lt;p&gt;But a junior developer who's treated as a &lt;em&gt;growing team member&lt;/em&gt; brings things AI doesn't:&lt;/p&gt;

&lt;p&gt;They ask "why." A junior dev who doesn't understand a design decision will ask about it. That question either surfaces something worth reconsidering or creates a teaching moment that strengthens the team's shared understanding. An AI assistant executes without asking why, which is great for speed and terrible for catching bad assumptions.&lt;/p&gt;

&lt;p&gt;They own things. An AI assistant doesn't feel the weight of shipping something broken. A junior dev who shipped a bug and had to fix it at 11pm carries that learning forward. Accountability drives judgment in a way that capability alone doesn't.&lt;/p&gt;

&lt;p&gt;They become senior developers. This is the most pragmatic point and somehow gets skipped in these conversations. If companies stop hiring juniors because AI handles entry-level coding tasks, there's a pipeline problem in three to five years when those companies need senior engineers who understand both the new AI-assisted workflows and the underlying fundamentals.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What Actually Works in Practice&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The teams I've seen handle this well treat AI coding assistants as a multiplier on junior developer productivity, not a replacement for it. The junior dev uses Copilot or Cursor aggressively for boilerplate and initial implementations, then applies their growing judgment about when the output is trustworthy and when it needs to be questioned.&lt;/p&gt;

&lt;p&gt;The senior developer's role shifts a bit, less time on code generation review at the line level, more time on architecture, context-setting, and helping the junior understand when and why to push back on what the AI suggested.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;Mittal Technologies&lt;/a&gt;, this kind of AI-augmented development workflow has become part of how they approach both internal projects and client builds, not as a gimmick, but as a genuine rethink of where human judgment adds the most value in a software development process.&lt;/p&gt;

&lt;p&gt;The answer to "AI coding assistants vs junior developers" isn't either/or. It's: what are you optimizing for, and are you being honest about what each one actually does well? &lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Server-Side Rendering vs Client-Side Rendering: What Nobody Tells You Until It's Too Late</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Mon, 08 Jun 2026 11:52:05 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/server-side-rendering-vs-client-side-rendering-what-nobody-tells-you-until-its-too-late-1kne</link>
      <guid>https://dev.to/mittal_technologies/server-side-rendering-vs-client-side-rendering-what-nobody-tells-you-until-its-too-late-1kne</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86rhqxrfoeh51hhvxkvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86rhqxrfoeh51hhvxkvx.png" alt=" "&gt;&lt;/a&gt;&lt;br&gt;
Every few months someone in Discord or Slack I'm in asks the SSR vs CSR question, and the answers are usually the same: "SSR is better for SEO," "CSR is better for interactivity," "it depends." All true. None of it particularly useful when you're staring at a greenfield project or trying to figure out why your React app tanks on Lighthouse.&lt;/p&gt;

&lt;p&gt;So let me try to be actually specific about this.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;The mental model that makes this click&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here's the thing that I wish someone had explained clearly when I was first navigating this: SSR and CSR aren't really competing architectural philosophies; they're answers to a specific question: &lt;em&gt;at what point in the journey from server to browser does your HTML get built?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server-Side Rendering (SSR):&lt;/strong&gt; The HTML is fully constructed on the server before it reaches the browser. The user gets a complete, readable page on first load. JavaScript may hydrate it afterward for interactivity, but the content is already there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Client-Side Rendering (CSR):&lt;/strong&gt;&lt;br&gt;
 The server sends a mostly empty HTML shell. The browser downloads JavaScript, executes it, makes API calls, and then builds the DOM. The page content arrives after several roundtrips.&lt;/p&gt;

&lt;p&gt;That distinction has real consequences depending on what you're building.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Where CSR actually makes sense (and developers keep picking it for the wrong reasons)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;CSR became the default for a lot of teams for one reason: React, Vue, and Angular all default to it, and those are the frameworks people know. So, there's a strong pull toward CSR just from familiarity and tooling momentum.&lt;/p&gt;

&lt;p&gt;And for certain apps, CSR is genuinely the right choice. Highly interactive dashboards, admin panels, SaaS tools where SEO doesn't matter and users are authenticated anyway, CSR is fine there. You don't need SSR to power an internal CRM or a data visualization tool behind a login.&lt;/p&gt;

&lt;p&gt;The problem is when CSR gets applied to content-heavy, public-facing sites. Here's what that actually looks like in the network tab:&lt;/p&gt;

&lt;p&gt;GET /              → 200 OK (returns ~1KB HTML shell)&lt;br&gt;
GET /bundle.js     → 200 OK (returns 800KB+ JS bundle)&lt;br&gt;
[JS executes]&lt;br&gt;
GET /api/posts     → 200 OK (returns actual content)&lt;br&gt;
[DOM renders content]&lt;/p&gt;

&lt;p&gt;The user sees a blank or loading screen for the entire duration of that chain. On a fast connection, it's maybe 1-2 seconds. On a 3G connection or a low-end Android device, the kind that a significant chunk of global users actually have, it can be 6-10 seconds of nothing. And Google's crawler, even though it can execute JavaScript, still has to wait for that execution before it can index your content.&lt;/p&gt;

&lt;p&gt;That's not a theoretical problem. That's why so many React SPAs have poor Lighthouse scores and mediocre search visibility despite genuinely good content.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;SSR done right and the hydration problem people don't warn you about&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;SSR solves the above by moving HTML construction to the server. Here's the same request flow:&lt;/p&gt;

&lt;p&gt;GET /              → 200 OK (returns ~50KB complete HTML)&lt;br&gt;
[Browser renders immediately — user sees content]&lt;br&gt;
GET /bundle.js     → 200 OK (hydrates for interactivity)&lt;/p&gt;

&lt;p&gt;The content is visible almost immediately. LCP scores are dramatically better. Search engines get complete HTML to index on the first fetch.&lt;/p&gt;

&lt;p&gt;In Next.js, the simplest SSR pattern looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/posts/[slug].js&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;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&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;post&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;fetchPostBySlug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// runs on server&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PostPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;post&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;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/article&lt;/span&gt;&lt;span class="err"&gt;&amp;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;The HTML returned to the browser already contains the post content. The browser doesn't need to wait for JavaScript execution to see anything meaningful.&lt;/p&gt;

&lt;p&gt;But here's what nobody adequately warns you about: hydration mismatches. When React "takes over" the server-rendered HTML and attaches event listeners, it needs the client-side render tree to match what the server sent. If they diverge, because of timestamps, random IDs, localStorage reads during render, browser-only APIs, React throws warnings or silently re-renders, potentially causing layout shift or interactivity bugs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This breaks SSR — window doesn't exist on server&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;theme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Safe pattern — check environment first&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;theme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a class of bug that only surfaces in SSR environments. If you've only ever built CSR apps, it'll catch you.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Static Site Generation: the option that beats both for the right use case&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Worth mentioning because it often gets collapsed into the SSR conversation: SSG (Static Site Generation) builds HTML at build time rather than request time. For content that doesn't change per-request, blog posts, marketing pages, documentation, this is almost always the right call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Next.js SSG&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;getStaticProps&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;posts&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;fetchAllPosts&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;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ISR: regenerate every hour&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;The HTML is pre-built, served from a CDN edge, and requires zero server computation per request. Time to the first byte is measured in single-digit milliseconds. This is how you get a 99 Lighthouse performance score without heroic optimization effort.&lt;/p&gt;

&lt;p&gt;The limitation is obviously dynamic content, if your page needs user-specific data or changes frequently, pure SSG doesn't work. Incremental Static Regeneration (ISR) in Next.js handles a lot of the middle ground.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Practical Decision Framework&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Rather than "SSR vs CSR," I now think about it as:&lt;br&gt;
&lt;strong&gt;Use SSG/ISR&lt;/strong&gt; for: public content pages, marketing, blogs, documentation, ecommerce product listings. Content doesn't change per-request; SEO matters; performance is critical.&lt;br&gt;
&lt;strong&gt;Use SSR&lt;/strong&gt; for: pages requiring real-time server data, user-specific server-rendered content (dashboards with server session data), or content that must be fresh on every request.&lt;br&gt;
&lt;strong&gt;Use CSR&lt;/strong&gt; for: authenticated application interfaces, heavily interactive tools, anything where SEO is irrelevant and you need maximum client-side flexibility.&lt;br&gt;
&lt;strong&gt;Use a hybrid&lt;/strong&gt; (which Next.js App Router, Nuxt 3, and SvelteKit all support natively): SSG/SSR for the outer shell and public content, CSR components for the interactive pieces.&lt;/p&gt;

&lt;p&gt;The businesses and products I've seen handle web performance well, including teams I've worked alongside at &lt;a href="https://mittaltechnologies.com/" rel="noopener noreferrer"&gt;Mittal Technologies&lt;/a&gt; building web applications for clients, tend to think at this level of granularity. Not "we're an SSR shop" or "we build SPAs," but "this page/route needs this rendering strategy for these specific reasons."&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;One last thing: measure before you decide&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you're revisiting an existing app's rendering strategy, run Chrome DevTools Coverage on your JavaScript bundle. It's not unusual to find that 40-60% of the JS being shipped to every page visitor is code that runs on maybe 10% of user interactions.&lt;/p&gt;

&lt;p&gt;That's not a rendering strategy problem; that's a code splitting problem. And solving it might deliver more Lighthouse improvement than switching rendering strategies entirely.&lt;/p&gt;

&lt;p&gt;Analyse your bundle before assuming you need SSR&lt;br&gt;
npx @ next/bundle-analyzer&lt;br&gt;
or for Vite/Vue&lt;br&gt;
npx vite-bundle-visualizer&lt;/p&gt;

&lt;p&gt;Understand what you're shipping before you redesign how you're shipping it.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>performance</category>
    </item>
    <item>
      <title>Building Custom Software vs Using SaaS: A Developer's Perspective</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Fri, 05 Jun 2026 09:04:07 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/building-custom-software-vs-using-saas-a-developers-perspective-1hei</link>
      <guid>https://dev.to/mittal_technologies/building-custom-software-vs-using-saas-a-developers-perspective-1hei</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5ugfxc6e42vyqdi1j4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5ugfxc6e42vyqdi1j4i.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
I want to be upfront about something before we get into this: I've seen smart people land on both sides of this decision and be completely right, and I've seen smart people land on both sides and be completely wrong. The build-vs-buy question doesn't have a clean universal answer, and anyone who tells you it does is either oversimplifying or has a financial interest in one direction.&lt;/p&gt;

&lt;p&gt;What I can offer is how I actually think about this when I'm in the room where this decision is being made, whether I'm advising a startup that's scaling faster than its tooling, or talking through architecture with a team at a company that's been using the same SaaS stack for six years and is starting to feel the ceiling.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The case for SaaS that developers undersell&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Developers, me included, have a bias toward building. It's what we do, it's what we're good at, and honestly, it's more interesting than configuring someone else's product. So, when a stakeholder asks, "can we build this ourselves?", the instinct is often yes before we've thought through the full implications.&lt;/p&gt;

&lt;p&gt;The honest case for SaaS is stronger than we typically give it credit for. A mature SaaS product embodies thousands of engineering hours, dozens of edge cases that took real production incidents to discover, security hardening that went through multiple audit cycles, and infrastructure that's been scaled and re-scaled by teams whose entire job is that one product. When you decide to build instead of buy, you're not just building the features you can see, you're committing to maintaining the features you'll discover you need over time, handling the security posture, managing the infrastructure, and doing all of this continuously, not just at launch.&lt;/p&gt;

&lt;p&gt;That's a serious commitment. And for commodity functions, authentication, payments, email delivery, document management, analytics, the SaaS option is almost always the right call. Not because building is impossible, but because the value of the custom version over the SaaS version rarely justifies the ongoing ownership cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Where the calculation actually flips for custom development&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The build vs buy decision framework for &lt;a href="https://mittaltechnologies.com/service/customsoftware" rel="noopener noreferrer"&gt;custom software development&lt;/a&gt; flips when you hit one or more of these conditions:&lt;/p&gt;

&lt;p&gt;Your core business logic is genuinely differentiating and doesn't map cleanly to any existing product. The combination of capabilities you need doesn't exist in any single SaaS product, and stitching together multiple products would create integration complexity that exceeds the complexity of building something unified. You have compliance, data residency, or security requirements that SaaS vendors can't satisfy. Or you're at a scale where the per-seat licensing economics have inverted, where the cost of the SaaS stack exceeds what a well-maintained custom solution would cost over a three-to-five-year horizon.&lt;/p&gt;

&lt;p&gt;In these cases, custom development isn't the indulgent option. It's the technically and financially correct one.&lt;/p&gt;

&lt;p&gt;Javascript&lt;br&gt;
// Example: business logic that doesn't map to generic SaaS&lt;br&gt;
// A pricing engine with dynamic rules across product combinations&lt;br&gt;
// No SaaS product handles this without significant custom configuration&lt;br&gt;
// that ends up being as complex as building it yourself&lt;/p&gt;

&lt;p&gt;const calculateDynamicPrice = async (cart, customer, context) =&amp;gt; {&lt;br&gt;
  const basePrice = await getPriceMatrix(cart.items);&lt;br&gt;
  const customerTier = await getCustomerTier(customer.id);&lt;br&gt;
  const contextualModifiers = await getContextualRules(context);&lt;/p&gt;

&lt;p&gt;return applyPricingRules(basePrice, customerTier, contextualModifiers);&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;When your pricing logic, your workflow logic, or your data model is this specific to your business, you're not configuring a SaaS product anymore, you're fighting it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Architecture decisions that matter for custom builds&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When custom is the right call, the architecture decisions made early determine almost everything about how well the system scales and how maintainable it is two or three-years in. A few things I've seen matter consistently:&lt;/p&gt;

&lt;p&gt;Domain modeling before data modeling. The database schema should reflect the business domain accurately, not just the current feature set. Spending time on this upfront, really understanding how the business talks about its own data, pays off enormously when requirements change, because the underlying model is flexible enough to accommodate them.&lt;/p&gt;

&lt;p&gt;Python&lt;br&gt;
Domain-first approach: model reflects actual business concepts&lt;br&gt;
class OrderFulfillment:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, order_id, fulfillment_method, warehouse_id):&lt;br&gt;
        self.order_id = order_id&lt;br&gt;
        self.fulfillment_method = fulfillment_method  # 'ship', 'pickup', 'delivery'&lt;br&gt;
        self.warehouse_id = warehouse_id&lt;br&gt;
        self.status = FulfillmentStatus.PENDING&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def assign_to_carrier(self, carrier_id):
    if self.fulfillment_method != 'ship':
        raise DomainError("Cannot assign carrier to non-shipping fulfillment")
    self.carrier_id = carrier_id
    self.status = FulfillmentStatus.ASSIGNED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The domain logic lives in the domain object. The delivery method is an explicit concept, not an enum in a generic "order" table. This seems like a small thing, but it compounds significantly at scale.&lt;/p&gt;

&lt;p&gt;API contracts designed for longevity. Version from day one. Design response shapes for the client's actual needs. Consistent error handling. Pagination that works when the dataset is ten times larger. These are decisions that are cheap to make correctly at the start and expensive to retrofit later.&lt;/p&gt;

&lt;p&gt;Observability as a first-class requirement. Distributed tracing, structured logging, and meaningful alerting are not optional extras, they're part of the definition of "done" for anything going to production. The debugging cost of retrofitting observability is always higher than building it in.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The hybrid reality that actually works&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The most functional architecture I've seen in production at growing companies is hybrid: SaaS for undifferentiated functions, custom for the core domain. Use Stripe for payments. Use Auth0 for authentication. Use SendGrid for transactional email. Build custom for anything that reflects how your business specifically operates, the workflow engine, the pricing logic, the customer portal, the internal tooling that powers your service delivery.&lt;/p&gt;

&lt;p&gt;The team at Mittal Technologies approaches this explicitly, identifying which parts of a system genuinely warrant custom development and which are better served by proven SaaS solutions, rather than defaulting to building everything or defaulting to SaaS for everything. That clarity at the architecture stage shapes a much better system than extreme.&lt;/p&gt;

&lt;p&gt;Build deliberately. Know what you're owning when you choose to build. And be honest about when the SaaS ceiling is a real problem versus when you just find configuration less interesting than writing code.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>softwareengineering</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Building Scalable Business Websites: Lessons Learned from Real Projects</title>
      <dc:creator>Mittal Technologies</dc:creator>
      <pubDate>Thu, 04 Jun 2026 10:03:45 +0000</pubDate>
      <link>https://dev.to/mittal_technologies/building-scalable-business-websites-lessons-learned-from-real-projects-4p21</link>
      <guid>https://dev.to/mittal_technologies/building-scalable-business-websites-lessons-learned-from-real-projects-4p21</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxcn4m4tue8wx19ujfre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxcn4m4tue8wx19ujfre.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Every developer at some point builds a website that works fine at launch, falls apart six months later, and teaches you more than any tutorial ever could. I've been there. Most of us have.&lt;/p&gt;

&lt;p&gt;The things that break aren't usually the things you spent the most time on. It's never the custom component you agonized over. It's the database that wasn't designed for how the client actually ended up using the product, or the CMS that made total sense at 10 pages but becomes a nightmare at 500.&lt;/p&gt;

&lt;p&gt;So, here's a collection of things I've learned, sometimes painfully from building business websites that actually need to scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Don't architect for the launch, architect for year two&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The brief almost always describes the site as it exists today. Five service pages, a blog, a contact form. Easy. But business websites for growing companies don't stay at five pages. They add case studies, then a resource library, then a careers section, then they want multi-language support, then the marketing team decides they need landing pages for fifteen different campaigns.&lt;/p&gt;

&lt;p&gt;If your content model, routing structure, and CMS setup was designed for the initial five pages, adding all that later becomes genuinely painful. You're retrofitting things that should have been native from the start.&lt;/p&gt;

&lt;p&gt;The fix is to spend more time upfront asking uncomfortable questions: where do you see this in two years? What sections might you add? How many people will be publishing content? Will you need localization? Some clients won't know the answers. That's fine, you can build flexible structures that accommodate uncertainty without overengineering for specific hypotheticals.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Your CMS choice is a five-year decision, treat it like one&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The CMS conversation often gets rushed. Clients want WordPress because they've heard of it. Developer defaults to whatever they're most comfortable with. Neither of those is a good reason.&lt;/p&gt;

&lt;p&gt;For a genuinely scalable business website, the CMS needs to handle: structured content modeling, multi-author workflows, versioning, API access (if you're going headless or integrating with anything), and ideally a reasonable learning curve for non-technical editors.&lt;/p&gt;

&lt;p&gt;Headless CMSes like Sanity, Contentful, or Strapi pair well with modern &lt;a href="https://mittaltechnologies.com/top-web-development-frameworks-in-2026:-what-developers-use-%28and-why%29" rel="noopener noreferrer"&gt;frontend frameworks&lt;/a&gt; and give you a clean separation of content from presentation, which pays off massively when the client wants to redesign the frontend without touching all their content. Worth the upfront complexity for anything expected to grow.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Performance is a Feature, Not a Polish Step&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I've seen too many projects where performance optimization gets scheduled for "after launch." It almost never happens after launch. There's always something more urgent.&lt;/p&gt;

&lt;p&gt;And the cost of a slow business website isn't just user experience, it's SEO, it's conversion rates, it's the client's opinion of the work you delivered. Core Web Vitals are ranking signals now. A site that loads slowly on mobile is a site that's leaving rankings on the table.&lt;/p&gt;

&lt;p&gt;Build performance from the start. Image optimization, lazy loading, appropriate caching headers, minimal third-party scripts, font loading strategy, these aren't things you add at the end. They're decisions made in how you structure the project from day one.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Integration Problem Nobody Warns You About&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Business websites don't live alone. They connect to CRMs, analytics platforms, email marketing tools, live chat widgets, booking systems, payment processors. Each integration adds complexity. Each one is a potential source of bugs, performance hits, and maintenance headaches.&lt;/p&gt;

&lt;p&gt;Document every integration from the start. Understand what happens to the site if an external service goes down. Use server-side rendering or caching where possible to insulate the site from flaky third-party APIs. And push back hard on requests to add "just one more widget", every widget has a weight.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;One Thing Every Scalable Web Project Needs: A Design System&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Even a simple one. Even if it's just a documented set of typography scales, color tokens, spacing rules, and the ten components you're actually using. Without this, by the time you're ten pages in, someone's doing everything slightly differently from someone else, and consistency disappears.&lt;/p&gt;

&lt;p&gt;Teams that build with component libraries and consistent design tokens spend dramatically less time on "why does this section look different from that section" conversations and dramatically more time on things that actually matter. This is one of the areas where working with a team experienced in &lt;a href="https://mittaltechnologies.com/service/development" rel="noopener noreferrer"&gt;scalable web development&lt;/a&gt; pays for itself quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Handoff is a Part of the Build&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The moment a developer hands off a business website to a non-technical client or a content team, the reality of the project changes. They're going to edit things you didn't expect them to edit. They're going to try to do things that break the layout. They're going to add a 4MB image directly from their camera roll.&lt;/p&gt;

&lt;p&gt;A scalable website is one that survives contact with its actual users, including the internal ones. That means documented editor guidelines, content type constraints in the CMS, image handling that degrades gracefully even when someone uploads something terrible, and a component structure that's hard to break without trying.&lt;/p&gt;

&lt;p&gt;Build for the editor who doesn't know what a viewport is. That's usually who's going to be living in your CMS six months after you've moved on to the next project.&lt;/p&gt;

&lt;p&gt;Every real-world project teaches you something the documentation doesn't. The patterns that hold up are the ones built not for the demo, but for the long run.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>performance</category>
      <category>djangocms</category>
    </item>
  </channel>
</rss>
