<?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: Vincent Romanus</title>
    <description>The latest articles on DEV Community by Vincent Romanus (@vincesanity).</description>
    <link>https://dev.to/vincesanity</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%2F3477292%2Fa9e8663b-468a-4184-b185-a095f57df14f.jpg</url>
      <title>DEV Community: Vincent Romanus</title>
      <link>https://dev.to/vincesanity</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vincesanity"/>
    <language>en</language>
    <item>
      <title>Signals: I Was Wrong. Kinda.</title>
      <dc:creator>Vincent Romanus</dc:creator>
      <pubDate>Mon, 08 Jun 2026 12:35:10 +0000</pubDate>
      <link>https://dev.to/vincesanity/signals-i-was-wrong-kinda-3ac2</link>
      <guid>https://dev.to/vincesanity/signals-i-was-wrong-kinda-3ac2</guid>
      <description>&lt;p&gt;A while ago, I wrote an article called &lt;a href="https://www.vincesanity.io/blog/post/signals-the-enshittification-of-angular" rel="noopener noreferrer"&gt;Signals: The Enshittification of Angular.&lt;/a&gt;And I still agree with a lot of it.&lt;/p&gt;

&lt;p&gt;The first iterations of Signals felt unfinished, awkward and weirdly ideological. Performance issues, endless update loops, another reactive abstraction on top of Angular’s already fragmented architecture and a community suddenly acting like the default was a historical mistake.&lt;/p&gt;

&lt;p&gt;At the time, Signals didn’t feel like Angular becoming simpler. They felt like Angular having an identity crisis. But with the recent updates: Signals work now. The endless update loops from the first iterations seem to be gone, the performance issues are no longer a real concern and Angular finally started building the framework consistently around the concept: &lt;code&gt;httpResource&lt;/code&gt;, forms as signals and the overall direction finally make Angular feel coherent again.&lt;/p&gt;

&lt;p&gt;And that’s the part where I was wrong. Kinda.&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular created a reactivity war
&lt;/h2&gt;

&lt;p&gt;One of Angular’s biggest ironies is that its original default change detection worked perfectly fine for most applications.&lt;/p&gt;

&lt;p&gt;Then the community overwhelmly decided it was unacceptable.&lt;/p&gt;

&lt;p&gt;OnPush, Async pipes, Subjects, manual &lt;code&gt;detectChanges()&lt;/code&gt; everywhere. Entire components looking like handcrafted RxJS operators just to handle a loading state. Angular developers spent too much time writing boilerplate to replicate behavior Angular already handled automatically. And somehow this became “clean architecture”.&lt;/p&gt;

&lt;p&gt;Everyone had a different definition of “proper Angular” and Signals didn’t really introduce a revolutionary new paradigm for me. Just made it look like another Wannabe-React.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signals made Angular coherent again
&lt;/h2&gt;

&lt;p&gt;This is the part I genuinely underestimated. Signals unified Angular’s mental model in a way Angular desperately needed. State changes update the UI. That’s it.&lt;/p&gt;

&lt;p&gt;No async pipe ceremony for synchronous state. No manually triggering change detection because Angular randomly missed another case. No weird “reactive but not reactive enough” social media post every week.&lt;/p&gt;

&lt;p&gt;Signals made a kinda straightforward solution the standard again.And honestly, that alone improved Angular more than most technical features ever could.&lt;/p&gt;

&lt;p&gt;Because for years, Angular’s biggest problem wasn’t really performance. It was that the ecosystem normalized complexity and called it scalability. Signals quietly killed a massive amount of unnecessary abstraction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular didn’t need this shift. The community did.
&lt;/h2&gt;

&lt;p&gt;This is the one thing I still struggle with. I’m still not fully convinced Angular itself needed such a massive architectural shift in the first place. A lot of the problems Signals solved were arguably created by Angular culture itself. Overusing OnPush, pushing reactive purity over developer experience and normalizing increasingly convoluted boilerplate as “enterprise best practice”.&lt;/p&gt;

&lt;p&gt;Angular probably could have solved a large part of this by enforcing simpler standards and better defaults much earlier. Instead, the ecosystem slowly drifted into a place where developers manually optimized everything while recreating behavior the framework already had.&lt;/p&gt;

&lt;p&gt;So maybe Angular didn’t need Signals as much as the community did. Signals became the escape hatch from that complexity. Ironically by introducing another reactive primitive.&lt;/p&gt;

&lt;p&gt;The weird part is that it worked, so I'm not against Signals anymore.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>frontendarchitecture</category>
      <category>frontend</category>
      <category>statemanagement</category>
    </item>
    <item>
      <title>Signals: The Enshittification of Angular</title>
      <dc:creator>Vincent Romanus</dc:creator>
      <pubDate>Fri, 27 Feb 2026 11:43:11 +0000</pubDate>
      <link>https://dev.to/vincesanity/signals-the-enshittification-of-angular-3o09</link>
      <guid>https://dev.to/vincesanity/signals-the-enshittification-of-angular-3o09</guid>
      <description>&lt;p&gt;Let’s start with a term that perfectly captures what’s happening here: &lt;strong&gt;Enshittification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Coined by Cory Doctorow, it describes the slow degradation of a product or platform over time. First, it’s amazing. Then it starts optimizing for growth. Then for platform goals. Then for &lt;em&gt;“strategy”&lt;/em&gt;. Eventually, the thing that made it great gets diluted, replaced, or buried under abstractions nobody asked for.&lt;/p&gt;

&lt;p&gt;It doesn’t break overnight. It erodes.&lt;/p&gt;

&lt;p&gt;And that’s exactly how Angular feels right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular Is Throwing Away Its Superpower
&lt;/h2&gt;

&lt;p&gt;Angular had a superpower. And no, it wasn’t TypeScript. It wasn’t DI. It wasn’t the CLI.&lt;/p&gt;

&lt;p&gt;It was &lt;strong&gt;Zone.js + RxJS + Default Change Detection&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That combination was insane.&lt;/p&gt;

&lt;p&gt;You could write reactive code with RxJS, pipe your streams, bind them in templates, and Angular would just… update the view. No manual state sync. No explicit subscriptions everywhere. No setState. No signal triggers. No reducers. No “please re-render now.”&lt;/p&gt;

