<?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: Dan Walsh</title>
    <description>The latest articles on DEV Community by Dan Walsh (@danwalsh).</description>
    <link>https://dev.to/danwalsh</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%2F538088%2F0afffc30-2be2-46e9-a105-b445ac41d892.jpg</url>
      <title>DEV Community: Dan Walsh</title>
      <link>https://dev.to/danwalsh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danwalsh"/>
    <language>en</language>
    <item>
      <title>[SOLVED] Vue 3 + TypeScript + Inlay Hint support in NeoVim</title>
      <dc:creator>Dan Walsh</dc:creator>
      <pubDate>Tue, 19 Nov 2024 03:45:52 +0000</pubDate>
      <link>https://dev.to/danwalsh/solved-vue-3-typescript-inlay-hint-support-in-neovim-53ej</link>
      <guid>https://dev.to/danwalsh/solved-vue-3-typescript-inlay-hint-support-in-neovim-53ej</guid>
      <description>&lt;p&gt;It would be an understatement to say that getting stable Vue 3 language server support in &lt;a href="https://neovim.io" rel="noopener noreferrer"&gt;NeoVim&lt;/a&gt; over the last 9-12 months has been smooth sailing for me, as evidenced by this lengthy GitHub issue: &lt;a href="https://github.com/williamboman/mason-lspconfig.nvim/issues/371" rel="noopener noreferrer"&gt;volar v2 no longer works&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'd almost given up on finding "the right" solution. Everywhere I looked, others had "solved" the issue in different ways: they were using the &lt;a href="https://github.com/yioneko/vtsls" rel="noopener noreferrer"&gt;vtsls&lt;/a&gt; TypeScript LSP wrapper instead of &lt;a href="https://github.com/typescript-language-server/typescript-language-server" rel="noopener noreferrer"&gt;ts_ls&lt;/a&gt;, or they were using &lt;a href="https://dev.tovtsls"&gt;coc.nvim&lt;/a&gt;, or the now-archived &lt;a href="https://github.com/jose-elias-alvarez/null-ls.nvim" rel="noopener noreferrer"&gt;null-ls.nvim&lt;/a&gt;. But nowhere could I simply find a reliable configuration for a Vue language server configured natively in NeoVim.&lt;/p&gt;

&lt;p&gt;But today, I've finally got it working, and it looks like it should be for good. &lt;strong&gt;Massive thanks to &lt;a href="https://github.com/johnsoncodehk" rel="noopener noreferrer"&gt;Johnson Chu&lt;/a&gt; and &lt;a href="https://github.com/GR3YH4TT3R93" rel="noopener noreferrer"&gt;GR3YH4TT3R93&lt;/a&gt;.&lt;/strong&gt; 👏&lt;/p&gt;

&lt;p&gt;Now I can finally say:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvskqiwuc33bkawf4luz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvskqiwuc33bkawf4luz.gif" alt="Frodo from Lord of the Rings saying, " width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR, just gimme the config so I can write some sweet Vue code with that LSP-goodness
&lt;/h2&gt;

&lt;p&gt;Since you asked so nicely, sure. Here are the &lt;code&gt;volar&lt;/code&gt; and &lt;code&gt;ts_ls&lt;/code&gt; server configs for &lt;code&gt;nvim-lspconfig&lt;/code&gt;. If you're using something like &lt;a href="https://github.com/nvim-lua/kickstart.nvim" rel="noopener noreferrer"&gt;kickstart.nvim&lt;/a&gt;, you'll want to add these entries to your &lt;code&gt;servers&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;servers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;-- Vue 3        &lt;/span&gt;
  &lt;span class="n"&gt;volar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="c1"&gt;-- TypeScript&lt;/span&gt;
  &lt;span class="n"&gt;ts_ls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;filetypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'typescript'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'javascript'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'javascriptreact'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'typescriptreact'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'vue'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;init_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;plugins&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'@vue/typescript-plugin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdpath&lt;/span&gt; &lt;span class="s1"&gt;'data'&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="s1"&gt;'/mason/packages/vue-language-server/node_modules/@vue/language-server'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;languages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'vue'&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;span class="c1"&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 for bonus points, here's the config if you want &lt;a href="https://gpanders.com/blog/whats-new-in-neovim-0.10/#lsp-inlay-hints" rel="noopener noreferrer"&gt;inlay hints&lt;/a&gt;. For this to work we need to disable hybrid mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;servers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;-- Vue 3        &lt;/span&gt;
  &lt;span class="n"&gt;volar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;init_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;vue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;hybridMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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="n"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;typescript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;inlayHints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;enumMemberValues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="n"&gt;functionLikeReturnTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="n"&gt;propertyDeclarationTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="n"&gt;parameterTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;suppressWhenArgumentMatchesName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="n"&gt;variableTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;-- TypeScript&lt;/span&gt;
  &lt;span class="n"&gt;ts_ls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;init_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;plugins&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="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'@vue/typescript-plugin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdpath&lt;/span&gt; &lt;span class="s1"&gt;'data'&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="s1"&gt;'/mason/packages/vue-language-server/node_modules/@vue/language-server'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;languages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'vue'&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="n"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;typescript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;tsserver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;useSyntaxServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;inlayHints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;includeInlayParameterNameHints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'all'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;includeInlayParameterNameHintsWhenArgumentMatchesName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;includeInlayFunctionParameterTypeHints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;includeInlayVariableTypeHints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;includeInlayVariableTypeHintsWhenTypeMatchesName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;includeInlayPropertyDeclarationTypeHints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;includeInlayFunctionLikeReturnTypeHints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;includeInlayEnumMemberValueHints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;span class="c1"&gt;-- ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: this assumes you are using &lt;a href="https://github.com/williamboman/mason.nvim" rel="noopener noreferrer"&gt;mason.nvim&lt;/a&gt; to install and manage your LSPs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With that in place, you should be able to do all the good things: code completion, go to definitions, rename symbols across files, and tell your co-workers you use NeoVim btw.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wxnfap6kjngg9xe5vrw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wxnfap6kjngg9xe5vrw.gif" alt="Winning" width="480" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So how did we get here?
