<?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: Sanket Bhor</title>
    <description>The latest articles on DEV Community by Sanket Bhor (@shanky1992).</description>
    <link>https://dev.to/shanky1992</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%2F153764%2Fa6e8a03c-82d9-4f5d-9291-1820bba93679.jpg</url>
      <title>DEV Community: Sanket Bhor</title>
      <link>https://dev.to/shanky1992</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shanky1992"/>
    <language>en</language>
    <item>
      <title>GitHub Copilot dropped flat pricing on June 1st. Now it's usage-based — AI credits, Actions minutes, all metered.
Solo devs won't notice. Teams with heavy PR automation? Audit your usage before the bill does it for you.</title>
      <dc:creator>Sanket Bhor</dc:creator>
      <pubDate>Sun, 07 Jun 2026 02:10:00 +0000</pubDate>
      <link>https://dev.to/shanky1992/github-copilot-dropped-flat-pricing-on-june-1st-now-its-usage-based-ai-credits-actions-38m6</link>
      <guid>https://dev.to/shanky1992/github-copilot-dropped-flat-pricing-on-june-1st-now-its-usage-based-ai-credits-actions-38m6</guid>
      <description></description>
      <category>automation</category>
      <category>githubactions</category>
      <category>githubcopilot</category>
      <category>news</category>
    </item>
    <item>
      <title>You're Not Paying for Code Generation. You're Paying for Context</title>
      <dc:creator>Sanket Bhor</dc:creator>
      <pubDate>Wed, 03 Jun 2026 15:32:08 +0000</pubDate>
      <link>https://dev.to/shanky1992/youre-not-paying-for-code-generation-youre-paying-for-context-21l4</link>
      <guid>https://dev.to/shanky1992/youre-not-paying-for-code-generation-youre-paying-for-context-21l4</guid>
      <description>&lt;h3&gt;
  
  
  The hidden cost of AI isn't generating code. It's understanding your codebase.
&lt;/h3&gt;

&lt;p&gt;For a long time, I assumed AI coding tools became expensive because they generated a lot of code. These tools can produce components, tests, SQL queries, documentation, and sometimes entire features on demand. If costs were climbing, the output volume must be the reason.&lt;/p&gt;

&lt;p&gt;The more I used these tools, the more I realized I was measuring the wrong thing. The expensive part isn't writing code. &lt;strong&gt;The expensive part is understanding what code should be written — and that work is mostly invisible.&lt;/strong&gt; That realization changed how I think about AI-assisted development entirely.&lt;/p&gt;




&lt;h2&gt;
  
  
  Two Prompts, Two Very Different Problems
&lt;/h2&gt;

&lt;p&gt;Consider these two requests: &lt;em&gt;"Create a utility function that formats dates"&lt;/em&gt; and &lt;em&gt;"Review this feature and suggest improvements."&lt;/em&gt; At first glance, both look ordinary. Both might even produce short answers. But they require completely different levels of understanding.&lt;/p&gt;

&lt;p&gt;The first is narrow and well-defined. The AI needs very little information before it can produce a useful answer. The second is open-ended. Before suggesting a single improvement, the AI may need to read multiple files, understand dependencies, follow existing patterns, compare implementations, and build a mental model of why the feature exists at all.&lt;/p&gt;

&lt;p&gt;The output might still be small. The work required to reach it is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Agent Workflows Feel Different From Autocomplete
&lt;/h2&gt;

&lt;p&gt;This became much clearer when I started using AI agents. Traditional autocomplete is predictive — you type, the AI guesses what comes next. It's fast, cheap, and deliberately context-light.&lt;/p&gt;

&lt;p&gt;Agents behave differently. When you ask one to improve a feature or review a workflow, it doesn't immediately start generating code. It starts reading. It follows imports, finds related files, and tries to understand the system before touching it. That is exactly what makes agent workflows feel slower and more resource-intensive than autocomplete: they are spending effort on understanding first.&lt;/p&gt;

&lt;p&gt;This is also where the economics become visible. In many agent workflows, the model may consume far more input tokens understanding a codebase than output tokens generating recommendations. The imbalance can be surprisingly large. You're not paying for the answer. You're paying for everything the model had to read before it could write one.&lt;/p&gt;

&lt;p&gt;This shows up in concrete ways: repository-wide indexing, codebase context pins, and agentic terminal executions all consume large amounts of context before touching the first generated line.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Log File Trap
&lt;/h2&gt;

