<?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: Garrett Hawkins</title>
    <description>The latest articles on DEV Community by Garrett Hawkins (@hawk-pdx).</description>
    <link>https://dev.to/hawk-pdx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2531404%2F9687c4ed-a796-4dfb-8ab4-b60c61007472.jpeg</url>
      <title>DEV Community: Garrett Hawkins</title>
      <link>https://dev.to/hawk-pdx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hawk-pdx"/>
    <language>en</language>
    <item>
      <title>The Tailwind Tax Nobody Talks About</title>
      <dc:creator>Garrett Hawkins</dc:creator>
      <pubDate>Wed, 14 Jan 2026 22:03:00 +0000</pubDate>
      <link>https://dev.to/hawk-pdx/the-tailwind-tax-nobody-talks-about-2nag</link>
      <guid>https://dev.to/hawk-pdx/the-tailwind-tax-nobody-talks-about-2nag</guid>
      <description>&lt;p&gt;Look, I know what you're thinking. It's 2026, everyone's using Tailwind, and here I am with my external &lt;code&gt;.css&lt;/code&gt; files like some kind of developer fossil. But hear me out.&lt;/p&gt;

&lt;p&gt;I've been working on Next.js projects for a while now, and every few months someone tells me I should really migrate to Tailwind... advice in which I've taken heed and begrudgingly applied to a few projects. The thing is, I keep asking myself: why? What problem am I actually solving?&lt;/p&gt;