&lt;/h2&gt;

&lt;p&gt;I'm glad you asked.&lt;/p&gt;

&lt;p&gt;The previous Vue language server versions &lt;strong&gt;Vetur&lt;/strong&gt; and &lt;strong&gt;Volar v1&lt;/strong&gt; were both troubled with memory duplication issues and the additional complexity of requiring the &lt;strong&gt;TypeScript Vue Plugin&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Both the TypeScript language server and the Vue language server were creating duplicate TypeScript abstract syntax trees (AST) in memory, which scaled with the size of your project.&lt;/p&gt;

&lt;p&gt;While the TypeScript Vue Plugin had neat features like renaming symbols across &lt;code&gt;.ts&lt;/code&gt; and &lt;code&gt;.vue&lt;/code&gt; files, it added yet another layer of memory usage.&lt;/p&gt;

&lt;p&gt;All of this lead to performance issues and tooling trade-offs, amounting to a sub-optimal development environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution at last
&lt;/h2&gt;

&lt;p&gt;However, through much hard work and determination, Volar's author &lt;a href="https://github.com/johnsoncodehk" rel="noopener noreferrer"&gt;Johnson Chu&lt;/a&gt; delivered Volar v2 and a new "Hybrid mode" which solves these problems!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/johnsoncodehk/62580d04cb86e576e0e8d6bf1cb44e73" rel="noopener noreferrer"&gt;Johnson has a great write up on the history of these issues&lt;/a&gt;, including some useful visual aids. I would highly recommend you read it.&lt;/p&gt;

&lt;p&gt;And it was &lt;a href="https://github.com/GR3YH4TT3R93" rel="noopener noreferrer"&gt;GR3YH4TT3R93&lt;/a&gt;'s support and patience in &lt;a href="https://github.com/williamboman/mason-lspconfig.nvim/issues/371" rel="noopener noreferrer"&gt;this GitHub issue thread&lt;/a&gt;, helping find the right configuration to support not just the newly released Volar v2, but inlay hint support as well.&lt;/p&gt;