&lt;p&gt;Debugging is where this pattern becomes most visible. A build fails, tests start breaking, a deployment goes sideways — and the natural reaction is to paste everything into the AI and ask what's wrong. I've done it myself: hundreds of lines of logs, stack traces, terminal output, configuration snippets, all dumped in at once.&lt;/p&gt;

&lt;p&gt;Most of the time, the relevant information is buried somewhere in the middle. The AI processes all of it anyway. A focused, trimmed stack trace often produces the same answer as a full log dump. The difference is purely in how much context the AI had to wade through to reach it.&lt;/p&gt;

&lt;p&gt;The lesson isn't to use AI less. It's to be more deliberate about what information you're providing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed for Me
&lt;/h2&gt;

&lt;p&gt;Once I started thinking about context rather than code generation, my prompts changed. Instead of &lt;em&gt;"Review this feature,"&lt;/em&gt; I started asking &lt;em&gt;"Review the authentication logic in these two files."&lt;/em&gt; Instead of &lt;em&gt;"Refactor this module,"&lt;/em&gt; I asked &lt;em&gt;"Simplify this service without changing the public API."&lt;/em&gt; Instead of sharing an entire build log, I shared the relevant section.&lt;/p&gt;

&lt;p&gt;The clearest example was a three-file authentication refactor where a vague prompt returned generic suggestions about error handling, null checks, and naming — the kind of advice that sounds useful without really changing much. A scoped prompt, on the other hand, immediately surfaced a session invalidation edge case I hadn't considered. It pushed the conversation from cleanup to correctness.&lt;/p&gt;

&lt;p&gt;Same codebase. Same AI. Different input, different depth of answer.&lt;/p&gt;

&lt;p&gt;The quality of the answers rarely dropped — in many cases it improved. Better prompts weren't just helping the AI. They were forcing me to think more clearly about the problem I was trying to solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Most discussions about AI costs focus on output: how much code was generated, how many requests were made. Those are easy things to measure. The more important question is usually hidden — &lt;em&gt;how much did the AI need to understand before it could answer?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The goal isn't to eliminate context. &lt;strong&gt;The goal is to eliminate unnecessary context.&lt;/strong&gt; That distinction matters more than it sounds. In most cases, we're not paying for code generation. We're paying for understanding.&lt;/p&gt;

&lt;p&gt;The code is usually the easy part. Understanding the problem has always been where the real work happens.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you noticed similar patterns while using AI coding assistants? I'd love to hear how your workflows have changed.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I write about frontend problems from real projects — follow if that's useful.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this helped, drop a ❤️ — it helps with visibility.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Connect with me:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;LinkedIn: &lt;a href="https://linkedin.com/in/sanket-bhor" rel="noopener noreferrer"&gt;Sanket Bhor&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Website: &lt;a href="https://sanketbhor.dev" rel="noopener noreferrer"&gt;sanketbhor.dev&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>loadComponent vs loadChildren in Angular 19: Choosing the Right Lazy-Loading Boundary</title>
      <dc:creator>Sanket Bhor</dc:creator>
      <pubDate>Sun, 31 May 2026 17:55:58 +0000</pubDate>
      <link>https://dev.to/shanky1992/loadcomponent-vs-loadchildren-in-angular-19-choosing-the-right-lazy-loading-boundary-32ej</link>
      <guid>https://dev.to/shanky1992/loadcomponent-vs-loadchildren-in-angular-19-choosing-the-right-lazy-loading-boundary-32ej</guid>
      <description>&lt;p&gt;There's a pattern I've been seeing more frequently across Angular codebases since standalone components became mainstream.&lt;/p&gt;

&lt;p&gt;A team migrates away from NgModules. They discover &lt;code&gt;loadComponent&lt;/code&gt;. It's simpler, requires less boilerplate, and feels aligned with where Angular is heading. So they start replacing &lt;code&gt;loadChildren&lt;/code&gt; calls across the routing configuration — one by one, sometimes all at once.&lt;/p&gt;

&lt;p&gt;The build passes. The application behaves exactly as before. Bundle reports may even suggest the migration was a success.&lt;/p&gt;

&lt;p&gt;The problem is that routing decisions are judged by what happens immediately after deployment. Architectural decisions are judged six months later.&lt;/p&gt;