&lt;p&gt;Zone.js patched the async boundary and said: &lt;em&gt;“Don’t worry. I got this.”&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  And it worked. Surprisingly performant, too - if you knew what you were doing.
&lt;/h2&gt;

&lt;p&gt;People love to hate on Zone.js because “magic.” But that “magic” eliminated boilerplate. It allowed reactive rendering without introducing a state management framework every five minutes.&lt;/p&gt;

&lt;p&gt;Angular had something no one else had:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt; needed setState (and later 50 state libraries). &lt;strong&gt;Vue&lt;/strong&gt; leaned into its own reactivity system. &lt;strong&gt;Svelte&lt;/strong&gt; compiles it away.&lt;/p&gt;

&lt;p&gt;Angular? It just rendered your damn data.&lt;/p&gt;

&lt;p&gt;RxJS handled data flow. Zone.js handled the async boundary. Change detection did the rest.&lt;/p&gt;

&lt;p&gt;You didn’t need Redux. You didn’t need manual triggers. You didn’t need architectural gymnastics.&lt;/p&gt;

&lt;p&gt;It was enterprise-grade and boring in the best possible way. And now? We’re slowly being told that this wasn’t good enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Massive Architectural Pivot - But For What?
&lt;/h2&gt;

&lt;p&gt;Signals. Server-side rendering. Hydration. Zone-less Angular. Why?&lt;/p&gt;

&lt;p&gt;Angular was never the scrappy &lt;em&gt;“micro-frontend for landing pages”&lt;/em&gt; framework. It was the enterprise beast. The SAP dashboard monster. The internal tooling machine. The multi-team, multi-year platform workhorse. It had an identity.&lt;/p&gt;

&lt;p&gt;Now it feels like it’s chasing something else.&lt;/p&gt;

&lt;p&gt;SSR? Sure. Nice to have. But Angular didn’t dominate because of SEO. It dominated because of structure, stability, and predictability. This architectural shift feels less like evolution and more like insecurity. Instead of doubling down on what made Angular powerful, predictable reactive UI without ceremony, it’s pivoting toward parity with frameworks that already own that space.&lt;/p&gt;

&lt;p&gt;React has owned the fine-grained manual reactivity narrative for years. Svelte owns compiled reactivity. Angular trying to out-react React feels like Apple suddenly deciding to build budget Android clones.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Forced Migration = The Real Shittification Here’s where it gets ugly.
&lt;/h1&gt;

&lt;p&gt;Right now, you can still use Zone.js. You can still use default change detection. You can still write Angular the way it was designed. But read between the lines:&lt;/p&gt;

&lt;p&gt;Zone-less is the future. Signals are the new primitive. Manual control is the direction.&lt;/p&gt;

&lt;p&gt;Did you check Angular? I got wonky. The moment updates don’t behave the same way with zone + default detection, the moment you start having to manually push updates even though you’re using the &lt;em&gt;“old”&lt;/em&gt; model, that’s it. That’s the enshittification moment.&lt;/p&gt;

&lt;p&gt;Because now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You add boilerplate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You introduce manual triggers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You lose the simplicity of &lt;em&gt;“it just works.”&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You risk performance regressions because humans are now responsible for what the runtime handled flawlessly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that’s the irony: Zone.js was criticized for being magic. But the alternative? You become the runtime. Congratulations. You now manage update boundaries yourself. How is that progress?&lt;/p&gt;

&lt;h1&gt;
  
  
  Angular Is Losing Its Identity
&lt;/h1&gt;

&lt;p&gt;Frameworks win by owning a philosophy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt; : explicit, manual, flexible, chaotic. &lt;strong&gt;Svelte&lt;/strong&gt; : compile-time intelligence. &lt;strong&gt;Vue&lt;/strong&gt; : progressive reactivity. &lt;strong&gt;Angular&lt;/strong&gt; : was structured, opinionated, enterprise-stable, reactive without ceremony.&lt;/p&gt;

&lt;p&gt;Signals aren’t bad. SSR isn’t bad. Zone-less isn’t evil. But forcing a shift that invalidates the original design philosophy? That’s where the identity cracks.&lt;/p&gt;

&lt;p&gt;When Apple builds phones, people buy them because they are Apple phones. If Apple suddenly released plastic budget clones trying to beat Xiaomi at its own game, what happens? People who want premium stay confused. People who want cheap buy Xiaomi anyway. You lose both sides. That’s what this feels like.&lt;/p&gt;

&lt;p&gt;Angular is walking toward a space where React and Svelte already have cultural dominance. And when a framework loses its identity, it doesn’t immediately die.&lt;/p&gt;

&lt;p&gt;It slowly becomes… less. Less special. Less distinct. Less obvious.&lt;/p&gt;

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

&lt;p&gt;This isn’t about hating Signals. Just a little.&lt;/p&gt;

&lt;p&gt;It’s about watching a framework abandon the exact design choices that made it powerful.&lt;/p&gt;

&lt;p&gt;Angular didn’t need to be React. It didn’t need to be Svelte. It didn’t need to win the SSR hype cycle.&lt;/p&gt;

&lt;p&gt;It just needed to remain the enterprise reactive beast that didn’t make you manually babysit your view updates.&lt;/p&gt;

&lt;p&gt;Enshittification doesn’t happen because something becomes terrible. It happens because it stops being what made it great.&lt;/p&gt;

&lt;p&gt;And right now? Angular feels like it’s forgetting who it is.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>frontendarchitecture</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Hot Take: AI Didn’t Kill Tailwind’s Business. The Business Model Did.</title>
      <dc:creator>Vincent Romanus</dc:creator>
      <pubDate>Fri, 09 Jan 2026 16:42:16 +0000</pubDate>
      <link>https://dev.to/vincesanity/hot-take-ai-didnt-kill-tailwinds-business-the-business-model-did-3bg4</link>
      <guid>https://dev.to/vincesanity/hot-take-ai-didnt-kill-tailwinds-business-the-business-model-did-3bg4</guid>
      <description>&lt;p&gt;By now, most people in tech have seen it. If not, here’s the &lt;a href="https://github.com/tailwindlabs/tailwindcss.com/pull/2388#issuecomment-3717222957" rel="noopener noreferrer"&gt;full comment&lt;/a&gt;, that sparked a wildfire in the community, where he said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“75% of the people on our engineering team lost their jobs here yesterday because of the brutal impact AI has had on our business. And every second I spend trying to do fun free things for the community like this is a second I'm not spending trying to turn the business around and make sure the people who are still here are getting their paychecks every month.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s unpack that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Tailwinds Business Model?