</description>
      <category>neovim</category>
      <category>vue</category>
      <category>vim</category>
      <category>typescript</category>
    </item>
    <item>
      <title>TailwindCSS is great; why so much hate?</title>
      <dc:creator>Dan Walsh</dc:creator>
      <pubDate>Thu, 02 Feb 2023 00:35:36 +0000</pubDate>
      <link>https://dev.to/danwalsh/tailwindcss-is-great-why-so-much-hate-ink</link>
      <guid>https://dev.to/danwalsh/tailwindcss-is-great-why-so-much-hate-ink</guid>
      <description>&lt;p&gt;I see &lt;em&gt;way&lt;/em&gt; too many articles about why TailwindCSS is bad, or wrong, or bloated, or [insert-your-negative-adjective-here]. Absolutely, you should follow the rule &lt;strong&gt;"Horses for courses"&lt;/strong&gt;—use the &lt;em&gt;right&lt;/em&gt; tool for the &lt;em&gt;right&lt;/em&gt; job. But the majority of these articles (that I've read) seem to repeat the same anti-utility-CSS talking points such as "HTML bloat" and "repetition is bad".&lt;/p&gt;

&lt;p&gt;Let's respond to one such article, by &lt;a href="https://dev.to/gravy59"&gt;@gravy59&lt;/a&gt;. You should read their &lt;a href="https://dev.to/gravy59/tailwind-css-a-critique-2hfh"&gt;original post&lt;/a&gt; in full.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚨 Before we jump in
&lt;/h2&gt;

&lt;p&gt;Please read this with the intention that it was written, &lt;strong&gt;as a rebuttal to the original post&lt;/strong&gt;. The goal here is to provide devs (both starting-out and experienced) with multiple views on a topic, so they can make more informed decisions about the technologies and practices they choose to invest their time in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤦‍♂️ Atomic classes are essentially inline styles
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Tailwind's config file allows you to create any number of CSS properties, and their new JIT arbitrary values are essentially inline css&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;This is false.&lt;/strong&gt; &lt;a href="https://tailwindcss.com/docs/adding-custom-styles#using-arbitrary-values" rel="noopener noreferrer"&gt;Arbitrary values&lt;/a&gt; (and even arbitrary properties and variants, for that matter) are superior to inline styles in that you can use modifiers such as &lt;code&gt;hover:&lt;/code&gt; or even media queries, all without having to leave your HTML. Is it recommended that you use arbitrary values/properties/variants liberally? No—you should stick with your preconfigured design system wherever possible. This is a niche tool for things such as unique design elements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This can sometimes result in massive, bloated class names that are not that better than inline styles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again, as above, it is unfair to conflate inline styles with class names. And if you're struggling to read your TailwindCSS class names, make sure you have the &lt;a href="https://tailwindcss.com/blog/automatic-class-sorting-with-prettier" rel="noopener noreferrer"&gt;Prettier class sorting extension&lt;/a&gt; installed.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤦‍♂️ BEM is a better choice for reusable components
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Tailwind isn't as friendly to reusable components compared to something like BEM.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I would argue that BEM works &lt;em&gt;against&lt;/em&gt; reusable components&lt;/strong&gt;, in that at its core you are required to name "things"; arguably one of the most difficult and time consuming things a dev might have to do. Unless you have thought through every possible abstraction and mutation of your technical requirements, you're going to run into cascading and inheritance issues.&lt;/p&gt;

&lt;p&gt;Moreover, BEM can lead to premature abstraction and the creation of unique single-use modifier classes to target edge cases. &lt;a href="https://www.freecodecamp.org/news/in-defense-of-utility-first-css-4f406acee6fb/#-bem-is-enough-" rel="noopener noreferrer"&gt;Sarah Dayan has a great write up on this&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤦‍♂️ Repetition is bad
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Their solutions are flimsy at best. They recommend that you&lt;br&gt;
A) Use a framework, which not all developers want to do, or&lt;br&gt;
B) extract styles with their &lt;a class="mentioned-user" href="https://dev.to/apply"&gt;@apply&lt;/a&gt; directive, which do anything about the problem Tailwind was intended to solve.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Don't forget the &lt;em&gt;very first&lt;/em&gt; solution in their documentation: &lt;a href="https://tailwindcss.com/docs/reusing-styles#using-editor-and-language-features" rel="noopener noreferrer"&gt;Using editor and language features&lt;/a&gt;.&lt;/strong&gt; IDE tools such as multi-cursor editing and language template loops are powerful and quick enough to deal with repetition. Selecting the class and pressing Cmd+D or Ctrl+D a few times on your keyboard is super simple, effective and, in most cases, all you need:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hjo7r92p176yjfrevob.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hjo7r92p176yjfrevob.gif" alt="A code IDE demonstrating how to quickly edit class names using multi-cursor selection" width="482" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤦‍♂️ Avoid HTML file-size bloat at all costs
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The first solution works fine from a workflow standpoint, but at compile time you're still left with bloated class names (even if Tailwind purges unused css) that in some cases can balloon file sizes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is another one of those myths that keeps circling the drain, but threatens to linger on forever more. &lt;a href="https://www.freecodecamp.org/news/in-defense-of-utility-first-css-4f406acee6fb/#-it-bloats-the-html-" rel="noopener noreferrer"&gt;Sarah covers the "HTML class names bloat" myth succinctly in her article&lt;/a&gt;. The TL;DR version is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gzip was made to handle duplicate strings.&lt;/li&gt;
&lt;li&gt;Trimming your HTML classes will make little to no difference in your final request size.&lt;/li&gt;
&lt;li&gt;"HTML bloat" doesn't matter, but "CSS bloat" does.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📣 Don't take my word for it
&lt;/h2&gt;

&lt;p&gt;I would highly recommend you subscribe to and check out &lt;a href="https://dev.to/t3dotgg"&gt;Theo's&lt;/a&gt; content on &lt;a href="https://www.youtube.com/@t3dotgg" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;. Theo is a massive advocate for TailwindCSS, and for good reason.&lt;/p&gt;

&lt;p&gt;Below is just one of his videos debunking TailwindCSS myths and providing his sound reasoning for continuing to use it to implement his design systems:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/QBajvZaWLXs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  👍 At the end of the day, use what works
&lt;/h2&gt;

&lt;p&gt;I've said it before and I'll say it again: &lt;strong&gt;"Horses for courses"&lt;/strong&gt; 🏇&lt;/p&gt;

&lt;p&gt;Sometimes, TailwindCSS is going to be a great tool for the job, maybe even the best tool. Other times, plain CSS is going to do the trick nicely, or perhaps a CSS superset like SCSS. Or maybe Styled Components are going to deliver greater "bang for buck", given your project's technical requirements.&lt;/p&gt;

&lt;p&gt;Ultimately, use what works for you, and for your project. But let's make sure we're not misrepresenting the tools we choose &lt;em&gt;not&lt;/em&gt; to use.&lt;/p&gt;

&lt;p&gt;Peace 🕊️&lt;/p&gt;