&lt;p&gt;I've reviewed migrations where every &lt;code&gt;loadChildren&lt;/code&gt; route was replaced with &lt;code&gt;loadComponent&lt;/code&gt; in a single PR. The application kept working. Six months later the route structure no longer reflected the application's feature boundaries. Ownership became harder to understand. Shared concerns started leaking across routes. The routing configuration became flatter — but not simpler. One of those reviews turned into a two-sprint refactor that the team hadn't budgeted for.&lt;/p&gt;

&lt;p&gt;Angular 19 made standalone the default. New projects no longer generate NgModules, which means &lt;code&gt;loadComponent&lt;/code&gt; is now the first lazy-loading API many developers encounter. That makes the distinction between these two APIs more important than ever — not less.&lt;/p&gt;

&lt;p&gt;This article is not about which API is newer. It's about understanding the architectural boundary each one creates, and why treating them as interchangeable is a mistake that compounds quietly over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Angular Actually Says
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://angular.dev/guide/routing/loading-strategies" rel="noopener noreferrer"&gt;Angular routing documentation&lt;/a&gt; is accurate but brief on this distinction.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;loadComponent&lt;/code&gt; lazily loads a single standalone component when its route becomes active. &lt;code&gt;loadChildren&lt;/code&gt; lazily loads a set of child routes — typically from a separate routes file. Both use dynamic &lt;code&gt;import()&lt;/code&gt; under the hood. Both are fully supported in modern Angular.&lt;/p&gt;

&lt;p&gt;The documentation stops there. The architectural reasoning is left to the reader, which is where most of the confusion starts.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architectural Difference: Component Boundary vs Feature Boundary
&lt;/h2&gt;

&lt;p&gt;The surface-level difference is obvious: one loads a component, one loads routes.&lt;/p&gt;

&lt;p&gt;The more important difference is the &lt;strong&gt;scope of the lazy-loading boundary&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;loadComponent&lt;/code&gt; creates a boundary around a single screen. When a user navigates to &lt;code&gt;/help&lt;/code&gt;, Angular loads &lt;code&gt;HelpComponent&lt;/code&gt; and nothing else.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;loadChildren&lt;/code&gt; creates a boundary around a feature domain. When a user navigates to &lt;code&gt;/admin&lt;/code&gt;, Angular loads a route configuration that may contain dozens of child routes, shared providers, feature-specific guards, and related components — all bundled together as a cohesive unit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// loadComponent — boundary is one screen&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;help&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./help/help.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HelpComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// loadChildren — boundary is an entire feature domain&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;loadChildren&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/admin.routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;adminRoutes&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;Visualising where boundaries should sit makes this clearer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
│
├── /help          → loadComponent   (isolated screen, no sub-routes)
├── /about         → loadComponent   (isolated screen, no sub-routes)
├── /terms         → loadComponent   (isolated screen, no sub-routes)
│
├── /admin         → loadChildren    (feature domain)
│   ├── /users
│   ├── /users/:id
│   ├── /roles
│   └── /audit
│
├── /dashboard     → loadChildren    (feature domain)
│   ├── /analytics
│   └── /reports
│
└── /checkout      → loadChildren    (feature domain — shared state, sequential flow)
    ├── /cart
    ├── /shipping
    └── /payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The question is never "which API is more modern." The question is: &lt;strong&gt;where should the lazy-loading boundary exist for this part of the application?&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;loadComponent&lt;/th&gt;
&lt;th&gt;loadChildren&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lazy-loading scope&lt;/td&gt;
&lt;td&gt;Single component&lt;/td&gt;
&lt;td&gt;Feature route set&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chunk granularity&lt;/td&gt;
&lt;td&gt;Component-level&lt;/td&gt;
&lt;td&gt;Feature-level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Route organisation&lt;/td&gt;
&lt;td&gt;Flat&lt;/td&gt;
&lt;td&gt;Hierarchical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shared providers&lt;/td&gt;
&lt;td&gt;Possible but duplicated across routes&lt;/td&gt;
&lt;td&gt;Grouped at feature level, scoped to feature lifetime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Route-level providers&lt;/td&gt;
&lt;td&gt;Supported, but scoping breaks down at scale&lt;/td&gt;
&lt;td&gt;Naturally scoped via parent route &lt;code&gt;providers&lt;/code&gt; array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guard and resolver inheritance&lt;/td&gt;
&lt;td&gt;Must be repeated per route&lt;/td&gt;
&lt;td&gt;Applied once at the feature boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;Good for isolated pages&lt;/td&gt;
&lt;td&gt;Good for feature domains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team ownership&lt;/td&gt;
&lt;td&gt;Per-route&lt;/td&gt;
&lt;td&gt;Per-feature file&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  When loadComponent Works Best
&lt;/h2&gt;

