<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>John Henry Galino</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://jhgalino.codeberg.page/</id>
  <link href="https://jhgalino.codeberg.page/" rel="alternate"/>
  <link href="https://jhgalino.codeberg.page/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, John Henry Galino</rights>
  <title>jhgalino</title>
  <updated>2026-03-04T12:50:45.765Z</updated>
  <entry>
    <author>
      <name>John Henry Galino</name>
    </author>
    <category term="emacs" scheme="https://jhgalino.codeberg.page/tags/emacs/"/>
    <category term="csharp" scheme="https://jhgalino.codeberg.page/tags/csharp/"/>
    <category term="avalonia" scheme="https://jhgalino.codeberg.page/tags/avalonia/"/>
    <content>
      <![CDATA[<p>Recently, I’ve been experimenting with Avalonia for GUI applications in C#. However, I found out that despite the good support for C# in Emacs, the same could not be said for <a href="https://avaloniaui.net/">Avalonia</a>. The  problem stems mostly from the fact that Avalonia uses Avalonia XAML (.axaml) files for describing the UI, which Emacs doesn’t have a mode for. Unfortunately, Avalonia doesn’t have a free LSP lying around, so I can’t really create an <code>lsp-mode</code> client without creating my own LSP server.  However, it turns out that creating a major mode for Avalonia is really easy!</p><h2 id="Creating-a-new-major-mode"><a href="#Creating-a-new-major-mode" class="headerlink" title="Creating a new major mode"></a>Creating a new major mode</h2><p>Major modes in Emacs are really easy to create, since they are essentially just one Elisp file containing your customizations to an existing mode. The only blocker that I experienced was finding out how to get my major mode into Doom Emacs.</p><p>The first step to creating a major mode is of course, to write it. I created a directory to serve as my repository and wrote <code>avalonia-xaml-mode.el</code>. </p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">define-derived-mode</span> avalonia-xaml-mode</span><br><span class="line">  nxml-mode</span><br><span class="line">  <span class="string">&quot;Avalonia XAML&quot;</span></span><br><span class="line">  <span class="string">&quot;Major mode for editing Avalonia XAML.&quot;</span>)</span><br><span class="line"></span><br><span class="line">(<span class="name">add-to-list</span> &#x27;auto-mode-alist &#x27;(<span class="string">&quot;\\.axaml\\&#x27;&quot;</span> . avalonia-xaml-mode))</span><br><span class="line"></span><br><span class="line">(<span class="name">provide</span> &#x27;avalonia-xaml-mode)</span><br></pre></td></tr></table></figure><p><code>define-derived-mode</code> creates a new mode called <code>avalonia-xaml-mode</code>, basing the mode from Emacs’ existing <code>nxml-mode</code> to provide syntax highlighting. The two string arguments are just the text to display on the mode line and the docstring of the mode.</p><p>Next, we call <code>add-to-list</code> to associate the <code>.axaml</code> file extension with the mode.<br>Finally, we <code>provide</code> the mode itself.<br>After writing the code, we need to upload it to a Git repository. The Git repo must be named with the same name as the file containing the mode, so I named the repo <code>avalonia-xaml-mode</code>. Afterwards, I pushed the repository to the remote with the branch <code>master</code>, since this is the branch most Emacs package managers use by default when getting packages from Git repos.</p><p>After pushing the changes to the remote, I can now install it in Doom Emacs by writing the following in <code>packages.el</code> </p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">package!</span> avalonia-xaml-mode</span><br><span class="line">  <span class="symbol">:recipe</span> (<span class="symbol">:host</span> codeberg</span><br><span class="line">           <span class="symbol">:repo</span> <span class="string">&quot;jhgalino/avalonia-xaml-mode&quot;</span>))</span><br></pre></td></tr></table></figure>]]>
    </content>
    <id>https://jhgalino.codeberg.page/2026/03/03/avalonia-emacs/</id>
    <link href="https://jhgalino.codeberg.page/2026/03/03/avalonia-emacs/"/>
    <published>2026-03-03T21:21:21.000Z</published>
    <summary>
      <![CDATA[<p>Recently, I’ve been experimenting with Avalonia for GUI applications in C#. However, I found out that despite the good support for C# in]]>
    </summary>
    <title>Major mode in Emacs for Avalonia</title>
    <updated>2026-03-04T12:50:45.765Z</updated>
  </entry>
  <entry>
    <author>
      <name>John Henry Galino</name>
    </author>
    <category term="typescript" scheme="https://jhgalino.codeberg.page/tags/typescript/"/>
    <category term="web" scheme="https://jhgalino.codeberg.page/tags/web/"/>
    <category term="streams" scheme="https://jhgalino.codeberg.page/tags/streams/"/>
    <content>
      <![CDATA[<p>One of the more interesting features of the Web that I haven’t had an opportunity to use much yet is streams. A <a href="https://en.wikipedia.org/wiki/Stream_(computing)">stream</a> is a sequence of data processed over time. Usually, what happens is that the data is broken into pieces, then each chunk is processed, either written or read. In the Web, working with streams is done through the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Streams_API">Stream API</a>, which provides <code>ReadableStream</code> and <code>WritableStream</code> interfaces to read and write streams, respectively. The interface for <code>ReadableStream</code> is pretty easy to grok, while <code>WritableStream</code> is a bit harder to follow. As such, I’ll only be covering <code>ReadableStream</code> in this article. To be fair, most of the time you’ll probably be reading streams more than writing them.</p><h2 id="ReadableStream"><a href="#ReadableStream" class="headerlink" title="ReadableStream"></a><code>ReadableStream</code></h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> response = <span class="keyword">await</span> <span class="title function_">fetch</span>(<span class="string">&#x27;example.com&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> reader = response.<span class="property">body</span>.<span class="title function_">getReader</span>()</span><br><span class="line"><span class="keyword">const</span> &#123; value, done &#125; = reader.<span class="title function_">read</span>()</span><br></pre></td></tr></table></figure><p>The <code>ReadableStream</code> interface is used when you want to read a stream. In our example, the <code>body</code> property of a <code>Response</code> returns a <code>ReadableStream</code> To use it, you must first get a reader from the <code>ReadableStream</code> instance. This is done by calling <code>ReadableStream.getReader()</code>, which returns a reader of the <code>ReadableStream</code>. Once you have a reader from a <code>ReadableStream</code>, only that reader can read from the <code>ReadableStream</code>. Then you must call the <code>read</code> method of the reader to get a value of the form <code>{ value: chunk, done: boolean }</code>. The <code>value</code> is the chunk read by the reader. <code>done</code> represents whether the stream has been closed or not. Thus, to read all the chunks of a stream, you can use a <code>while</code> loop until <code>done</code> is set to true. Since <code>ReadableStream</code> is an async iterator, you can also use a <code>for await...of</code> loop to process each chunk.</p>]]>
    </content>
    <id>https://jhgalino.codeberg.page/2026/02/07/streams/</id>
    <link href="https://jhgalino.codeberg.page/2026/02/07/streams/"/>
    <published>2026-02-07T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>One of the more interesting features of the Web that I haven’t had an opportunity to use much yet is streams. A <a href="https://en.wikip]]>
    </summary>
    <title>Reading Streams in the Browser</title>
    <updated>2026-03-03T12:02:07.509Z</updated>
  </entry>
  <entry>
    <author>
      <name>John Henry Galino</name>
    </author>
    <category term="typescript" scheme="https://jhgalino.codeberg.page/tags/typescript/"/>
    <category term="adonisjs" scheme="https://jhgalino.codeberg.page/tags/adonisjs/"/>
    <category term="inertia" scheme="https://jhgalino.codeberg.page/tags/inertia/"/>
    <category term="shadcn" scheme="https://jhgalino.codeberg.page/tags/shadcn/"/>
    <category term="tailwindcss" scheme="https://jhgalino.codeberg.page/tags/tailwindcss/"/>
    <content>
      <![CDATA[<p>Recently, I’ve been playing around with <a href="https://adonisjs.com/">Adonis</a> to create my side-project. I especially like the fact that it’s batteries-included, which is a rare trait in the world of Javascript. I also like that it has an included adapter for <a href="https://inertiajs.com/">Inertia</a>, which lets me use popular frontend libraries while still using the many tools included with MVC frameworks. However, I hit a snag when I wanted to use <a href="https://ui.shadcn.com/"><code>shadcn/ui</code></a> in my Inertia frontend. It turns out that using <code>shadcn</code> with Adonis and Inertia is not documented well. Luckily, with some help from random blog posts and other projects using Inertia, I was able to integrate <code>shadcn</code> successfully.</p><h2 id="Setup"><a href="#Setup" class="headerlink" title="Setup"></a>Setup</h2><p>You can setup an Adonis&#x2F;Inertia application by following the instructions <a href="https://docs.adonisjs.com/guides/getting-started/installation">here</a>. For the rest of this article, I’m gonna assume that you have a working Adonis&#x2F;Inertia application scaffolded using the Inertia starter kit.</p><h2 id="Installing-shadcn"><a href="#Installing-shadcn" class="headerlink" title="Installing shadcn"></a>Installing shadcn</h2><p>To use <code>shadcn/ui</code> with Adonis’ Inertia adapter, we need to follow <code>shadcn</code>‘s <a href="https://ui.shadcn.com/docs/installation/vite">instructions</a> for installing it on a Vite application, but with a few modifications.</p><h3 id="Install-Tailwind"><a href="#Install-Tailwind" class="headerlink" title="Install Tailwind"></a>Install Tailwind</h3><p>Since we have an Adonis application already, we can start by installing TailwindCSS.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install tailwindcss @tailwindcss/vite</span><br></pre></td></tr></table></figure><p>Then, instead of <code>src/index.css</code>, replace the contents of <code>inertia/css/app.css</code> with:</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">@import</span> <span class="string">&quot;tailwindcss&quot;</span>;</span><br></pre></td></tr></table></figure><h3 id="Edit-tsconfig-json"><a href="#Edit-tsconfig-json" class="headerlink" title="Edit tsconfig.json"></a>Edit tsconfig.json</h3><p>Before editing <code>tsconfig.json</code>, we need to create a directory where the <code>shadcn</code> components will live. I created a <code>lib/</code> directory inside <code>inertia/</code> for this purpose. Next, we need to edit the <code>tsconfig.json</code> in the root directory of our app as well as the one in <code>inertia/</code>. For <code>inertia/tsconfig.json</code>, I did the following changes:</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;extends&quot;: &quot;@adonisjs/tsconfig/tsconfig.client.json&quot;,</span><br><span class="line">  &quot;compilerOptions&quot;: &#123;</span><br><span class="line">     &quot;baseUrl&quot;: &quot;.&quot;,</span><br><span class="line">     &quot;module&quot;: &quot;ESNext&quot;,</span><br><span class="line">     &quot;jsx&quot;: &quot;react-jsx&quot;,</span><br><span class="line">     &quot;paths&quot;: &#123;</span><br><span class="line">       &quot;~/*&quot;: [&quot;./*&quot;],</span><br><span class="line"><span class="addition">+      &quot;@/*&quot;: [&quot;./lib/*&quot;]</span></span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">  &quot;include&quot;: [&quot;./**/*.ts&quot;, &quot;./**/*.tsx&quot;],</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>For the <code>tsconfig.json</code> in the root folder, we need to follow the changes made to <code>tsconfig.app.json</code>, but modifying the <code>baseUrl</code> property to point instead to our created directory for <code>shadcn</code> components.</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;extends&quot;: &quot;@adonisjs/tsconfig/tsconfig.app.json&quot;,</span><br><span class="line">  &quot;compilerOptions&quot;: &#123;</span><br><span class="line">    &quot;rootDir&quot;: &quot;./&quot;,</span><br><span class="line">    &quot;outDir&quot;: &quot;./build&quot;,</span><br><span class="line"><span class="addition">+   &quot;baseUrl&quot;: &quot;./inertia/lib/&quot;,</span></span><br><span class="line"><span class="addition">+   &quot;paths&quot;: &#123;</span></span><br><span class="line"><span class="addition">+       &quot;@/*&quot;: [&quot;./*&quot;]</span></span><br><span class="line"><span class="addition">+   &#125;</span></span><br><span class="line">  &#125;,</span><br><span class="line">  &quot;exclude&quot;: [&quot;./inertia/**/*&quot;, &quot;node_modules&quot;, &quot;build&quot;]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="Update-vite-config-ts"><a href="#Update-vite-config-ts" class="headerlink" title="Update vite.config.ts"></a>Update <code>vite.config.ts</code></h3><p>Next, we need to add <code>tailwindcss()</code> in the list of plugins in <code>vite.config.ts</code>.</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="addition">+ import tailwindcss from &#x27;@tailwindcss/vite&#x27;</span></span><br><span class="line">...</span><br><span class="line">export default defineConfig(&#123;</span><br><span class="line">  plugins: [</span><br><span class="line">    inertia(&#123; ssr: &#123; enabled: true, entrypoint: &#x27;inertia/app/ssr.tsx&#x27; &#125; &#125;),</span><br><span class="line">    react(),</span><br><span class="line">    adonisjs(&#123; entrypoints: [&#x27;inertia/app/app.tsx&#x27;], reload: [&#x27;resources/views/**/*.edge&#x27;] &#125;),</span><br><span class="line"><span class="addition">+   tailwindcss(),</span></span><br><span class="line">  ],</span><br><span class="line"></span><br><span class="line">  /**</span><br><span class="line">   * Define aliases for importing modules from</span><br><span class="line">   * your frontend code</span><br><span class="line">   */</span><br><span class="line">  resolve: &#123;</span><br><span class="line">    alias: &#123;</span><br><span class="line">      &#x27;~/&#x27;: `$&#123;getDirname(import.meta.url)&#125;/inertia/`,</span><br><span class="line"><span class="addition">+     &#x27;@/&#x27;: `$&#123;getDirname(import.meta.url)&#125;/inertia/lib/`,</span></span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h3 id="Initialize-shadcn"><a href="#Initialize-shadcn" class="headerlink" title="Initialize shadcn"></a>Initialize <code>shadcn</code></h3><p>Finally, we can now install shadcn and start adding components.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx shadcn@latest init</span><br></pre></td></tr></table></figure><p>Huge thanks to Matteo Gassend’s <a href="https://www.matteogassend.com/articles/using-shadcn-ui-with-inertia-and-adonisjs">article</a> and the <a href="https://inertia-rails.dev/">Inertia Rails</a> project for serving as basis for my research on integrating <code>shadcn/ui</code> with AdonisJS and Inertia.js.</p>]]>
    </content>
    <id>https://jhgalino.codeberg.page/2026/01/19/adonis-shadcn/</id>
    <link href="https://jhgalino.codeberg.page/2026/01/19/adonis-shadcn/"/>
    <published>2026-01-19T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>Recently, I’ve been playing around with <a href="https://adonisjs.com/">Adonis</a> to create my side-project. I especially like the fact]]>
    </summary>
    <title>How to set up shadcn/ui in AdonisJS 6 with Inertia.js</title>
    <updated>2026-02-11T16:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>John Henry Galino</name>
    </author>
    <category term="book review" scheme="https://jhgalino.codeberg.page/tags/book-review/"/>
    <content>
      <![CDATA[<p>I recently read Dave Thomas’s book, <a href="https://pragprog.com/titles/dtcode/simplicity/">Simplicity</a> and I can say that I learnt a lot. One of the things that I really liked  about the book was the chapter about state machines, and how they often make the code much simpler to maintain and understand. In the codebase I’m working now, I also started turning my logic code into state machines, and I do agree that they have become simpler. </p>]]>
    </content>
    <id>https://jhgalino.codeberg.page/2026/01/13/simplicity/</id>
    <link href="https://jhgalino.codeberg.page/2026/01/13/simplicity/"/>
    <published>2026-01-13T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>I recently read Dave Thomas’s book, <a href="https://pragprog.com/titles/dtcode/simplicity/">Simplicity</a> and I can say that I learnt a]]>
    </summary>
    <title>Simplicity and the power of state machines</title>
    <updated>2026-03-03T12:02:07.509Z</updated>
  </entry>
  <entry>
    <author>
      <name>John Henry Galino</name>
    </author>
    <category term="thoughts" scheme="https://jhgalino.codeberg.page/tags/thoughts/"/>
    <content>
      <![CDATA[<p>This post is a reflection about the things that I did this week.</p><h2 id="What-I-did-right"><a href="#What-I-did-right" class="headerlink" title="What I did right"></a>What I did right</h2><ul><li>Choosing React Router turned out to be for the best, since we didn’t have to suffer the recent security debacle of Next.</li><li>Doom Emacs is the bomb. After going through tons of editors, I can say that Doom Emacs might be the last one I use. My only concern with it is how long can the maintainers actually maintain it.</li></ul><h2 id="What-I-did-wrong"><a href="#What-I-did-wrong" class="headerlink" title="What I did wrong"></a>What I did wrong</h2><ul><li>I shouldn’t have spent too much time trying to perfect the looks of my work. I violated Joe Armstrong’s three rules of software development: make it work, make it beautiful, and make it fast.</li><li>I also should have chosen a big framework at the start instead of choosing a small one. There’s a reason why these big frameworks are popular.</li></ul><h2 id="What-to-change"><a href="#What-to-change" class="headerlink" title="What to change"></a>What to change</h2><ul><li>Strictly adhere to tenets of software engineering</li><li>Start big, then go small when the big framework don’t serve your needs anymore</li></ul>]]>
    </content>
    <id>https://jhgalino.codeberg.page/2025/12/17/reflections/</id>
    <link href="https://jhgalino.codeberg.page/2025/12/17/reflections/"/>
    <published>2025-12-17T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>This post is a reflection about the things that I did this week.</p>
<h2 id="What-I-did-right"><a href="#What-I-did-right" class="headerl]]>
    </summary>
    <title>Reflections</title>
    <updated>2026-03-03T12:02:07.509Z</updated>
  </entry>
  <entry>
    <author>
      <name>John Henry Galino</name>
    </author>
    <category term="tailwindcss" scheme="https://jhgalino.codeberg.page/tags/tailwindcss/"/>
    <category term="emacs" scheme="https://jhgalino.codeberg.page/tags/emacs/"/>
    <category term="biomejs" scheme="https://jhgalino.codeberg.page/tags/biomejs/"/>
    <content>
      <![CDATA[<p>Currently, I’m working on a React project with Doom Emacs. Doom Emacs is amazing, with good support for Javascript and Typescript. However, it lacks support for Tailwind  and Biome, which I’m using in the project.</p><p>To set-up Tailwind, I followed the instructions for <code>lsp-tailwindcss</code> in <a href="https://github.com/merrickluo/lsp-tailwindcss">Github</a>.  First, add the following in packages.el:</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">package!</span> lsp-tailwindcss</span><br><span class="line">          <span class="symbol">:recipe</span></span><br><span class="line">          (<span class="symbol">:host</span> github</span><br><span class="line">           <span class="symbol">:repo</span> <span class="string">&quot;merrickluo/lsp-tailwindcss&quot;</span>))</span><br></pre></td></tr></table></figure><p>Then, in <code>config.el</code>, add this:</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">use-package</span> lsp-tailwindcss</span><br><span class="line">             <span class="symbol">:after</span> lsp-mode</span><br><span class="line">             <span class="symbol">:init</span> (<span class="name">setq</span> lsp-tailwindcss-add-on-mode <span class="literal">t</span>))</span><br></pre></td></tr></table></figure><p>To set-up Biome, I used <a href="https://github.com/cxa/lsp-biome">lsp-biome</a>. I adapted the  above setup for Tailwind to configure <code>lsp-biome</code>.</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">package!</span> lsp-biome</span><br><span class="line">          <span class="symbol">:recipe</span></span><br><span class="line">          (<span class="symbol">:host</span> github</span><br><span class="line">           <span class="symbol">:repo</span> <span class="string">&quot;cxa/lsp-biome&quot;</span>))</span><br></pre></td></tr></table></figure><p>In <code>config.el</code>, I placed the following config code:</p><figure class="highlight lisp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">(<span class="name">use-package</span> lsp-biome</span><br><span class="line">             <span class="symbol">:init</span> (<span class="name">defun</span> my/lsp-biome-active-hook ()</span><br><span class="line">             (<span class="name">setq-local</span> apheleia-formatter &#x27;(biome)))</span><br><span class="line">             <span class="symbol">:config</span> (<span class="name">add-hook</span> &#x27;lsp-biome-active-hook #&#x27;my/lsp-biome-active-hook))</span><br></pre></td></tr></table></figure><p>For LSP and completion to work, both Tailwind and Biome must be available in the <code>PATH</code> or available in <code>node_modules/</code>.</p>]]>
    </content>
    <id>https://jhgalino.codeberg.page/2025/12/14/setting-up/</id>
    <link href="https://jhgalino.codeberg.page/2025/12/14/setting-up/"/>
    <published>2025-12-14T16:00:00.000Z</published>
    <summary>
      <![CDATA[<p>Currently, I’m working on a React project with Doom Emacs. Doom Emacs is amazing, with good support for Javascript and Typescript. Howeve]]>
    </summary>
    <title>Setting up Tailwind CSS and Biome LSP in Doom Emacs</title>
    <updated>2026-03-03T12:02:07.509Z</updated>
  </entry>
</feed>