&lt;/h2&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prebuilt UI components (HTML + Tailwind CSS snippets)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An UI kit for React and/or Headless UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One-time payment, no recurring revenue&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a space with insane competition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Flowbite&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DaisyUI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Preline&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HyperUI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Headless UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TW Elements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TailGrids&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FlyonUI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Meraki UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wind UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ripple UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Material Tailwind&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of these are completely free. So, yeah, you get the idea: if your product is a one-time bundle of copy-pastable HTML, and every mid-level dev can churn out each block in some hours or even minutes... That's not exactly a good long-term strategy in this market.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a 75% Layoff Really Means
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;75%&lt;/strong&gt; layoff sounds catastrophic, until you realize it's about &lt;strong&gt;three&lt;/strong&gt; people. No punchline.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Media Hype Train
&lt;/h2&gt;

&lt;p&gt;Big dev YouTubers like &lt;strong&gt;Theo - t3․gg&lt;/strong&gt; jumped in to declare:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This is one of the first examples of AI immediately causing engineers to lose jobs.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Come on, man. For real?&lt;/p&gt;

&lt;h2&gt;
  
  
  My 2 Cents
&lt;/h2&gt;

&lt;p&gt;Is it still sad? Yes, of course. Tailwind is arguably the most popular UI library in web development right now. But when your entire business sits on a shaky foundation, it doesn’t take AI to pull the rug out. That said, the drama paid off. Tailwind landed a wave of new sponsorships in just a few days: Vercel, Google AI Studio, Theo himself, and loveable.&lt;/p&gt;

&lt;p&gt;Hopefully, they don’t just survive. &lt;strong&gt;But learn something from it too.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Faster, Dumber, Fragile: Welcome to AI-Driven Development in 2025</title>
      <dc:creator>Vincent Romanus</dc:creator>
      <pubDate>Mon, 29 Dec 2025 12:53:39 +0000</pubDate>
      <link>https://dev.to/vincesanity/faster-dumber-fragile-welcome-to-ai-driven-development-in-2025-3goc</link>
      <guid>https://dev.to/vincesanity/faster-dumber-fragile-welcome-to-ai-driven-development-in-2025-3goc</guid>
      <description>&lt;h2&gt;
  
  
  Code faster, ship dumber? The productivity illusion of AI
&lt;/h2&gt;

&lt;p&gt;Remember when the wildest part of software development was a new JavaScript framework every week?&lt;/p&gt;

&lt;p&gt;Now we’ve got Copilot and accomplices auto-completing entire functions. AI tools are everywhere. And according to the headlines, developer productivity is up. 25 percent, 30 percent, 40 percent, depending on who’s selling the story.&lt;/p&gt;

&lt;p&gt;The numbers sound impressive. Studies show teams writing more code, finishing tasks faster, shipping sooner.&lt;/p&gt;

&lt;p&gt;But the closer you look, the messier it gets.&lt;/p&gt;

&lt;p&gt;Nearly &lt;strong&gt;half&lt;/strong&gt; of all developers say they don’t trust AI-generated code. A controlled study found experienced developers actually took 19 percent longer when using AI, not because the code was better, but because they had to double-check every suggestion.&lt;/p&gt;

&lt;p&gt;Another analysis showed that 45 percent of AI-generated code had security flaws.&lt;/p&gt;

&lt;p&gt;And even when the code “works,” it’s often verbose, redundant, or barely maintainable. More code, more bugs, more time spent debugging instead of building. AI doesn't just increase output. It accelerates organizational debt.&lt;/p&gt;

&lt;p&gt;Yet somehow, companies still celebrate velocity as if more lines of code equals progress. Elon Musk once claimed great developers write more code than average ones. Linus Torvalds had a fitting response:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Anybody who thinks that's a valid metric is too stupid to work at a tech company.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's not about writing more code. It’s about writing the right code and trusting that it won’t blow up in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The dangerous myth of “we won’t need developers”&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;AI should revolutionize software development. In 2025, it distorted it.&lt;/p&gt;

&lt;p&gt;Instead of empowering teams, it gave companies an excuse to cut headcount. Layoffs happened. Some of those same engineers got quietly rehired. But the worst shift? Junior developers stopped getting hired at all.&lt;/p&gt;

&lt;p&gt;And that’s not just short-sighted. It’s dangerous.&lt;/p&gt;

&lt;p&gt;The loudest voices claiming “you won’t need to code anymore” are either trying to inflate their AI startup valuation or have never shipped a product past a prototype. Saying developers are obsolete isn't insight. It's grift.&lt;/p&gt;

&lt;p&gt;Even AWS CEO Matt Garman called it out directly. Replacing junior devs with AI, he said, is one of the dumbest ideas he’s ever heard.&lt;/p&gt;

&lt;p&gt;And he backed it up with three reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Juniors adapt faster to AI&lt;/strong&gt; They’re AI and digital natives. They grew up with this tech. Over 55 percent of junior developers use AI tools daily, higher than most senior engineers. They explore, iterate, and learn in public.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;They’re not the cost problem&lt;/strong&gt; Juniors are the cheapest employees on the team. Cutting them doesn’t move the needle on cost, but it guts your ability to grow from within.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No juniors, no pipeline&lt;/strong&gt; You don’t get senior engineers out of nowhere. Without juniors, you lose mentorship, fresh thinking, and future leadership. It's a slow death spiral.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This isn’t theory. Companies that cut junior roles in 2024 are already rehiring offshore or at reduced wages just to keep up. The work didn’t go away. They just convinced themselves it could be automated.&lt;/p&gt;

&lt;p&gt;You don’t build a strong engineering culture by pretending AI is a replacement. You build it by investing in humans and letting AI assist them, not erase them.&lt;/p&gt;

&lt;p&gt;Anyone telling you otherwise is just trying to cash in on the bubble before it bursts.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The death of learning by doing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;AI didn’t just automate boilerplate. It skipped the learning process too, and that’s a problem.&lt;/p&gt;