&lt;p&gt;Some routes are genuinely independent. They have no sub-navigation. They don't share services with adjacent routes. They don't need their own route hierarchy.&lt;/p&gt;

&lt;p&gt;Good candidates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/help&lt;/code&gt; — static content, visited rarely&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/about&lt;/code&gt; — no dependencies on feature services&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/terms&lt;/code&gt;, &lt;code&gt;/privacy&lt;/code&gt; — purely informational&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/error&lt;/code&gt; — error boundary pages&lt;/li&gt;
&lt;li&gt;A lightweight settings landing page that links out to deeper sections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For these routes, &lt;code&gt;loadComponent&lt;/code&gt; is the right answer. There's no feature boundary to model, no shared providers to group, and no sub-routes that logically belong together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;help&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./help/help.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HelpComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;about&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./about/about.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AboutComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;terms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./legal/terms.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TermsComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No extra route file. No unnecessary abstraction. Just a lazy-loaded screen.&lt;/p&gt;




&lt;h2&gt;
  
  
  When loadChildren Is the Correct Architecture
&lt;/h2&gt;

&lt;p&gt;Now consider an admin area. It contains user management, role configuration, audit logs, reporting, and a dashboard. These routes share services. They share guards. They have their own sub-navigation. They belong to the same business domain and are typically owned by the same team.&lt;/p&gt;

&lt;p&gt;Here's what it looks like when &lt;code&gt;loadComponent&lt;/code&gt; is overused on a feature domain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// What this looks like when loadComponent is applied to a feature domain&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/dashboard/dashboard.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DashboardComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/users/users.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UsersComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin/users/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/users/user-detail.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UserDetailComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin/roles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/roles/roles.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RolesComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin/audit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/audit/audit-log.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AuditLogComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flat structure has real costs. Guards and resolvers must be repeated on every route individually. Providers must either be hoisted to root — where they live for the entire application lifetime — or duplicated across route definitions. Child route hierarchy is gone: &lt;code&gt;/admin/users/:id&lt;/code&gt; is now a peer of &lt;code&gt;/admin/dashboard&lt;/code&gt; at the application level rather than a child of &lt;code&gt;/admin/users&lt;/code&gt;. Ownership is unclear.&lt;/p&gt;

&lt;p&gt;Here's what it should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Feature domain correctly modelled as loadChildren&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loadChildren&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./admin/admin.routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;adminRoutes&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nx"&gt;AdminUserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;AdminAuditService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And inside &lt;code&gt;admin.routes.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adminRoutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;canActivate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AdminGuard&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dashboard/dashboard.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DashboardComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&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="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&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/users.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UsersComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&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/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&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/user-detail.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UserDetailComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;roles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./roles/roles.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RolesComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;audit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loadComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./audit/audit-log.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AuditLogComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure does several things the flat version cannot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AdminGuard&lt;/code&gt; is applied once at the feature boundary, not repeated on five routes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AdminUserService&lt;/code&gt; and &lt;code&gt;AdminAuditService&lt;/code&gt; are scoped to the admin feature — instantiated when the admin section loads, destroyed when the user leaves it (assuming default router configuration without a custom &lt;code&gt;RouteReuseStrategy&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/admin/users/:id&lt;/code&gt; is correctly a child of &lt;code&gt;/admin/users&lt;/code&gt;, not an application-level peer&lt;/li&gt;
&lt;li&gt;The admin team owns and modifies &lt;code&gt;admin.routes.ts&lt;/code&gt; without touching the root routing configuration&lt;/li&gt;
&lt;li&gt;Route &lt;code&gt;data&lt;/code&gt;, breadcrumb metadata, and analytics identifiers cascade naturally to all child routes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Worth calling out explicitly: &lt;code&gt;loadComponent&lt;/code&gt; does support a &lt;code&gt;providers&lt;/code&gt; array. The technical limitation isn't that providers are unavailable — it's that when five sibling routes all need the same service, you either duplicate the provider declaration across all five or hoist it to root. Neither is correct. &lt;code&gt;loadChildren&lt;/code&gt; solves this cleanly because the scoping boundary and the feature boundary are the same thing.&lt;/p&gt;