&lt;p&gt;(Before you write me off as inflexible: I'm a pragmatist. If I join a team that lives and breathes Tailwind, I'll write Tailwind. I've worked with plenty of tools I didn't initially love. But when I'm choosing for my own projects, I want that choice to be deliberate, not just habitual.)&lt;/p&gt;

&lt;h2&gt;
  
  
  We Already Learned This Stuff
&lt;/h2&gt;

&lt;p&gt;Remember when we all sat down and learned CSS? Flexbox, grid, media queries, the cascade, specificity—all of it. It took time, sure, but we figured it out. Now Tailwind comes along and says "forget all that, learn our utility classes instead."&lt;/p&gt;

&lt;p&gt;Except... it's the same concepts. &lt;code&gt;flex items-center&lt;/code&gt; is just &lt;code&gt;display: flex; align-items: center;&lt;/code&gt; with extra steps. I'm not learning something new, I'm learning a different syntax for something I already know. That feels backwards to me.&lt;/p&gt;

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

&lt;p&gt;Here's where it gets real for me. I've got existing projects. They work. They're styled. Users are happy. &lt;/p&gt;

&lt;p&gt;If I want to jump on the Tailwind train, I'm looking at weeks of work. Going through every component, ripping out class names, replacing them with utility strings, making sure nothing breaks. And for what? So my HTML looks like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Click me
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"btn-primary"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Click me
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't know. That first one makes me tired just looking at it.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's Harder to Change My Mind
&lt;/h2&gt;

&lt;p&gt;Say I decide our primary color needs to change. With my old-school approach, I pop into my CSS file, update one variable or a few declarations, done. With Tailwind, I'm searching through components trying to find every instance of &lt;code&gt;bg-indigo-600&lt;/code&gt; and hoping I don't miss any.&lt;/p&gt;

&lt;p&gt;Yeah, yeah, I know—you can configure the colors in the config file. But then you're mapping semantic names to Tailwind's naming system, and honestly, at that point, didn't we just reinvent CSS custom properties with extra complexity?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Readability Thing
&lt;/h2&gt;

&lt;p&gt;Maybe I'm weird, but when I come back to code six months later, &lt;code&gt;&amp;lt;article className="blog-post"&amp;gt;&lt;/code&gt; tells me something. &lt;code&gt;&amp;lt;article className="max-w-2xl mx-auto px-4 py-8 prose prose-lg"&amp;gt;&lt;/code&gt; just tells me... measurements? &lt;/p&gt;

&lt;p&gt;I want my HTML to describe what things &lt;em&gt;are&lt;/em&gt;, not what they look like. Isn't that what we've been saying for years?&lt;/p&gt;

&lt;h2&gt;
  
  
  Are We Just Chasing Trends?
&lt;/h2&gt;

&lt;p&gt;I wonder sometimes if we've confused "best practices" with "what's popular right now." CSS isn't broken. It's been working for websites since before most of us were developers. &lt;/p&gt;

&lt;p&gt;Tailwind didn't unlock some new capability—it just changed the workflow. And that's fine! If it works for you, great. But I'm starting to think the emperor's new clothes might just be... regular clothes with a hipper marketing team.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Matters
&lt;/h2&gt;

&lt;p&gt;At the end of the day, I ship features. My sites load fast. My styles are maintainable (at least to me). My users don't care whether I used Tailwind or hand-rolled CSS—they care if the button works and the site doesn't look broken on mobile.&lt;/p&gt;

&lt;p&gt;I'm not against new tools. I've adopted plenty over the years. But I am against refactoring for the sake of keeping up with the Joneses. My time is finite. I'd rather spend it building things than rewriting things that already work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maybe There's Room for Both
&lt;/h2&gt;

&lt;p&gt;I'm not trying to convince anyone to ditch Tailwind if you love it. If utility classes make you more productive, then you should absolutely use them. This isn't a holy war.&lt;/p&gt;

&lt;p&gt;I just think we should be honest about the tradeoffs. Tailwind has costs—learning curves, migration overhead, verbosity, coupling between markup and styles. Classic CSS has costs too—naming things is hard, bad stylesheets can become spaghetti, specificity battles are real.&lt;/p&gt;

&lt;p&gt;Pick your poison based on your project, not based on what's trending.&lt;/p&gt;

&lt;h2&gt;
  
  
  So Yeah, I'm Sticking with CSS
&lt;/h2&gt;

&lt;p&gt;Call me old-fashioned if you want. I've made peace with it. While the cool kids are debating whether to use &lt;code&gt;@apply&lt;/code&gt; or pure utilities, I'm over here writing &lt;code&gt;.card { padding: 1rem; background: white; }&lt;/code&gt; and moving on with my life.&lt;/p&gt;

&lt;p&gt;Maybe someday I'll convert. Or maybe in five years we'll all be using something else entirely and this whole debate will seem quaint. &lt;/p&gt;

&lt;p&gt;Until then, my external stylesheet is doing just fine.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What about you? Are you team Tailwind or team classic CSS? Or have you found some other approach entirely? I'm genuinely curious what's working for other people.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>javascript</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>'A Santa at Nasa?!!!!'</title>
      <dc:creator>Garrett Hawkins</dc:creator>
      <pubDate>Fri, 06 Dec 2024 06:05:00 +0000</pubDate>
      <link>https://dev.to/hawk-pdx/a-santa-at-nasa-3p3k</link>
      <guid>https://dev.to/hawk-pdx/a-santa-at-nasa-3p3k</guid>
      <description>&lt;p&gt;Complex problems have always intrigued me. Anything that can take my overactive mind and allow it to… more so, FORCE IT to, temporarily transition to another dimension.&lt;br&gt;
… a world where i can step away from life’s complexities. I.e. pondering the past, working to keep up with the present AND trippin’ on the future!&lt;br&gt;
That being said, I’m not sure solving this algorithm was the brain vacation I was looking for haha.&lt;/p&gt;

&lt;p&gt;While reading up on arithmetic and its place in JavaScript, i came across what’s known as a&lt;br&gt;
‘Palindrome’. Palindromes are a string that when read in reverse, reads the same as it does reading left-to-right.&lt;br&gt;
Initially I thought, how hard can it be?!&lt;br&gt;
My ultimate experience as a ‘Budding Dev Student’ proved the process a bit more involved than original expected but where’s the fun in easy?&lt;/p&gt;

&lt;p&gt;ANYWAYS… Less talking, more doing. &lt;br&gt;
Let’s get on with it! &lt;/p&gt;

&lt;p&gt;As always, I started with a plan. Nothing crazy, just a few words or partial sentences placed in specific order (probably only understood by me). As a relatively new practice I’ve found with larger/more complicated Deliverables, breaking them down to simpler, easier to attain, mini goals take away some of the anxieties of a problem. I put a checkmark next to each goal as it’s been addressed which helps reinforce (really.. ‘trick’) my mind will each small victory!&lt;/p&gt;

&lt;p&gt;OK, for real now…&lt;br&gt;
First, i knew i wanted a descriptive name for my variable, in this attempt, I went with a function. I called it ‘isPalindrome’ in reference to my goal. &lt;/p&gt;

&lt;p&gt;Second, I assigned the function a ‘placeholder’ variable. In this case, ’str’ seemed sufficient.&lt;/p&gt;

&lt;p&gt;With the easy part out the way, I ran in to my first real challenge. I found that I needed to breakdown the problem even further if I was going to make this work. &lt;br&gt;
Back to the drawing board, so to speak. I referred back to my plan and added a couple sub-steps:&lt;/p&gt;

&lt;p&gt;Task number one, convert all characters within the provided string to match ‘case-wise’… I guess I really could have gone either way but I chose the ‘.toLowerCase()’ method.&lt;br&gt;
Sweet! One of two, out the way…. next, one of my challenges was to have the ability to compare strings of any length, to include spaces, sentences, as well as symbols and other non-alphanumeric qualities.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;function ‘isPalindrome’ is created&lt;/li&gt;
&lt;li&gt;function takes placeholder, ‘str’, as input &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;‘alphanumericDelete’ variable is created: This variable will be asked to some things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;# destruct the original string.&lt;/li&gt;
&lt;li&gt;# iterate over each element &lt;/li&gt;
&lt;li&gt;# convert the input string ‘.toLowerCase’ using the built-in method.&lt;/li&gt;
&lt;li&gt;# remove anything that is not a number or letter.
— this process was the most taxing, it required a bit of googling but I was able to find        another built-in regular expression that did exactly what I needed!
— this particular ‘Regex’ uses this syntax, in addition to previous methods to basically      completely destruct each string, convert to an Array, do the work provided in parameters,       ‘join’ all the characters back together and rebuild/output our ‘baby’!
Finally, one last step… after completing our complex requests, it takes the values on         each side of the === qualifier and check to see whether or not they match. 
And by ‘match’ i mean the string on the left (provided string) matches the declared value       on the opposite side of === which applies reverse() to compare the string in… reverse!        Haha, what a concept!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s what I came up with:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function isPalindrome(str) { 
const alphanumericDelete = str.toLowerCase().match(/[a-z0-9]/g);
return alphanumericDelete.join(“”) === alphanumbericDelete.reverse().join(“”);
};  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some test cases:&lt;br&gt;
    console.log(isPalindrome('A man, a plan, a canal: Panama')); // true&lt;br&gt;
    console.log(isPalindrome('race car'));&lt;br&gt;
    console.log(isPalindrome('Was it a car or a cat i saw?'))&lt;br&gt;
    console.log(isPalindrome('A Santa at Nasa?!!!!')&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now it’s your turn! &lt;br&gt;
Copy the included code into your console and try out a word or phrase of your own!&lt;br&gt;
In fact, I challenge you to think one up for yourself… if you’re going to cheat, at least make it something that doesn’t show up in the first few google results :P &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