&lt;p&gt;Developers used to learn by doing. You broke things. You fixed them. You tried the wrong approach, then figured out why it failed. That struggle built context. Judgment. Real problem-solving skills.&lt;/p&gt;

&lt;p&gt;Now? You ask ChatGPT. You accept Copilot’s suggestion. You ship something that works, but you don’t know why.&lt;/p&gt;

&lt;p&gt;We lose the most important developer skill: &lt;strong&gt;engineering intuition.&lt;/strong&gt; The ability to understand problems and choose the best solution based on the current context.&lt;/p&gt;

&lt;p&gt;Without that, you don’t grow. You just copy, paste, and hope for the best.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use It, Don’t Worship It
&lt;/h2&gt;

&lt;p&gt;AI is great for boilerplate, quick fixes, even writing docs. But it doesn’t understand context like we do, and it won’t write long-term code for you or your team. It’s not a tool. &lt;strong&gt;It’s a genie without senses.&lt;/strong&gt; Don’t expect it to understand the world. And don’t forget how to think.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Why You Should Introduce Theming at the Start of Your Project</title>
      <dc:creator>Vincent Romanus</dc:creator>
      <pubDate>Wed, 03 Sep 2025 17:13:00 +0000</pubDate>
      <link>https://dev.to/vincesanity/why-you-should-introduce-theming-at-the-start-of-your-project-2fmc</link>
      <guid>https://dev.to/vincesanity/why-you-should-introduce-theming-at-the-start-of-your-project-2fmc</guid>
      <description>&lt;p&gt;There are design decisions that come back to bite you later. Color is one of them. At the beginning, it always feels like a “later” problem, &lt;em&gt;“Let’s just get it working first.”&lt;/em&gt; Fast-forward a few months, and you’re the poor soul refactoring &lt;code&gt;#0FB9B1&lt;/code&gt; from 17 different files because marketing decided the primary turquoise needs to be 5% darker. Lovely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Theming isn’t a luxury. It’s hygiene.
&lt;/h2&gt;

&lt;p&gt;Theming, the separation of visual styling from component logic, usually gets introduced &lt;em&gt;after&lt;/em&gt; requirements scream loud enough. Light/Dark mode. Whitelabel support. Multi-tenancy. Accessibility. Take your pick.&lt;/p&gt;

&lt;p&gt;But why wait?&lt;/p&gt;

&lt;p&gt;If you &lt;em&gt;know&lt;/em&gt; these things might show up down the line, there’s zero reason not to prep for them from day one. It’s not overengineering. It’s laying down the tracks before the train speeds up.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Practical Starting Point: Color Token Design
&lt;/h2&gt;

&lt;p&gt;Solid theming starts with a system. Not just defining &lt;code&gt;--primary&lt;/code&gt; and calling it a day. You need structure. Context. Semantics.&lt;/p&gt;

&lt;p&gt;This is how you build it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Color Roles
&lt;/h3&gt;

&lt;p&gt;Think in &lt;em&gt;roles&lt;/em&gt;, not &lt;em&gt;colors&lt;/em&gt;. Not “blue,” but “Info.” Not “green,” but “Success.” Your UI communicates states, your tokens should reflect that.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Neutral foundation (e.g., form fields)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;td&gt;Main interactive elements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Info&lt;/td&gt;
&lt;td&gt;Contextual or neutral information&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Success&lt;/td&gt;
&lt;td&gt;Positive outcomes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error&lt;/td&gt;
&lt;td&gt;Validation errors or destructive actions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  State Variants
&lt;/h3&gt;

&lt;p&gt;Colors have states. A button doesn’t look the same when it’s hovered, focused, disabled, or selected, and your system should reflect that.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;Standard visual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Muted&lt;/td&gt;
&lt;td&gt;Disabled or low priority&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Highlight&lt;/td&gt;
&lt;td&gt;Hover/Focus state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;Active/Selected state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Facing&lt;/td&gt;
&lt;td&gt;Text or content on top of the color&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Elevation Levels
&lt;/h3&gt;

&lt;p&gt;Don’t forget backgrounds. Especially when dealing with nested layouts or UI depth, a layered token model is a must.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--level-0: #FFFFFF; /* Default background */
--level-1: #F5F8F9; /* First level nesting */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Selling B2B? Theming Is Non-Negotiable
&lt;/h2&gt;

&lt;p&gt;If your software is meant for multiple clients, especially in the B2B or SaaS world, then theming isn't just a nice-to-have. It's a hard requirement.&lt;/p&gt;

&lt;p&gt;Every customer will want their own logo. Sure. But it won’t stop there. The moment one of them asks for “our brand colors,” you either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Pray they’re close to your default palette, or&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Spend an unholy amount of time building what you should’ve started with: a theme system.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Supporting custom branding at scale means color flexibility is baked into your foundation. When each client gets their own palette, your design system &lt;em&gt;must&lt;/em&gt; decouple style from structure.&lt;/p&gt;

&lt;p&gt;Tokens are your scalable way forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Okay... But What If I Haven’t Done This Yet?
&lt;/h2&gt;

&lt;p&gt;If you’re halfway through a project (or deep into one) and realizing you skipped theming, don’t panic. The good news? You probably don’t need a massive refactor to get back on track. You just need to start &lt;em&gt;now&lt;/em&gt;, and you can do it incrementally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a Theme CSS File
&lt;/h3&gt;

&lt;p&gt;Start by defining your design tokens in a dedicated theme scope — usually tied to a root class like &lt;code&gt;.my-theme&lt;/code&gt; or &lt;code&gt;:root&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.my-theme {
  /* LEVEL */
  --level-0: #ffffff;
  --level-1: #f5f7f9;

  /* BASIC */
  --basic-default: #ffffff;
  --basic-muted: #e9ecef;
  --basic-highlight: #dfe3e7;
  --basic-strong: #b0b8c1;
  --basic-facing: #1c1e21;

  /* PRIMARY */
  --primary-default: #2f5aa8;
  --primary-muted: #d5deef;
  --primary-highlight: #4a73c2;
  --primary-strong: #24488c;
  --primary-facing: #ffffff;

  ...
}

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

&lt;/div&gt;