&lt;p&gt;The architectural signal is straightforward: if you find yourself writing &lt;code&gt;admin/&lt;/code&gt; as a prefix on five separate &lt;code&gt;loadComponent&lt;/code&gt; routes, you've missed a feature boundary.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Note on Chunk Count and Preloading
&lt;/h2&gt;

&lt;p&gt;It's tempting to treat more lazy chunks as automatically better. I've seen teams celebrate an increase in lazy-loaded chunks without measuring the actual impact. That's optimising an assumption, not a result.&lt;/p&gt;

&lt;p&gt;More chunks mean more network requests. Whether that matters depends heavily on your preloading strategy. With &lt;code&gt;PreloadAllModules&lt;/code&gt; or &lt;code&gt;QuicklinkStrategy&lt;/code&gt;, Angular preloads lazy chunks in the background after initial load — which means chunk granularity becomes less critical for perceived performance. With no preloading, a large feature chunk loaded on first navigation to &lt;code&gt;/admin&lt;/code&gt; is a real cost.&lt;/p&gt;

&lt;p&gt;Before restructuring routes for bundle reasons, run &lt;code&gt;ng build --stats-json&lt;/code&gt; and load the output into &lt;a href="https://github.com/webpack-contrib/webpack-bundle-analyzer" rel="noopener noreferrer"&gt;Webpack Bundle Analyzer&lt;/a&gt;. Measure the before and after. If you haven't measured, you haven't optimised — you've just changed things.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Replacing every &lt;code&gt;loadChildren&lt;/code&gt; call with &lt;code&gt;loadComponent&lt;/code&gt; during a standalone migration.&lt;/strong&gt;&lt;br&gt;
This is the most common mistake I see. Standalone components and route architecture are separate concerns. A standalone component works perfectly inside a &lt;code&gt;loadChildren&lt;/code&gt; route file. Migrating one does not require changing the other. I've reviewed PRs where an engineer replaced every &lt;code&gt;loadChildren&lt;/code&gt; call in a single commit and labelled it a "standalone migration" — it wasn't. It was an architectural change that happened to compile cleanly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Losing hierarchical route structure.&lt;/strong&gt;&lt;br&gt;
When &lt;code&gt;loadChildren&lt;/code&gt; is replaced with flat &lt;code&gt;loadComponent&lt;/code&gt; routes, child route hierarchy disappears. Guards, resolvers, and providers that once applied at the feature level must now be repeated per route. This surfaces in code review as &lt;code&gt;canActivate: [AuthGuard]&lt;/code&gt; duplicated across every admin route — a clear sign that a feature boundary was missed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Treating standalone components as an architecture strategy.&lt;/strong&gt;&lt;br&gt;
Standalone components improve dependency declaration and compilation. They say nothing about how routes should be organised. The routing structure decisions still belong to the engineering team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimising without measuring.&lt;/strong&gt;&lt;br&gt;
Run bundle analysis before and after any routing restructure. Smaller bundles are not automatically better. More chunks are not automatically better. Your preloading strategy changes what "better" means.&lt;/p&gt;




&lt;h2&gt;
  
  
  When loadChildren Is Overkill
&lt;/h2&gt;

&lt;p&gt;The case for &lt;code&gt;loadChildren&lt;/code&gt; at feature boundaries holds for medium-to-large applications. It is not universally correct.&lt;/p&gt;

&lt;p&gt;A small internal tool. A side project. A marketing site. A single-team application with eight routes. These gain little from introducing route files and feature boundaries everywhere. The abstraction costs more than it saves.&lt;/p&gt;

&lt;p&gt;The honest rule: use &lt;code&gt;loadChildren&lt;/code&gt; when the feature boundary is real — when there are multiple related routes, shared providers, and a clear reason to group them together. Don't introduce it to impose large-application structure on a codebase that isn't there yet. Premature route architecture is still premature optimisation.&lt;/p&gt;

&lt;p&gt;The inflection point is usually recognisable: when you find yourself duplicating guards across related routes, or when a new developer can't tell which routes belong together by reading the root configuration, the feature boundary has been missed and &lt;code&gt;loadChildren&lt;/code&gt; will pay for itself quickly.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Use in Production
&lt;/h2&gt;

&lt;p&gt;On a 600+ component Angular platform serving enterprise clients, both strategies coexist and have distinct jobs.&lt;/p&gt;