</description>
      <category>crypto</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>I thought I'd share two dev wallpapers with you</title>
      <dc:creator>Dan Walsh</dc:creator>
      <pubDate>Fri, 25 Nov 2022 13:24:34 +0000</pubDate>
      <link>https://dev.to/danwalsh/i-thought-id-share-two-dev-wallpapers-with-you-10eg</link>
      <guid>https://dev.to/danwalsh/i-thought-id-share-two-dev-wallpapers-with-you-10eg</guid>
      <description>&lt;p&gt;Felt randomly inspired to create a couple of JavaScript-based wallpapers this evening, and I thought that I might post them here for you guys. I used the fantastic website &lt;a href="https://ray.so/" rel="noopener noreferrer"&gt;https://ray.so/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;They're a bit on the philosophical side, a little bit whimsical, so take them as they are.&lt;/p&gt;

&lt;p&gt;I hope your coding projects are inspiring you in new and wonderful ways ✌️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;practice-makes-better.js&lt;/strong&gt; &lt;a href="https://imgur.com/a/HMzaHtI" rel="noopener noreferrer"&gt;(Download hi-res)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8i3bl4qnqijzmjie4cu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8i3bl4qnqijzmjie4cu.png" alt="Image description" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;life-event-handler.js&lt;/strong&gt; &lt;a href="https://imgur.com/a/2Y9oqLT" rel="noopener noreferrer"&gt;(Download hi-res)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdbyttf610bm9zicpmof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdbyttf610bm9zicpmof.png" alt="Image description" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>showdev</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Why FontAwesome is still awesome</title>
      <dc:creator>Dan Walsh</dc:creator>
      <pubDate>Wed, 08 Jun 2022 01:54:42 +0000</pubDate>
      <link>https://dev.to/danwalsh/why-fontawesome-is-still-awesome-2bo</link>
      <guid>https://dev.to/danwalsh/why-fontawesome-is-still-awesome-2bo</guid>
      <description>&lt;p&gt;I read an &lt;a href="https://dev.to/rockykev/im-officially-done-with-fontawesome-2h2f"&gt;interesting post&lt;/a&gt; in which the author stated the reasons why they were officially done with &lt;a href="https://fontawesome.com/" rel="noopener noreferrer"&gt;FontAwesome&lt;/a&gt;. I was intrigued, given I use FontAwesome in all my projects and feel that I am familiar enough with its various implementations.&lt;/p&gt;

&lt;p&gt;To my surprise, the reasons provided all revolved around one core issue—&lt;em&gt;improper production implementation&lt;/em&gt;. It seemed a little unfair to negatively review FontAwesome as a whole based on improper or impractical implementations. That would be like giving negative reviews to a toaster manufacturer because lots of people set up their toasters in their bathrooms (and were met with unfortunate accidents). It’s not a failing of the manufacturer...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtn068ou5icdr19d30t9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtn068ou5icdr19d30t9.gif" alt="Hmm..."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FontAwesome can be implemented in many ways such as using &lt;a href="https://fontawesome.com/docs/web/setup/use-kit" rel="noopener noreferrer"&gt;Kits&lt;/a&gt;, downloading and hosting the SVG files, and my personal favourite: importing the FontAwesome npm packages into your project and using the &lt;a href="https://fontawesome.com/docs/web/use-with/react/add-icons#add-icons-globally" rel="noopener noreferrer"&gt;Library&lt;/a&gt; for selective icon importing.&lt;/p&gt;

&lt;p&gt;Developers should rarely be hosting and linking the entire suite of FontAwesome CSS files in a production application or site (unless they are happy to accept the pitfalls that go along with it, or if it's necessitated by the project's requirements). But to be clear: this is not the optimum nor the recommended implementation approach, and as such, &lt;em&gt;it shouldn’t be used as the yard stick to measure the practicality and usefulness of FontAwesome as a whole&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4lpa618ot1hwr560lyy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4lpa618ot1hwr560lyy.gif" alt="Don't do this"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's address the points in the &lt;a href="https://dev.to/rockykev/im-officially-done-with-fontawesome-2h2f"&gt;original post&lt;/a&gt;...&lt;/p&gt;




&lt;h2&gt;
  
  
  🙅‍♂️ Myth #1: Managing versions is nightmare
&lt;/h2&gt;