&lt;p&gt;This becomes your palette, one place to rule all styles.&lt;/p&gt;

&lt;p&gt;And because the structure is consistent, you can now define a new theme and swap with a single class change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.my-dark-theme {
  /* LEVELS */
  --level-0: #1a1a1a;
  --level-1: #252525;

  /* BASIC */
  --basic-default: #2f2f2f;
  --basic-muted: #3a3a3a;
  --basic-highlight: #4c4c4c;
  --basic-strong: #666666;
  --basic-facing: #d0d0d0;

  /* PRIMARY */
  --primary-default: #f72585;
  --primary-muted: #4b1e38;
  --primary-highlight: #fa58aa;
  --primary-strong: #ff7cb8;
  --primary-facing: #e8cce0;
...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Refactor Styles to Use Tokens
&lt;/h3&gt;

&lt;p&gt;Apply the tokens in your core components. Here’s a simple button example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.button-base {
  background-color: var(--basic-default);
  color: var(--basic-facing);

  &amp;amp;.disabled {
    background-color: var(--basic-muted);
  }

  &amp;amp;:not(.disabled) {
    &amp;amp;:hover {
      background-color: var(--basic-highlight);
    }
    &amp;amp;:active {
      background-color: var(--basic-strong);
    }
  }
}

.button-primary {
  background-color: var(--primary-default);
  color: var(--primary-facing);

  &amp;amp;.disabled {
    background-color: var(--primary-muted);
  }

  &amp;amp;:not(.disabled) {
    &amp;amp;:hover {
      background-color: var(--primary-highlight);
    }
    &amp;amp;:active {
      background-color: var(--primary-strong);
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start small, pick high-traffic components like buttons and forms. Over time, your codebase will shift from brittle and hardcoded to flexible and theme-aware.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR: Theming Isn’t a Later Decision
&lt;/h2&gt;

&lt;p&gt;If your product is going to grow, team-wise, feature-wise, or audience-wise, theming from day one is the smarter path. Not for the hype, but for the foundation.&lt;/p&gt;

&lt;p&gt;Start with color tokens. Think in roles and states. Stop seeing your UI as “blue on white,” and start seeing it as “Primary on Level-0.”&lt;/p&gt;

&lt;p&gt;Your future self will thank you. Your future clients will demand it. And let’s be honest, you wanted a &lt;strong&gt;Dark Mode&lt;/strong&gt; anyway.&lt;/p&gt;

</description>
      <category>css</category>
      <category>theming</category>
    </item>
    <item>
      <title>Component Composition vs. Options API: Why Flexibility Always Wins</title>
      <dc:creator>Vincent Romanus</dc:creator>
      <pubDate>Wed, 09 Apr 2025 15:11:52 +0000</pubDate>
      <link>https://dev.to/vincesanity/component-composition-vs-options-api-why-flexibility-always-wins-27fa</link>
      <guid>https://dev.to/vincesanity/component-composition-vs-options-api-why-flexibility-always-wins-27fa</guid>
      <description>&lt;p&gt;In UI development, structure matters — not just what you build, but how you build it. Whether you're designing a basic dashboard or a deeply interactive enterprise app, your approach to UI architecture shapes how quickly you can deliver, how clean your code stays, and how far you can scale before rewrites become necessary.&lt;/p&gt;

&lt;p&gt;Two common patterns dominate the frontend ecosystem: &lt;strong&gt;Component Composition&lt;/strong&gt; and the &lt;strong&gt;Options API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Component Composition, exemplified by Angular Material, encourages building UIs out of small, reusable parts. You compose templates with components, use logic where logic belongs, and work with the full expressive range of the language.&lt;/p&gt;

&lt;p&gt;The Options API — found in libraries like DevExtreme — favors configuration. You describe the structure, behavior, and rules of your UI in a single object tree. It looks clean at first. It’s structured. It’s even tempting.&lt;/p&gt;

&lt;p&gt;But once you move beyond basic setups — into custom interactions, reactive logic, or anything resembling actual business rules — it starts to feel like trying to do origami with steel plates.&lt;/p&gt;

&lt;p&gt;Both models are viable. But only one scales with your brain, not against it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Options API: “Just Configure Everything… If You Can”
&lt;/h2&gt;

&lt;p&gt;Using an Options API feels great right up until you want to do something &lt;em&gt;not&lt;/em&gt; already baked in.&lt;/p&gt;

&lt;p&gt;Take something like DevExtreme’s DataGrid. It’s packed. You don’t write much HTML — just configure options:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dx-data-grid
  [dataSource]="data"
  [columns]="columns"
  [remoteOperations]="true"
  [editing]="{
    mode: 'popup',
    allowUpdating: true,
    allowAdding: true,
    allowDeleting: true
  }"
  [paging]="{ pageSize: 10 }"
&amp;gt;
&amp;lt;/dx-data-grid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool, right? You’ve barely written code and already have sorting, filtering, grouping, paging, exporting, and editing.&lt;/p&gt;

&lt;p&gt;But the deeper you go, the more it feels like you’re writing a spec sheet — not a UI. Here’s what a more “real-world” setup looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dx-data-grid
  [dataSource]="data"
  [columns]="columns"
  [remoteOperations]="true"
  [allowColumnReordering]="true"
  [allowColumnResizing]="true"
  [columnAutoWidth]="true"
  [rowAlternationEnabled]="true"
  [filterRow]="{ visible: true }"
  [searchPanel]="{ visible: true, highlightCaseSensitive: true }"
  [groupPanel]="{ visible: true }"
  [sorting]="{ mode: 'multiple' }"
  [editing]="{
    mode: 'popup',
    allowUpdating: true,
    allowAdding: true,
    allowDeleting: true,
    popup: {
      title: 'Edit Record',
      showTitle: true,
      width: 700,
      height: 525
    }
  }"
  [selection]="{ mode: 'multiple' }"
  [paging]="{ pageSize: 20 }"
  [pager]="{
    showPageSizeSelector: true,
    allowedPageSizes: [10, 20, 50],
    showInfo: true
  }"
  [export]="{ enabled: true, fileName: 'MyDataGridExport' }"
  [stateStoring]="{ enabled: true, type: 'localStorage', storageKey: 'gridState' }"
&amp;gt;
&amp;lt;/dx-data-grid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s &lt;em&gt;just&lt;/em&gt; the grid. And you haven't even touched:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Custom cell rendering (&lt;code&gt;cellTemplate&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asynchronous data validation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Master-detail views&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Virtual scrolling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Infinite scrolling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keyboard navigation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Custom summary calculations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Load indicators&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Command columns&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Predefined column types&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Localization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accessibility configs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not a component anymore. It’s a degree program.&lt;/p&gt;

&lt;p&gt;You’ll find yourself crawling through documentation, Stack Overflow, DevExpress forums — not to find cool tricks, but just to do basic things like “change the icon on the edit button.”&lt;/p&gt;

&lt;p&gt;And yet, when you need to show a tooltip on a disabled context menu item? Still no dice. All this config, and the simple stuff still breaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Two Simple Things Should Work Together — But Don’t
&lt;/h2&gt;

&lt;p&gt;The biggest weakness of an Options API isn't what it &lt;em&gt;can&lt;/em&gt; do — it's what it &lt;em&gt;can't combine&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a textbook example: you want a context menu item that’s disabled, but still shows a tooltip explaining &lt;em&gt;why&lt;/em&gt;. Sounds simple, right? Two basic UI primitives: a menu and a tooltip.&lt;/p&gt;

&lt;p&gt;With a composition-first framework, you’d just write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button
  mat-menu-item
  [disabled]="!isAdmin"
  matTooltip="Only admins can delete"
&amp;gt;
  &amp;lt;mat-icon&amp;gt;delete&amp;lt;/mat-icon&amp;gt;
  Delete
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom. You’re done. The tooltip appears even when the button is disabled. The UX is clear. It behaves exactly as expected.&lt;/p&gt;

&lt;p&gt;Now try the same with DevExtreme’s Options API — specifically &lt;code&gt;dx-context-menu&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dx-context-menu
  [items]="contextMenuItems"
  target="#someElement"
&amp;gt;&amp;lt;/dx-context-menu&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You set up your menu items like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contextMenuItems = [
  {
    text: 'Delete',
    icon: 'trash',
    disabled: true,
    hint: 'Only admins can delete'
  }
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You think the &lt;code&gt;hint&lt;/code&gt; will show up as a tooltip. But it doesn’t. Why? Because the item is disabled, and DevExtreme disables &lt;em&gt;everything&lt;/em&gt; — including pointer events. No hover. No focus. No tooltip. The two components — context menu and tooltip — don’t talk to each other, and there’s no composable escape hatch.&lt;/p&gt;

&lt;p&gt;You can’t just wrap the item in a tooltip component. You can’t move logic into the template — because there &lt;em&gt;is&lt;/em&gt; no template. You’re stuck in config-land, where everything is abstracted, and flexibility is gone.&lt;/p&gt;

&lt;p&gt;The workaround? Either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Enable the item and block interaction with custom logic (gross UX), or&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Abandon the tooltip and hope the user just “gets it” (bad accessibility).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are compromises. All because you tried to combine two basic things that should have worked together.&lt;/p&gt;

&lt;p&gt;That’s not a limitation of context menus. That’s the cost of a tightly-scoped Options API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Component Composition: Build What You Want, How You Want
&lt;/h2&gt;

&lt;p&gt;Now compare that to a compositional approach — like Angular Material, but this could be React, Vue, Svelte, or anything that favors building with components.&lt;/p&gt;

&lt;p&gt;Here’s the same tooltip-on-disabled-button scenario:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button
  mat-menu-item
  [disabled]="!isAdmin"
  matTooltip="Only admins can delete"
&amp;gt;
  &amp;lt;mat-icon&amp;gt;delete&amp;lt;/mat-icon&amp;gt;
  Delete
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No hacks. No weird tricks. It just works.&lt;/p&gt;

&lt;p&gt;Need that in a menu? Easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;mat-menu #menu="matMenu"&amp;gt;
  &amp;lt;button
    mat-menu-item
    [disabled]="!isAdmin"
    matTooltip="Only admins can delete"
  &amp;gt;
    &amp;lt;mat-icon&amp;gt;delete&amp;lt;/mat-icon&amp;gt;
    Delete
  &amp;lt;/button&amp;gt;
&amp;lt;/mat-menu&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Component Composition doesn’t abstract the DOM away from you. It invites you to use it the way it was designed to be used. You write templates. You apply logic. Likewise, you get exactly what you expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tables: Config Orchestration vs. Clean Logic
&lt;/h2&gt;

&lt;p&gt;If you’re still wondering when to use each: let’s talk tables.&lt;/p&gt;

&lt;p&gt;With an options-based grid (again: DevExtreme), it’s all in the setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dx-data-grid
  [dataSource]="users"
  [columns]="columns"
  [editing]="{ mode: 'form', allowUpdating: true }"
  ...
&amp;gt;&amp;lt;/dx-data-grid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works, but you’re forever constrained by what’s in the config model. Want a custom filter? Custom header? Reactive interaction between columns? Prepare to override callbacks, inject raw DOM, or regret your choices.&lt;/p&gt;

&lt;p&gt;With a &lt;code&gt;mat-table&lt;/code&gt;, you build exactly what you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;table mat-table [dataSource]="dataSource" class="mat-elevation-z8"&amp;gt;
  &amp;lt;ng-container *ngFor="let col of displayedColumns" [matColumnDef]="col"&amp;gt;
    &amp;lt;th mat-header-cell *matHeaderCellDef&amp;gt;{{ col }}&amp;lt;/th&amp;gt;
    &amp;lt;td mat-cell *matCellDef="let element"&amp;gt;{{ element[col] }}&amp;lt;/td&amp;gt;
  &amp;lt;/ng-container&amp;gt;

  &amp;lt;tr mat-header-row *matHeaderRowDef="displayedColumns"&amp;gt;&amp;lt;/tr&amp;gt;
  &amp;lt;tr mat-row *matRowDef="let row; columns: displayedColumns"&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Less magic. More freedom. You can customize the rendering, plug in your own sorting logic, paginate however you want — and it all feels like Angular. Not like writing a JSON spec for an alien UI framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use What
&lt;/h2&gt;

&lt;p&gt;Use an &lt;strong&gt;Options API&lt;/strong&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Your backend defines everything: layout, structure, behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want a UI engine, not a UI framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You don’t plan to inject much custom logic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use &lt;strong&gt;Component Composition&lt;/strong&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You’re building anything custom.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want clean separation of concerns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You like being in control of your UI, not negotiating with it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because at scale, composability isn’t just nicer — it’s necessary.&lt;/p&gt;

</description>
      <category>componentcomposition</category>
      <category>optionsapi</category>
      <category>angular</category>
      <category>frontendarchitecture</category>
    </item>
    <item>
      <title>Tailwind: Why I love it but disagree with its creator</title>
      <dc:creator>Vincent Romanus</dc:creator>
      <pubDate>Mon, 03 Feb 2025 00:16:33 +0000</pubDate>
      <link>https://dev.to/vincesanity/tailwind-why-i-love-it-but-disagree-with-its-creator-10p3</link>
      <guid>https://dev.to/vincesanity/tailwind-why-i-love-it-but-disagree-with-its-creator-10p3</guid>
      <description>&lt;p&gt;&lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; has gained immense popularity in the web development community for its customizable CSS framework and extensive utility classes. These utility classes provide developers with the flexibility to create consistent and customized designs for modern and responsive web interfaces. One of the most significant benefits of &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; is that it offers cross-browser support, and most IDEs support &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; plugins for autocompletion.&lt;/p&gt;

&lt;p&gt;One of the most notable features of &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; is &lt;code&gt;@apply&lt;/code&gt;, which merges utility classes and applies them into one CSS class. Combining &lt;a href="https://getbem.com/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt; and &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; through &lt;code&gt;@apply&lt;/code&gt; is awesome, allowing for separation of concerns and ensuring readability, especially with long lists of utility classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn-primary {
  @apply py-2 px-4 rounded-lg;
  @apply text-white bg-blue-500 hover:bg-blue-700;
  @apply focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the creator of &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;, &lt;a href="https://adamwathan.me/" rel="noopener noreferrer"&gt;Adam Wathan&lt;/a&gt;, would disagree with this approach. &lt;a href="https://twitter.com/adamwathan/status/1226511611592085504?lang=en" rel="noopener noreferrer"&gt;He suggests that you should reuse your utility-littered HTML instead of using BEM&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While reusing utility classes can work in some cases, it can make debugging a nightmare in large projects, and it can lead junior dev developer to use &lt;code&gt;!important&lt;/code&gt; when frustrated by implementing nested mutation while not wanting to refactor the huge chunks of utility classes. I have seen that in some projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=ab8RePo5ZYU" rel="noopener noreferrer"&gt;Even when creating components instead of BEM&lt;/a&gt;, &lt;a href="https://tailwindcss.com/docs/utility-first" rel="noopener noreferrer"&gt;Tailwind's Utility-First&lt;/a&gt; approach can be challenging to use when there are variations involved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{type === “primary” ? 
  &amp;lt;button className=“py-2 px-4 rounded-lg shadow-md focus:outline-none focus:ring-2 focus:ring-opacity-75 bg-blue-500 text-white hover:bg-blue-700 focus:ring-blue-400”&amp;gt;
    Do it
  &amp;lt;/button&amp;gt; : 
  null
}
{type === “secondary” ? 
  &amp;lt;button className=“py-2 px-4 rounded-lg shadow-md focus:outline-none focus:ring-2 focus:ring-opacity-75 bg-purple-500 text-white hover:bg-purple-700 focus:ring-purple-400”&amp;gt;
    Do it
  &amp;lt;/button&amp;gt; : 
  null
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;@apply&lt;/code&gt; with &lt;a href="https://getbem.com/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt; makes things much simpler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.btn {
  @apply py-2 px-4 text-white rounded-lg outline-none ring-2 ring-opacity-75;
  &amp;amp;.btn-primary {
    @apply bg-blue-500 hover:bg-blue-700 focus:ring-blue-400;
  }
  &amp;amp;.btn-secondary {
    @apply bg-purple-500 hover:bg-purple-700 focus:ring-purple-400;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In summary, just using &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; utility classes can significantly speed up projects, but for big projects with heavy nesting, components with variations, or white labeling, combining &lt;a href="https://getbem.com/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt; and &lt;code&gt;@apply&lt;/code&gt; is a better approach.&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>css</category>
    </item>
    <item>
      <title>HTMX: The Minimalist Challenger of Angular, React, and Vue.js</title>
      <dc:creator>Vincent Romanus</dc:creator>
      <pubDate>Mon, 03 Feb 2025 00:02:01 +0000</pubDate>
      <link>https://dev.to/vincesanity/htmx-the-minimalist-challenger-of-angular-react-and-vuejs-2d4l</link>
      <guid>https://dev.to/vincesanity/htmx-the-minimalist-challenger-of-angular-react-and-vuejs-2d4l</guid>
      <description>&lt;p&gt;In the dynamic world of web development, where complexity often reigns supreme, a minimalist contender is making waves: HTMX. This lightweight library is gaining traction among developers who crave simplicity and minimalism. As the community splits between those who rely on robust frameworks like Angular, React, and Vue.js, and those embracing minimalism, HTMX stands out as a beacon of hope. The cure of JavaScript fatigue and what REST actually should be, an “architectural style for distributed hypermedia systems”.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is HTMX
&lt;/h2&gt;

&lt;p&gt;HTMX, short for HyperText Markup eXtensions, is a JavaScript library that allows developers to build modern web applications using simple HTML attributes. It was created by Carson Gross, who envisioned a return to the simplicity of the early web, where HTML was king, and complexity was minimized.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interactivity Through HTML:&lt;/strong&gt; HTMX leverages HTML attributes to handle AJAX requests, CSS transitions, WebSockets, and server-sent events. This approach reduces the need for complex JavaScript code, making development faster and more intuitive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No Build Step:&lt;/strong&gt; Unlike major frameworks that often require extensive build processes and toolchains, HTMX operates directly within the browser. This makes it ideal for rapid prototyping and smaller projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Progressive Enhancement:&lt;/strong&gt; HTMX embraces the principle of progressive enhancement, allowing developers to add interactive features to existing web pages without a complete rewrite. This makes it a powerful tool for incremental upgrades.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See more on &lt;a href="https://htmx.org/" rel="noopener noreferrer"&gt;htmx.org&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Origins and Philosophy
&lt;/h3&gt;

&lt;p&gt;HTMX is inspired by the Hypermedia as the Engine of Application State (HATEOAS) concept from RESTful APIs. It was born out of a desire to simplify web development, reducing the reliance on heavy JavaScript frameworks. Carson Gross and the HTMX community advocate for a web where HTML, CSS, and a minimal amount of JavaScript can achieve dynamic, responsive interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  The HTMX Hype
&lt;/h2&gt;

&lt;p&gt;The minimalist approach of HTMX has struck a chord with a growing number of developers, especially Backend developers and Go Evangelists. No more huge JavaScript frameworks or libs, just HTML with some attributes. No more discussion about how the JSON output should look like, so the API can be consumed as convenient as possible but is sustainable and extendable. Some even question if JSON was ever a good direction for RESTful APIs.&lt;/p&gt;

&lt;p&gt;Adding to its allure is the playful and often cheeky presence of HTMX on social media. &lt;a href="https://twitter.com/htmx_org" rel="noopener noreferrer"&gt;The official HTMX Twitter account&lt;/a&gt; has gained a reputation for its witty and sometimes trolling tweets, engaging with the community in a humorous and relatable way. This not only adds to the hype but also humanizes the technology, making it more approachable and fun. The excitement around HTMX isn't just limited to developers in forums and social media. Big-name developers on YouTube, like &lt;a href="https://www.youtube.com/@ThePrimeTimeagen/search?query=htmx" rel="noopener noreferrer"&gt;ThePrimeTime&lt;/a&gt; and &lt;a href="https://www.youtube.com/@t3dotgg/search?query=htmx" rel="noopener noreferrer"&gt;Theo - t3․gg&lt;/a&gt;, have given HTMX and its creator a stage, showcasing its capabilities and simplicity in their videos. Their endorsements have significantly amplified the buzz, introducing HTMX to a broader audience and validating its potential in the eyes of many in the web development community.&lt;/p&gt;

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

&lt;p&gt;HTMX is carving out a niche in the web development world, challenging the dominance of traditional and heavy JavaScript frameworks with its minimalist philosophy. It offers a refreshing, but traditional approach for developers looking to simplify their workflows and create efficient, interactive applications without the bloat.&lt;/p&gt;

&lt;p&gt;Whether you are a seasoned developer entrenched in the world of Angular, React, and Vue.js, or a newcomer seeking a simpler way to build, HTMX presents an intriguing option.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Take on HTMX
&lt;/h2&gt;

&lt;p&gt;Despite the growing buzz and its promising features, HTMX currently has a relatively small community. While the tight-knit community fosters innovation and direct support, it also means that best practices for essential aspects such as routing, templating/components, form validation, state handling, and inter-component event handling are not established yet.&lt;/p&gt;

&lt;p&gt;An exciting development is the ongoing enhancement of HTML itself. As HTML continues to implement basic JavaScript use cases like accordions and dialogs, this would be a massive boost for HTMX, potentially expanding its capabilities even more and reducing the need for JavaScript for basic functionality.&lt;/p&gt;

&lt;p&gt;However, given the current state of HTMX, I wouldn't recommend using it for large-scale projects just yet. The time spent creating concepts and solutions for HTMX might outweigh the benefits, especially when such solutions are readily available in major frameworks like Angular, React, and Vue.js.&lt;/p&gt;

&lt;p&gt;That said, I am keenly watching the evolution of HTMX. It holds great revolting promise, and I will certainly be using it for small projects and prototyping.&lt;/p&gt;

</description>
      <category>backenddevelopment</category>
      <category>frontend</category>
      <category>htmx</category>
    </item>
    <item>
      <title>How Instagram fails at jobs to be done</title>
      <dc:creator>Vincent Romanus</dc:creator>
      <pubDate>Sun, 30 Apr 2023 10:26:37 +0000</pubDate>
      <link>https://dev.to/vincesanity/how-instagram-fails-at-jobs-to-be-done-3emo</link>
      <guid>https://dev.to/vincesanity/how-instagram-fails-at-jobs-to-be-done-3emo</guid>
      <description>&lt;p&gt;If you're unfamiliar with the concept of "jobs to be done," it refers to the needs that people have that a product should fulfill. For example, the job of a spoon is to make it easy to consume soup, but it shouldn't be expected to provide Wi-Fi. Conversely, a negative example would be a coffee mug that leaks or is difficult to hold. If a product fails to fulfill its job to be done, it can result in user dissatisfaction and a decline in popularity. That's a pretty simplification, for a deeper dive you can watch &lt;a href="https://www.youtube.com/watch?v=Stc0beAxavY" rel="noopener noreferrer"&gt;Clay Christensen: The Jobs to be Done Theory.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the case of &lt;a href="https://www.instagram.com/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;, its job is to provide a platform for visual artists to showcase their work and for users to discover new artists whose style they enjoy. However, &lt;a href="https://www.instagram.com/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; has shifted its focus to competing with platforms like Snapchat and TikTok, even though they fulfill completely different jobs. &lt;a href="https://www.instagram.com/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; now requires creators to make short videos (Reels), similar to &lt;a href="https://www.tiktok.com/" rel="noopener noreferrer"&gt;TikTok's&lt;/a&gt;. This move has alienated creators and compromised the platform's original job of being a creator and shared-interest platform.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.instagram.com/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; shift has caused issues for creators and users alike. The algorithm is poorly designed, and Reels are often just reposts or screen captures of TikTok videos. Major updates often result in backlash from users and are eventually reverted. The shop feature is underutilized, and &lt;a href="https://www.instagram.com/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; seems to be burning through money without understanding its job to be done.&lt;/p&gt;

&lt;p&gt;While &lt;a href="https://www.instagram.com/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; is currently too big to fail, it's also in a fragile state. By focusing on fulfilling its original job to be done as a creator and shared-interest platform, &lt;a href="https://www.instagram.com/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; could re-engage creators and users and improve its overall functionality.&lt;/p&gt;

</description>
      <category>instagram</category>
      <category>tiktok</category>
      <category>productvision</category>
    </item>
  </channel>
</rss>