&lt;p&gt;Feature domains — client configuration, reporting, user administration, the main product dashboard — all use &lt;code&gt;loadChildren&lt;/code&gt;. These are coherent domains with their own providers, guards, and sub-navigation. Fragmenting them into individual &lt;code&gt;loadComponent&lt;/code&gt; calls would make the routing configuration harder to read and the feature boundaries harder to maintain. In a monorepo, these feature route files map directly to library boundaries, which means the routing structure reflects actual team ownership.&lt;/p&gt;

&lt;p&gt;Isolated screens — the help centre, terms pages, error boundaries, and a handful of rarely visited informational pages — use &lt;code&gt;loadComponent&lt;/code&gt;. No sub-routes, no shared dependencies, no reason to create a route file.&lt;/p&gt;

&lt;p&gt;Nobody on the team debates the APIs in isolation. The conversation is usually about ownership, shared dependencies, and deployment boundaries. The routing decision follows from those answers.&lt;/p&gt;




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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Help / About / Terms pages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;loadComponent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Isolated, no sub-routes, no shared dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error boundaries&lt;/td&gt;
&lt;td&gt;&lt;code&gt;loadComponent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Independent, no feature services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Admin area&lt;/td&gt;
&lt;td&gt;&lt;code&gt;loadChildren&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Feature domain with sub-routes, shared guards, shared services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reporting dashboard&lt;/td&gt;
&lt;td&gt;&lt;code&gt;loadChildren&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Multiple related routes, shared data services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-step checkout flow&lt;/td&gt;
&lt;td&gt;&lt;code&gt;loadChildren&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shared state, guards, sequential child routes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User account section&lt;/td&gt;
&lt;td&gt;&lt;code&gt;loadChildren&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Profile, billing, security — related routes with shared context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marketing pages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;loadComponent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Independent, no feature services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Small internal tool (&amp;lt;8 routes total)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;loadComponent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Overhead of feature files not justified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature-rich business domain&lt;/td&gt;
&lt;td&gt;&lt;code&gt;loadChildren&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Architecture boundary, not just a routing convenience&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Most routing mistakes aren't caused by choosing the wrong API. They're caused by placing the lazy-loading boundary in the wrong place.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;loadComponent&lt;/code&gt; works best when a route represents a genuinely independent screen — one component, no children, no shared dependencies.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;loadChildren&lt;/code&gt; works best when a route represents a feature domain — a coherent set of routes that share providers, guards, and ownership.&lt;/p&gt;

&lt;p&gt;The strongest Angular routing configurations use both. Not because mixing APIs is sophisticated, but because real applications contain both isolated screens and feature domains. The routing configuration should reflect that honestly.&lt;/p&gt;

&lt;p&gt;When evaluating a route, I've stopped asking "which API should I use?" I ask: &lt;strong&gt;what is the actual boundary here?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the answer is "a page," I reach for &lt;code&gt;loadComponent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the answer is "a feature," I reach for &lt;code&gt;loadChildren&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once the boundary is clear, the API choice is obvious.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you're in the middle of a standalone migration and replacing &lt;code&gt;loadChildren&lt;/code&gt; calls wholesale — slow down. Ask whether each replacement is an architectural decision or a syntax preference. The answer is not always the same, and the difference matters six months from now.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.dev/guide/routing/loading-strategies" rel="noopener noreferrer"&gt;Angular Documentation — Routing Loading Strategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.dev/guide/routing" rel="noopener noreferrer"&gt;Angular Documentation — Routing Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.dev/guide/components/importing" rel="noopener noreferrer"&gt;Angular Documentation — Standalone Components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.dev/guide/di/hierarchical-dependency-injection" rel="noopener noreferrer"&gt;Angular Documentation — Hierarchical Dependency Injection (route-level providers)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.dev/api/router/withPreloading" rel="noopener noreferrer"&gt;Angular Documentation — withPreloading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.angular.dev/meet-angular-v19-7b29dfd05b84" rel="noopener noreferrer"&gt;Angular v19 Release Notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webpack-contrib/webpack-bundle-analyzer" rel="noopener noreferrer"&gt;Webpack Bundle Analyzer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;I write about frontend problems from real projects — follow if that's useful.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this helped, drop a ❤️ — it helps with visibility.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Connect with me:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;LinkedIn: &lt;a href="https://linkedin.com/in/sanket-bhor" rel="noopener noreferrer"&gt;Sanket Bhor&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Website: &lt;a href="https://sanketbhor.dev" rel="noopener noreferrer"&gt;sanketbhor.dev&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The Stylelint Rule That Was Silently Rewriting Our SCSS Colors</title>
      <dc:creator>Sanket Bhor</dc:creator>
      <pubDate>Thu, 28 May 2026 20:30:12 +0000</pubDate>
      <link>https://dev.to/shanky1992/the-stylelint-rule-that-was-silently-rewriting-our-scss-colors-15pb</link>
      <guid>https://dev.to/shanky1992/the-stylelint-rule-that-was-silently-rewriting-our-scss-colors-15pb</guid>
      <description>&lt;p&gt;A colleague flagged something odd in a PR review — our SCSS colors had changed. Not broken, just different. &lt;code&gt;rgba(0, 0, 0, 0.7)&lt;/code&gt; had quietly become &lt;code&gt;rgb(0, 0, 0, 0.7)&lt;/code&gt; across dozens of files. The &lt;code&gt;a&lt;/code&gt; was just gone. Nobody on the team had touched those lines.&lt;/p&gt;