&lt;p&gt;The premise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[You're] building a website in 2018, you may have used FontAwesome 5. [...] Let's say you need a gameboy icon. [...] But it doesn't work. Here's all the reasons why.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here we go...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;REASON 1:&lt;/strong&gt; You're on FontAwesome 5.0. And this is on FontAwesome 5.11.0.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If implemented as project dependencies using npm, a quick update to your FontAwesome packages will provide you with all the latest icons.&lt;/p&gt;

&lt;p&gt;Alternatively, if you've implemented a Kit, all of the latest icons will be available to you, based on your selected version. You easily can check and update the version of your Kit by logging into your FontAwesome account.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;REASON 2:&lt;/strong&gt; This is a 'pro' font. You're using a free version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When searching for icons to use on the FontAwesome website, &lt;a href="https://fontawesome.com/search?m=free" rel="noopener noreferrer"&gt;just click on the “Free” filter&lt;/a&gt; so you only list the icons available to your project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;REASON 3:&lt;/strong&gt; You've been importing solid versions of fonts. You should You need the light versions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So then install the light-style npm package and import the icons you need. &lt;/p&gt;

&lt;p&gt;Better yet, if you've implemented FontAwesome as a Kit, then you automatically have access to &lt;em&gt;every single icon style&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcfaap3qx1gxy6zwpdao.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcfaap3qx1gxy6zwpdao.gif" alt="Mic drop"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🙅‍♂️ Myth #2 - You import thousands of unused icons
&lt;/h2&gt;

&lt;p&gt;The premise: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How many icons are you really using on your site? Maybe 6 or 7? Most sites (and I'm speaking from my own background) only use a handful of icons. [...] If you're importing a fontAwesome's regular.css, you're bringing in hundreds of fonticons you don't need. It's even more nightmare-ish if you're getting a circle-question icon (which lives in regular.css) AND a Facebook icon (which lives in brands.css). Now there's thousands of fonts imported... all eating bandwidth.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again, if set up optimally, only the very few imported icons you are actually using (and their supporting CSS styles) are added to your final transpiled build files.&lt;/p&gt;

&lt;p&gt;Reading further:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Defenders may say, "Well you can tree-shake it" or "optimize it".&lt;/p&gt;

&lt;p&gt;And you're right! So... how many devs even know to do that or have the gumption to set that up?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some common ground! While I was glad to hear that the author agreed that the defenders are right, I was taken aback by the assumption that implementing FontAwesome optimally is some Herculean task beyond the ability and understanding of most devs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkkkgqi8gs5vhrpsk84h2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkkkgqi8gs5vhrpsk84h2.gif" alt="Wow, OK. Harsh!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TailwindCSS includes the entire kitchen sink as well. But they also include helpers to prune it all so you ship the absolute, smallest most performant css you can.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The comparison to TailwindCSS is moot, given that FontAwesome provides the same optimisation options out of the box, provided your chosen implementation method supports it. For example, using npm packages and importing select icons ensures only the relevant icon data and CSS is included in your transpiled build.&lt;/p&gt;

&lt;p&gt;And using Kits means none of this data is included in your final build and the specific CSS and SVG data is sent to the user during the client-side render of the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfpyxx0k10cac6lw130w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfpyxx0k10cac6lw130w.gif" alt="So good."&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🙅‍♂️ Myth #3 - Resizing the icons is a nightmare
&lt;/h2&gt;

&lt;p&gt;The premise: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A major problem with font icons is that you're treating them like fonts first, not icons. You want a horse icon to be 100px wide. This won't work: &lt;code&gt;.fa-horse { width: 100px; /* does nothing */ }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead, you have to fiddle with this using font-size.&lt;/p&gt;

&lt;p&gt;That also means these icons are also affected by other css text modifiers, like line-height.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;FontAwesome uses the &lt;code&gt;font-size&lt;/code&gt; property because the icons are sized &lt;em&gt;relative to the content and UI elements surrounding them&lt;/em&gt;. When you place a contextual icon next to your button label, it’s great that the icon will automatically match its size with that of the button label text. Need the icon to be a little bigger? Just add the &lt;code&gt;fa-lg&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;A quick skim over the &lt;a href="https://fontawesome.com/docs/web/style/size" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; will tell you everything you need to know about sizing your icons.&lt;/p&gt;




&lt;h2&gt;
  
  
  🙅‍♂️ Myth #4 - Major version releases break compatibility across the board
&lt;/h2&gt;

&lt;p&gt;The premise:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="c"&gt;&amp;lt;!-- FontAwesome 3 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"icon-star"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt; 

&lt;span class="c"&gt;&amp;lt;!-- FontAwesome 4 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fa fa-star"&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- FontAwesome 5 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fas fa-star"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- FontAwesome 6 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fa-solid fa-star"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/i&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;If I wanted to upgrade FontAwesome 3 to FontAwesome 6, I'll have to go find all the markup and fix that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If someone is using FontAwesome 3, sure, they would have to do that. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmue7em3scjc8brcv13a1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmue7em3scjc8brcv13a1.gif" alt="Sure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, from FontAwesome 4 and up, backward compatibility is built in. You can upgrade your v4 or v5 project to v6 without having to make any changes to your markup. &lt;/p&gt;

&lt;p&gt;If you check out the &lt;a href="https://fontawesome.com/docs/web/setup/upgrade/whats-changed#backward-compatibility" rel="noopener noreferrer"&gt;“Backward Compatibility” section of the “What’s Changed” section of the documentation&lt;/a&gt;, you’ll find that support for the use of the old style syntax (and even old icon names and Unicode values) comes out of the box. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fniexog7xooaqwzzkb82f.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fniexog7xooaqwzzkb82f.gif" alt="#WINNING"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🙅‍♂️ Myth #5 - You have to upgrade your plan to get the latest icons
&lt;/h2&gt;

&lt;p&gt;The premise: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If I have FontAwesome 5 Pro, which I purchased in 2019, and I wanted a [&lt;a href="https://fontawesome.com/icons/bagel?s=thin" rel="noopener noreferrer"&gt;thin-style bagel icon&lt;/a&gt;], I'll have to either:&lt;/p&gt;

&lt;p&gt;Option 1: Keep FontAwesome 5 Pro and also include FontAwesome 6 [thin-style icons]&lt;br&gt;
Option 2: Buy FontAwesome 6 Pro.&lt;/p&gt;

&lt;p&gt;Just to get a [bagel icon], I now can either fracture my versions or pay $99.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer is easy: just use the icon! &lt;a href="https://fontawesome.com/plans" rel="noopener noreferrer"&gt;A pro plan&lt;/a&gt; with FontAwesome includes the use of &lt;em&gt;any icon in the latest version, always&lt;/em&gt;. So when v7 inevitably gets released, you’ll get access to those icons too, no plan-upgrade or additional payments required.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2For9pr5j7ngpk4jpzh0bz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2For9pr5j7ngpk4jpzh0bz.gif" alt="You get the icons! And you get the icons!"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  In Summary
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;All of these problems do have workarounds. The thing is -- all these problems are strictly from using FontAwesome!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is &lt;em&gt;almost&lt;/em&gt; true. I would go further to say that “all these problems are strictly from implementing FontAwesome &lt;em&gt;in an unoptimised manner&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;When implemented well, FontAwesome provides you with lean, accessible, scalable icons for your projects. The original post conflated the issues present in bloated and “quick” implementations with the service as a whole, which I feel misinforms people of its great many utilities when used appropriately.&lt;/p&gt;

&lt;p&gt;In my eyes, &lt;em&gt;FontAwesome is still awesome&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;☝️ Remember: Always import just the icons you need, tree-shake your projects, and never make toast in the bath.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;💬 What do you think? Have you worked on a project that implemented FontAwesome in a not-so-awesome way? What's your favourite method for adding icons to your projects? I'm keen to hear your perspectives and thoughts in the comments below!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This post was originally a comment that I wanted to expand into a more long-form response. You can view the original post and my comment here:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post:&lt;/strong&gt; &lt;a href="https://dev.to/rockykev/im-officially-done-with-fontawesome-2h2f"&gt;https://dev.to/rockykev/im-officially-done-with-fontawesome-2h2f&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comment:&lt;/strong&gt; &lt;a href="https://dev.to/danwalsh/comment/1p8e4"&gt;https://dev.to/danwalsh/comment/1p8e4&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>fonts</category>
      <category>frontend</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Bootstrap 5 + React project setup and customisation</title>
      <dc:creator>Dan Walsh</dc:creator>
      <pubDate>Mon, 14 Dec 2020 07:28:34 +0000</pubDate>
      <link>https://dev.to/danwalsh/getting-started-with-the-new-bootstrap-5-beta-and-nextjs-51am</link>
      <guid>https://dev.to/danwalsh/getting-started-with-the-new-bootstrap-5-beta-and-nextjs-51am</guid>
      <description>&lt;p&gt;With the &lt;a href="https://blog.getbootstrap.com/2020/12/07/bootstrap-5-beta-1/" rel="noopener noreferrer"&gt;recent release of Bootstrap 5 Beta 1&lt;/a&gt;, now is a great time to dip your toes into working with the new major updates and getting your tools ready for when the final release drops.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up your project 🗂
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Set up your environment 🌳
&lt;/h3&gt;

&lt;p&gt;Initialise a new npm package in your directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-y&lt;/code&gt; parameter tells npm to accept the default answers for all options.&lt;/p&gt;

&lt;p&gt;Next, install our packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm i bootstrap@next react react-dom next sass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/bootstrap" rel="noopener noreferrer"&gt;bootstrap@next&lt;/a&gt; -- Bootstrap 5 Beta&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/react" rel="noopener noreferrer"&gt;react&lt;/a&gt; -- React&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/react-dom" rel="noopener noreferrer"&gt;react-dom&lt;/a&gt; -- React DOM&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/next" rel="noopener noreferrer"&gt;next&lt;/a&gt; -- NextJS&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/sass" rel="noopener noreferrer"&gt;sass&lt;/a&gt; -- SASS/SCSS preprocessor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also need to set up our scripts in &lt;code&gt;package.json&lt;/code&gt; as follows:&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&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;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next start"&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="err"&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;h3&gt;
  
  
  2. Add your SCSS file 👨‍🎨
&lt;/h3&gt;

&lt;p&gt;Next we need to add our SCSS folder and file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;scss
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;scss/main.scss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add the following content to &lt;code&gt;scss/main.scss&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import Bootstrap 5 Beta!&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"~bootstrap/scss/bootstrap.scss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Set up your pages 📄
&lt;/h3&gt;

&lt;p&gt;We need to set up our usual index page, but also a custom App component that lives within the &lt;code&gt;/pages&lt;/code&gt; directory. This is  so we can ensure that Bootstrap 5 Beta is loaded across the entire NextJs app.&lt;/p&gt;

&lt;p&gt;Create your pages folder, the index page and custom App component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;pages &lt;span class="c"&gt;# Your pages folder&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;pages/index.js &lt;span class="c"&gt;# The index page&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;pages/_app.js &lt;span class="c"&gt;# The custom App component&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;pages/index.js&lt;/code&gt; file, add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;IndexPage&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello world!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;IndexPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in your &lt;code&gt;pages/_app.js&lt;/code&gt; file, add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../scss/main.scss&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point you can run &lt;code&gt;npm run dev&lt;/code&gt; in your terminal and browse to &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt; in your web browser and you'll be greeted with the universal dev message "Hello world!".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd0nknn1l2aw7nt385ltb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd0nknn1l2aw7nt385ltb.png" alt="Screen Shot 2020-12-14 at 5.07.25 pm" width="670" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now for the fun part...&lt;/p&gt;




&lt;h2&gt;
  
  
  Customising Bootstrap 🎨
&lt;/h2&gt;

&lt;p&gt;So we've got our project up and running, our dependencies are all installed and ready roll, and Bootstrap is being imported into our main SCSS file.&lt;/p&gt;

&lt;p&gt;Let's add some structure and a little content to our index page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;IndexPage&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;col&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mt-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;This&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;Bootstrap&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="nx"&gt;Beta&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;NextJS&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn btn-primary me-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Read&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn btn-outline-secondary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;just&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;started&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;IndexPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will render our new content within Bootstrap's fully-responsive mobile-first grid system:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6kkz6a0s5pqshvq5vsp3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6kkz6a0s5pqshvq5vsp3.png" alt="Screen Shot 2020-12-14 at 5.14.57 pm" width="670" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can then override Bootstrap's SCSS variables to build our our theme:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Change the primary colour&lt;/span&gt;
&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;207&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;44&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Set the sans-serif font&lt;/span&gt;
&lt;span class="nv"&gt;$font-family-sans-serif&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Maybe set a difference heading font family&lt;/span&gt;
&lt;span class="nv"&gt;$headings-font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Georgia&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Make headings bolder!&lt;/span&gt;
&lt;span class="nv"&gt;$headings-font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Thicken up our borders&lt;/span&gt;
&lt;span class="nv"&gt;$border-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Remove the border-radius everywhere&lt;/span&gt;
&lt;span class="nv"&gt;$border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Import Bootstrap 5 Beta!&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"~bootstrap/scss/bootstrap.scss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which should give you something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz15st6csc2f791sjw19y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz15st6csc2f791sjw19y.png" alt="Screen Shot 2020-12-14 at 5.45.18 pm" width="670" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That should be enough to get your next Bootstrap 5 + NextJS web app kick started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now get out there and make something beautiful!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>npm</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Self-host Google Fonts in your next React project with Fontsource</title>
      <dc:creator>Dan Walsh</dc:creator>
      <pubDate>Sat, 12 Dec 2020 12:25:02 +0000</pubDate>
      <link>https://dev.to/danwalsh/self-host-google-fonts-in-your-next-react-project-with-fontsource-1n07</link>
      <guid>https://dev.to/danwalsh/self-host-google-fonts-in-your-next-react-project-with-fontsource-1n07</guid>
      <description>&lt;h2&gt;
  
  
  The situation 🤔
&lt;/h2&gt;

&lt;p&gt;While you can rely on Google's CDN to host and serve your fonts so you don't have to, you're relying on that connection and the fonts themselves being available. That's fine for a quick mock-up, but not so great for your production roll-out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typefaces—the status quo 👌
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/KyleAMathews/typefaces" rel="noopener noreferrer"&gt;Typefaces project&lt;/a&gt; has been the long-standing approach to self-hosting Google fonts with your React web apps, but it wasn't without its caveats, as explained in the opening lines of the project's &lt;a href="https://github.com/KyleAMathews/typefaces/blob/master/README.md" rel="noopener noreferrer"&gt;README.md&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Typefaces project is now deprecated.&lt;/p&gt;

&lt;p&gt;@DecliningLotus created FontSource which provides the same functionality as Typefaces but with automated releases &amp;amp; richer support for importing specific weights, styles, or language subsets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Enter, Fontsource 🙇‍♂️
&lt;/h2&gt;

&lt;p&gt;With &lt;a href="https://fontsource.org" rel="noopener noreferrer"&gt;Fontsource&lt;/a&gt;, you get a number of great benefits right out of the gate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ridiculous performance gains from self-hosting (&lt;a href="https://github.com/HTTPArchive/almanac.httparchive.org/pull/607" rel="noopener noreferrer"&gt;source&lt;/a&gt;, &lt;a href="https://github.com/reactiflux/reactiflux.com/pull/21" rel="noopener noreferrer"&gt;source&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Version locking ensures your fonts are free from Google's tinkering.&lt;/li&gt;
&lt;li&gt;Your fonts will be available even if your React app is running offline.&lt;/li&gt;
&lt;li&gt;Fontsource also includes Open Source fonts, not just Google's library.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why are we still talking about it? Let's use some fonts already!&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Fontsource with React 🔤
&lt;/h2&gt;

&lt;p&gt;As an example, let's use the Google Font "&lt;a href="https://fonts.google.com/specimen/Poppins" rel="noopener noreferrer"&gt;Poppins&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;A note from the installation docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fontsource assumes you are using a bundler, such as Webpack, to load in CSS. Solutions like CRA, Gatsby and Next.js are prebuilt examples that are compatible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, on to the fun part:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;In your project directory, install the font:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @fontsource/poppins
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In your app or index JS file, import the font:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@fontsource/poppins&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// Defaults to weight 400 with all styles included.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Alternatively, in your project SCSS file, prepend the following to the top:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"~@fontsource/poppins/index.css"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Defaults to weight 400 with all styles included.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lastly, use the font in your CSS/SCSS rules:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Poppins"&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;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that's it!&lt;/p&gt;

&lt;p&gt;As long as your chosen font supports it, you can optionally import other subsets that you need, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"~@fontsource/poppins/700.css"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* Font-weight 700 */&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"~@fontsource/poppins/600-italic.css"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* Font-weight 600 italic */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  But do they have x font? 🙄
&lt;/h2&gt;

&lt;p&gt;Fontsource has an amazing &lt;a href="https://fontsource.org/fonts" rel="noopener noreferrer"&gt;search directory&lt;/a&gt; that lists all supported fonts. It also allows you to interactively adjust font-size on the fly.&lt;/p&gt;

&lt;p&gt;Better still, every font page lists the npm installation commands and JavaScript/SCSS import scripts needed to get you up and running in seconds.&lt;/p&gt;




&lt;p&gt;You now have all the knowledge you need to make your React app beautiful with any self-hosted font you could want (aside from &lt;a href="https://fontsource.org/fonts/comic-neue" rel="noopener noreferrer"&gt;comic-neue&lt;/a&gt; and &lt;a href="https://fontsource.org/fonts/lobster" rel="noopener noreferrer"&gt;lobster&lt;/a&gt;, because you want your React app to look beautiful, right? 😅).&lt;/p&gt;




&lt;p&gt;Cover photo source: &lt;span&gt;Photo by &lt;a href="https://unsplash.com/@marcusdepaula?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Marcus dePaula&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit 30/08/2021:&lt;/strong&gt; Updated Fontsource package names (as they were moved from fontsource-[font] to @fontsource/[font].&lt;br&gt;
&lt;strong&gt;Edit 30/08/2021:&lt;/strong&gt; Updated Fontsource links (thank you, &lt;a class="mentioned-user" href="https://dev.to/jerhowden"&gt;@jerhowden&lt;/a&gt;! 🙇‍♂️)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
      <category>fonts</category>
    </item>
    <item>
      <title>Flush your DNS cache with a single easy-to-remember command</title>
      <dc:creator>Dan Walsh</dc:creator>
      <pubDate>Fri, 11 Dec 2020 04:02:44 +0000</pubDate>
      <link>https://dev.to/danwalsh/flush-your-dns-with-one-easy-to-remember-command-42m7</link>
      <guid>https://dev.to/danwalsh/flush-your-dns-with-one-easy-to-remember-command-42m7</guid>
      <description>&lt;h2&gt;
  
  
  The problem 🙄
&lt;/h2&gt;

&lt;p&gt;Has this ever happened to you?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You're working away merrily on your web project and you've just made a DNS change—maybe you've added a new subdomain or you're now redirecting site traffic through a Web Application Firewall (WAF). But... your browser still thinks it can find your web project at the &lt;em&gt;old&lt;/em&gt; IP address. You &lt;em&gt;could&lt;/em&gt; wait until the time-to-live (TTL) expires on the DNS records you changed, but you've got a deadline to meet. Now you'll have to scour the web for another &lt;code&gt;mac flush dns&lt;/code&gt; article...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because it happens to me &lt;strong&gt;all the time&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution 👍
&lt;/h2&gt;

&lt;p&gt;I figured it was time that I made my life just a little easier and create a system-wide bash script that I could invoke from any user account on my Mac.&lt;/p&gt;

&lt;p&gt;Now when I want to flush my DNS, all I need to do is open a Terminal window and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;flush-dns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: This works on MacOS Catalina and MacOS Big Sur. Be sure to replace the DNS flushing commands in my example with those relevant to your OS and version.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to do it 🧐
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open up Terminal.&lt;/li&gt;
&lt;li&gt;Enter the following commands:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/local/bin
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder &amp;amp;&amp;amp; echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;DNS cache flushed successfully&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; flush-dns
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x flush-dns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol start="3"&gt;
  &lt;li&gt;Close and relaunch Terminal.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Testing it out 👨‍🔬
&lt;/h2&gt;

&lt;p&gt;Now the moment of truth!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In your freshly opened terminal window, type in &lt;code&gt;flush-dns&lt;/code&gt; and hit &lt;strong&gt;Enter&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Terminal will prompt you for your password as it needs to elevate privileges via the &lt;code&gt;sudo&lt;/code&gt; commands—type it in and hit &lt;strong&gt;Enter&lt;/strong&gt; again.&lt;/li&gt;
&lt;li&gt;Terminal will then execute the DNS cache flushing commands we added earlier—perfect!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Don't forget!&lt;/strong&gt; — You might also need to clear your browser cache and restart your browser for the script to take effect!&lt;/p&gt;




&lt;p&gt;Cover image source: &lt;a href="https://www.freepik.com/vectors/business" rel="noopener noreferrer"&gt;macrovector @ www.freepik.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bash</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