&lt;p&gt;No error. No warning. Just silent rewrites on every save.&lt;/p&gt;

&lt;p&gt;Took us a while to trace it back, but it was one line in &lt;code&gt;.stylelintrc&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"color-function-notation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"legacy"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My first thought was — okay, &lt;code&gt;"legacy"&lt;/code&gt; means keep the old syntax. That's literally what the word means. And technically it does enforce the older comma-separated format, so that part tracks.&lt;/p&gt;

&lt;p&gt;The issue was our codebase had gotten inconsistent. Some files had already picked up modern &lt;code&gt;rgb()&lt;/code&gt; syntax through updated dependencies. The rest still used &lt;code&gt;rgba()&lt;/code&gt;. When Stylelint's auto-fix kicked in, it just... normalised everything. Aggressively. Didn't ask, didn't warn. Hundreds of color changes in commits that had nothing to do with colors.&lt;/p&gt;

&lt;h3&gt;
  
  
  What each value does
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;What it enforces&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;"modern"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;rgb(0 0 0 / 0.7)&lt;/code&gt; — space-separated, slash for alpha&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;"legacy"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;rgba(0, 0, 0, 0.7)&lt;/code&gt; — traditional comma-separated alpha syntax&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Nothing — leaves your code exactly as you wrote it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What we actually saw in our project was &lt;code&gt;rgba()&lt;/code&gt; being rewritten to &lt;code&gt;rgb(..., alpha)&lt;/code&gt; — not the standard modern space-separated conversion. More on that below.&lt;/p&gt;

&lt;p&gt;Worth knowing: &lt;strong&gt;none of this happens without auto-fix.&lt;/strong&gt; If you're just running Stylelint normally, it warns. The actual rewrites only happen when you run &lt;code&gt;stylelint --fix&lt;/code&gt;, have a CI step with &lt;code&gt;--fix&lt;/code&gt; enabled, or have format-on-save turned on in your editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this one is easy to miss
&lt;/h2&gt;

&lt;p&gt;A lot of articles about &lt;code&gt;color-function-notation&lt;/code&gt; talk about the dramatic conversion — &lt;code&gt;rgba(0, 0, 0, 0.7)&lt;/code&gt; turning into &lt;code&gt;rgb(0 0 0 / 0.7)&lt;/code&gt;. Space-separated, slash before alpha, completely different looking. Hard to miss.&lt;/p&gt;

&lt;p&gt;What we got was quieter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Before:&lt;/strong&gt; &lt;code&gt;rgba(0, 0, 0, 0.7)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After:&lt;/strong&gt; &lt;code&gt;rgb(0, 0, 0, 0.7)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same commas. Same numbers. Just the &lt;code&gt;a&lt;/code&gt; missing. In a busy PR review across dozens of files, that's almost invisible.&lt;/p&gt;

&lt;p&gt;And it's not purely cosmetic either. For us the issue showed up as diff noise — but depending on your setup, silent rewrites like this can have downstream effects worth watching for.&lt;/p&gt;

&lt;p&gt;For us honestly the bigger headache was just the diff noise. PR history full of color changes nobody made. Not ideal.&lt;/p&gt;

&lt;h2&gt;
  
  
  One thing to check first
&lt;/h2&gt;

&lt;p&gt;If you're using &lt;code&gt;stylelint-config-standard-scss&lt;/code&gt; — most Angular projects do — this rule is already on inside the preset, set to &lt;code&gt;"modern"&lt;/code&gt;. So even if you never added it yourself it might already be running. Before changing anything, figure out if it's in your own config or coming from the preset. That changes where you need to override it.&lt;/p&gt;

&lt;p&gt;In our case it was explicitly set in our own &lt;code&gt;.stylelintrc&lt;/code&gt;:&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;"extends"&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;"stylelint-config-standard-scss"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rules"&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;"color-function-notation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"legacy"&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;h2&gt;
  
  
  Ways to fix it
&lt;/h2&gt;

&lt;p&gt;There's no one-size-fits-all here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1 — Just turn it off
&lt;/h3&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;"rules"&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;"color-function-notation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&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;Stylelint leaves your color syntax alone entirely. No rewrites, no warnings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good for:&lt;/strong&gt; when you just need the noise to stop right now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Downside:&lt;/strong&gt; mixed syntax sticks around forever if you never come back to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2 — Clean it up properly, separately
&lt;/h3&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;"rules"&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;"color-function-notation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"modern"&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;Set it to &lt;code&gt;"modern"&lt;/code&gt; and do one isolated cleanup PR — just this, nothing else mixed in. Audit your SCSS before running auto-fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good for:&lt;/strong&gt; when you want consistency and have time to do it properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Downside:&lt;/strong&gt; needs some prep work. Don't just flip it and run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 3 — Scope it with &lt;code&gt;overrides&lt;/code&gt;
&lt;/h3&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;"overrides"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"files"&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;"**/*.scss"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"rules"&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;"color-function-notation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&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;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;Keeps the rule active for CSS, disables it for SCSS only. More precise than a global disable and way cleaner than scattering &lt;code&gt;/* stylelint-disable */&lt;/code&gt; comments across your whole project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good for:&lt;/strong&gt; when you want enforcement on CSS but your SCSS theming files need to be left alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Downside:&lt;/strong&gt; bit more config, but honestly manageable.&lt;/p&gt;

&lt;h3&gt;
  
  
  What we did
&lt;/h3&gt;

&lt;p&gt;Went with &lt;code&gt;null&lt;/code&gt;. Stopped the noise, unblocked the team the same day. Will come back with a proper cleanup PR when things settle down. One thing at a time.&lt;/p&gt;

&lt;h2&gt;
  
  
  If it's happening on every save locally
&lt;/h2&gt;

&lt;p&gt;Check VS Code before you go debugging your pipelines.&lt;/p&gt;

&lt;p&gt;The Stylelint extension has this:&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="nl"&gt;"stylelint.autoFixOnSave"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When that's on, &lt;code&gt;--fix&lt;/code&gt; runs silently every single save. Seen teams spend a long time pointing fingers at CI when it was their own editor config the whole time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to know if this is your issue
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Color changes showing up in diffs nobody made&lt;/li&gt;
&lt;li&gt;PR reviews catching &lt;code&gt;rgba&lt;/code&gt; → &lt;code&gt;rgb&lt;/code&gt; changes out of nowhere&lt;/li&gt;
&lt;li&gt;Weird rendering after running &lt;code&gt;stylelint --fix&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check your &lt;code&gt;.stylelintrc&lt;/code&gt;, &lt;code&gt;.stylelintrc.json&lt;/code&gt;, or &lt;code&gt;stylelint.config.js&lt;/code&gt; for &lt;code&gt;color-function-notation&lt;/code&gt;. And check your extended presets too — it might not even be in your own config.&lt;/p&gt;

&lt;h2&gt;
  
  
  tl;dr
&lt;/h2&gt;

&lt;p&gt;Stylelint auto-fix on an inconsistent codebase will rewrite things you didn't ask it to rewrite. The &lt;code&gt;color-function-notation&lt;/code&gt; rule is one of the quieter offenders because the change it makes — &lt;code&gt;rgba&lt;/code&gt; to &lt;code&gt;rgb&lt;/code&gt; — is easy to overlook.&lt;/p&gt;

&lt;p&gt;Check your config, check your presets, and don't run auto-fix blind.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I write about frontend problems from real projects — follow if that's useful.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If this helped, drop a ❤️ — it helps with visibility.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Connect with me:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;LinkedIn: &lt;a href="https://linkedin.com/in/yourlinkedinhandle" rel="noopener noreferrer"&gt;Sanket Bhor&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Website: &lt;a href="https://sanketbhor.dev" rel="noopener noreferrer"&gt;sanketbhor.dev&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>scss</category>
      <category>stylelint</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
