<?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: Marabesi</title>
    <description>The latest articles on DEV Community by Marabesi (@marabesi).</description>
    <link>https://dev.to/marabesi</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%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg</url>
      <title>DEV Community: Marabesi</title>
      <link>https://dev.to/marabesi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marabesi"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Mon, 16 Feb 2026 05:19:34 +0000</pubDate>
      <link>https://dev.to/marabesi/-57bb</link>
      <guid>https://dev.to/marabesi/-57bb</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0" class="crayons-story__hidden-navigation-link"&gt;Hexagonal architecture - Another way to the hexagone&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/marabesi" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" alt="marabesi profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/marabesi" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Marabesi
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Marabesi
                
              
              &lt;div id="story-author-preview-content-3180231" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/marabesi" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Marabesi&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jan 18&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0" id="article-link-3180231"&gt;
          Hexagonal architecture - Another way to the hexagone
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/architecture"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;architecture&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            7 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>programming</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Five Years of json-tool and 3,000 Active Users Later</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Tue, 03 Feb 2026 19:54:19 +0000</pubDate>
      <link>https://dev.to/marabesi/five-years-of-json-tool-and-3000-active-users-later-55l3</link>
      <guid>https://dev.to/marabesi/five-years-of-json-tool-and-3000-active-users-later-55l3</guid>
      <description>&lt;p&gt;Five years ago, I started working on &lt;a href="https://github.com/marabesi/json-tool" rel="noopener noreferrer"&gt;json-tool&lt;/a&gt; out of necessity. I needed aJSON formatting tool I could trust with sensitive data: one that wouldn't send my information to third-party servers filled with ads and tracking scripts. What began as a personal weekend project has quietly grown into something used by 3,000 active users. This milestone made me pause and reflect on what this journey has taught me about building and maintaining open source software.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/IhCSsIGQ7YQ"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;3k users?: The number of weekly active users are fetched from the snapcraft channel distribution. The 3k comes from there, however,&lt;br&gt;
I would think this number is higher if adding taking into account the &lt;a href="https://marabesi.github.io/json-tool" rel="noopener noreferrer"&gt;web version&lt;/a&gt;. I am&lt;br&gt;
unable to know that as there are no trackers.&lt;/p&gt;
&lt;h2&gt;
  
  
  Privacy First
&lt;/h2&gt;

&lt;p&gt;In 2021, my workflow involved frequent JSON manipulation: debugging API responses, integrating with third-party services, and inspecting data structures. Like many developers, I defaulted to googling "JSON prettier" and using whatever website appeared first. Tools like &lt;a href="https://jsonformatter.curiousconcept.com/" rel="noopener noreferrer"&gt;JSON Formatter&lt;/a&gt; and &lt;a href="https://jsonformatter.org/json-pretty-print" rel="noopener noreferrer"&gt;JSON Pretty Print&lt;/a&gt; worked fine, but they came with a cost: ads everywhere, no transparency about data handling, and zero guarantee that my JSON strings weren't being logged somewhere.&lt;/p&gt;

&lt;p&gt;For personal projects, this was mildly annoying. For work involving production data or sensitive information, it felt irresponsible. &lt;a href="https://www.thoughtworks.com/content/dam/thoughtworks/documents/radar/2022/10/tr_technology_radar_vol_27_en.pdf" rel="noopener noreferrer"&gt;ThoughtWorks Tech Radar volume 27&lt;/a&gt; later highlighted this exact concern, warning developers about formatting tools that don't comply with data jurisdiction requirements.&lt;/p&gt;

&lt;p&gt;I wanted something different: a tool that collected no data, showed no ads, and remained transparent through open source code. No complex feature set, just reliable JSON formatting that respected user privacy. That's how json-tool was born.&lt;/p&gt;

&lt;p&gt;The initial implementation was straightforward: an Electron app built with React, published to &lt;a href="https://snapcraft.io/json-tool" rel="noopener noreferrer"&gt;snapcraft.io&lt;/a&gt;. I applied outside-in TDD using Cypress and React Testing Library (a practice I've &lt;a href="https://marabesi.com/tdd/a-working-skeleton-to-get-started-with-outside-in-tdd.html" rel="noopener noreferrer"&gt;written about&lt;/a&gt; to ensure the core functionality worked reliably from the start.&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%2F2tiei95t5oe2xuzvilt2.png" 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%2F2tiei95t5oe2xuzvilt2.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  When Users Broke Things
&lt;/h2&gt;

&lt;p&gt;The first version worked well for typical use cases. Developers could paste JSON from logs, validate it, format it with custom spacing, and copy the result back to their clipboard. The privacy-first approach meant enterprise developers working with sensitive data could use it without corporate firewall concerns, and most importantly it runs offline once installed via Snapcraft.&lt;/p&gt;

&lt;p&gt;Then reality hit: users started pasting JSON strings larger than 1MB.&lt;/p&gt;

&lt;p&gt;The application froze. Completely. The user interface became unresponsive, buttons stopped working, and the whole experience fell apart. Through benchmarking with &lt;code&gt;console.time()&lt;/code&gt; and &lt;code&gt;console.timeEnd()&lt;/code&gt;, I traced the bottleneck to the JSON parsing and formatting happening on the main thread. JavaScript's single-threaded nature, combined with the event loop execution model, meant any blocking operation would freeze the entire UI.&lt;/p&gt;

&lt;p&gt;This is where web workers entered the picture.&lt;/p&gt;
&lt;h3&gt;
  
  
  Moving to Web Workers
&lt;/h3&gt;

&lt;p&gt;According to Ido Green's book &lt;a href="https://www.goodreads.com/book/show/19627608-web-workers" rel="noopener noreferrer"&gt;"Web Workers: Multithreaded Programs in JavaScript"&lt;/a&gt;, if your web application needs to complete a task that takes more than 150 milliseconds, you should consider using web workers. Green specifically lists "encoding/decoding a large string" as a primary use case, this is what json-tool was doing.&lt;/p&gt;

&lt;p&gt;The architecture shift was significant. What was previously synchronous code:&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;onJsonChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;spacing&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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;invalid json&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseSpacing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parseSpacing&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parseSpacing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;setOriginalResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&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="nx"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Became an event-driven system where the main thread delegates heavy computation to a dedicated worker:&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;onChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eventSpacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
      &lt;span class="na"&gt;jsonAsString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;eventValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;eventSpacing&lt;/span&gt; 
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;setOriginalResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setInProgress&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The worker itself handles the actual parsing and formatting:&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="nf"&gt;importScripts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://unpkg.com/format-to-json@2.1.2/fmt2json.min.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;importScripts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsonAsString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fmt2json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;expand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;indent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
          &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
          &lt;span class="na"&gt;originalJson&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
          &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&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="p"&gt;}&lt;/span&gt;

      &lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
        &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;originalJson&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; 
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Did this improve performance? No. The actual computation time remained the same. But the user experience was transformed.&lt;br&gt;
Developers could continue interacting with the application while JSON processing happened in the background. I documented this technical journey in detail in &lt;a href="https://marabesi.com/javascript/web-workers-to-the-rescue-how-to-work-with-json-strings-without-blocking-user-interactions.html" rel="noopener noreferrer"&gt;Web Workers to the Rescue&lt;/a&gt;, where I explored the architecture changes and performance implications.&lt;/p&gt;
&lt;h2&gt;
  
  
  Web Workers and TDD
&lt;/h2&gt;

&lt;p&gt;One of my non-negotiables for json-tool was maintaining TDD discipline. I had &lt;a href="https://marabesi.com/tdd/a-working-skeleton-to-get-started-with-outside-in-tdd.html" rel="noopener noreferrer"&gt;written&lt;/a&gt; about using outside-in TDD from the beginning, and I wasn't going to compromise on that.&lt;/p&gt;

&lt;p&gt;Web workers introduced testing complexity I hadn't anticipated. The &lt;code&gt;Worker&lt;/code&gt; object exists in the browser under the &lt;code&gt;window&lt;/code&gt; scope, but in Jest's jsdom environment, it's undefined. My test suite broke immediately after introducing workers.&lt;/p&gt;

&lt;p&gt;The solution came from Jason Miller's &lt;a href="https://github.com/developit/jsdom-worker" rel="noopener noreferrer"&gt;jsdom-worker&lt;/a&gt; library, which provides a Worker API implementation for jsdom. It doesn't create actual threads, it mocks the behavior. The setup required two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install: &lt;code&gt;npm i jsdom-worker&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Import in &lt;code&gt;setupTests.ts&lt;/code&gt;: &lt;code&gt;import 'jsdom-worker'&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The library had limitations, it doesn't support shared workers, and it required using the Blob pattern instead of separate&lt;br&gt;
script files. But it allowed me to maintain my existing tests without coupling them to implementation details:&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="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should format json from uploaded file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{"a":"b"}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello.json&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;render&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;App&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;await&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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;await&lt;/span&gt; &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;upload-json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;waitFor&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;raw-result&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toHaveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`{
  "a": "b"
}`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test describes behavior, not implementation. It doesn't care whether a web worker handles the formatting or not, it just verifies that uploaded JSON gets formatted correctly. This became a valuable lesson: &lt;strong&gt;web workers are implementation details&lt;/strong&gt;. Tests should focus on user-facing behavior.&lt;/p&gt;

&lt;p&gt;I later explored this testing approach further during a &lt;a href="https://marabesi.com/2023/10/20/live-coding-with-web-workers-an-experiment.html" rel="noopener noreferrer"&gt;live coding session with web workers&lt;/a&gt;, where we applied TDD in a coding dojo setting and demonstrated that you can refactor synchronous code to use workers while maintaining test coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges and Learnings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Performance vs. Simplicity
&lt;/h3&gt;

&lt;p&gt;The web worker implementation solved the UI freezing problem but introduced complexity. The codebase went from straightforward synchronous code to an event-driven architecture. New contributors would need to understand worker lifecycle management, message passing, and the implications of moving code off the main thread.&lt;/p&gt;

&lt;p&gt;I balanced this by keeping the worker implementation isolated. The rest of the application remains simple: React components, straightforward state management, minimal abstractions. The complexity is contained, documented, and necessary for the user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Maintenance Reality
&lt;/h3&gt;

&lt;p&gt;Open source maintenance is time-consuming. Dependencies need updates. Security vulnerabilities require patches. Browser APIs change. Testing libraries evolve.&lt;/p&gt;

&lt;p&gt;For json-tool, I aimed for sustainability over rapid development. The tech stack (React, TypeScript, Tailwind, CodeMirror) consists of stable, well-maintained projects with large communities. I avoid cutting-edge dependencies that might break or get abandoned.&lt;/p&gt;

&lt;p&gt;Updates happen in batches, typically when I'm actively using the tool and notice something that needs improvement. This isn't a business with support SLAs, it's a community tool maintained alongside other responsibilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Open Source Philosophy
&lt;/h2&gt;

&lt;p&gt;Building json-tool taught me what open source means beyond "putting code on GitHub":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transparency builds trust. Users can audit the entire codebase. They can verify no tracking happens, no data gets sent anywhere, no ads get injected. Trust isn't demanded, it's proven through openness.&lt;/li&gt;
&lt;li&gt;Focused tools solve problems better. Json-tool doesn't try to be everything to everyone. It does one thing well: formats JSON with privacy guarantees. This focus makes it maintainable and useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Test-driven development pays long-term dividends. The initial TDD investment enabled the web worker refactoring without breaking existing functionality. Tests served as a safety net, allowing confident changes years after initial development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking Forward
&lt;/h2&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%2Fhc58l812f4jg8mzfhbne.png" 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%2Fhc58l812f4jg8mzfhbne.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Json-tool will continue as it is: a focused, privacy-first tool for developers who need trustworthy JSON formatting. I have no plans to monetize it, add analytics, or transform it into something bigger. The value lies in its simplicity and reliability. However, sponsorships are welcome via &lt;a href="https://github.com/sponsors/marabesi" rel="noopener noreferrer"&gt;GitHub Sponsors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Future improvements will likely focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance optimization for extremely large JSON files (&amp;gt;100MB)&lt;/li&gt;
&lt;li&gt;Better accessibility (screen reader support, keyboard navigation improvements)&lt;/li&gt;
&lt;li&gt;Editor synchronization so both scroll simultaneously&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing revolutionary. Just steady improvements that serve the existing user base better. For example, update with the latest version of CodeMirror to benefit from performance and accessibility enhancements, ReactJs updates, and TypeScript improvements.&lt;/p&gt;

&lt;p&gt;The most rewarding part of this journey wasn't reaching 3,000 users, it was building something that solves a real problem without compromising on principles. No tracking. No ads. No data collection. Just a tool that does what it promises and respects its users.&lt;/p&gt;

&lt;p&gt;The source code for json-tool remains available at &lt;a href="https://github.com/marabesi/json-tool" rel="noopener noreferrer"&gt;github.com/marabesi/json-tool&lt;/a&gt;. The tool itself is available at &lt;a href="https://marabesi.github.io/json-tool" rel="noopener noreferrer"&gt;marabesi.github.io/json-tool&lt;/a&gt;. It's been five years. Here's to many more of building software that respects privacy and serves developers well.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Sat, 24 Jan 2026 20:38:57 +0000</pubDate>
      <link>https://dev.to/marabesi/-edh</link>
      <guid>https://dev.to/marabesi/-edh</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0" class="crayons-story__hidden-navigation-link"&gt;Hexagonal architecture - Another way to the hexagone&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/marabesi" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" alt="marabesi profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/marabesi" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Marabesi
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Marabesi
                
              
              &lt;div id="story-author-preview-content-3180231" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/marabesi" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Marabesi&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jan 18&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0" id="article-link-3180231"&gt;
          Hexagonal architecture - Another way to the hexagone
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/architecture"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;architecture&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            7 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>programming</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>opensource</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Sun, 18 Jan 2026 11:46:24 +0000</pubDate>
      <link>https://dev.to/marabesi/-bp5</link>
      <guid>https://dev.to/marabesi/-bp5</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/marabesi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" alt="marabesi"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/marabesi/testing-reactjs-context-a-guide-with-test-doubles-3ap3" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Testing ReactJS Context - A Guide with test-doubles&lt;/h2&gt;
      &lt;h3&gt;Marabesi ・ Dec 3 '24&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#mock&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>mock</category>
    </item>
    <item>
      <title>Hexagonal architecture - Another way to the hexagone</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Sun, 18 Jan 2026 11:45:52 +0000</pubDate>
      <link>https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0</link>
      <guid>https://dev.to/marabesi/hexagonal-architecture-another-way-to-the-hexagone-25g0</guid>
      <description>&lt;h2&gt;
  
  
  Theory
&lt;/h2&gt;

&lt;p&gt;Hexagonal Architecture, also known as the Ports and Adapters pattern, offers a powerful way to design software systems that are modular, testable, and adaptable to change. This architectural style emphasizes the separation of concerns, ensuring that core business logic remains independent of external systems such as databases, user interfaces, or third-party services.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll explore Hexagonal Architecture in two parts. The first part dives into the theory, explaining its principles, benefits, and how it contrasts with traditional layered architectures. The second part brings these concepts to life with a real-world implementation based on my interpretation of Hexagonal Architecture, demonstrating how to structure code for flexibility and maintainability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hexagonal
&lt;/h3&gt;

&lt;p&gt;I got to know hex architecture (I am going to follow this pattern from now on to refer to the hexagonal architecture) in the clean &lt;a href="https://marabesi.com/architecture/2020/05/22/clean-architecture.html" rel="noopener noreferrer"&gt;architecture book&lt;/a&gt;, indeed it was inspired by Uncle Bob to get the clean architecture in place. Alistair Cockburn realized that there was a different approach to building applications instead of the classical layered architecture:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The attempted solution, repeated in many organizations, is to create a new layer in the architecture, with the promise that this time, really and truly no business logic will be put into the new layer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A more flexible way of dealing with different adapters in the application and using the same code to process business rules. Even though experts argue that there are differences between open and closed layers, to avoid such interactions or constraint violations, in the hex architecture the approach is different stating that the goal is to avoid it by design instead of trying to enforce a constraint. Nevertheless, Stenber in his &lt;a href="https://www.infoq.com/news/2014/10/exploring-hexagonal-architecture" rel="noopener noreferrer"&gt;blog written for infoQ&lt;/a&gt; says that hexagonal architecture is an example of a layered architecture as it conforms to all the constraints and properties of a layered architecture.&lt;/p&gt;

&lt;p&gt;Hexagonal vs Clean Architecture?&lt;/p&gt;

&lt;p&gt;Hexagonal architecture is usually mixed with &lt;a href="https://marabesi.com/architecture/2020/05/22/clean-architecture.html" rel="noopener noreferrer"&gt;clean architecture&lt;/a&gt;, even though, it was used as an inspiration for the clean architecture, they are different. Valentina Cupác&lt;br&gt;
describes that in &lt;a href="https://www.youtube.com/watch?v=IZWLnn2fNko" rel="noopener noreferrer"&gt;her talk&lt;/a&gt; with details.&lt;/p&gt;

&lt;p&gt;In my observations throughout code bases, both are often mixed together. However, Clean Architecture is more prescriptive than Hexagonal Architecture. For example, &lt;a href="https://jmgarridopaz.github.io/content/hexagonalarchitecture.html" rel="noopener noreferrer"&gt;Juan Manuel Garrido de Paz&lt;/a&gt;&lt;br&gt;
describes that "Ports &amp;amp; Adapters pattern says nothing about the structure of the inside of the hexagon." Ports &amp;amp; Adapters is another way to name the same architectural style.&lt;/p&gt;

&lt;p&gt;Which goes against the opinion from &lt;a href="https://jmgarridopaz.github.io/content/hexagonalarchitecture.html" rel="noopener noreferrer"&gt;Juan Manuel&lt;/a&gt;, who says that the "pattern" says nothing about layers. However, what I see lacking in his argument is: what is a layer anyway? Such an abstract definition as an architectural style may be interpreted differently by different people, which leads to those different opinions. The naming "layer" might be too abstract, leading to confusion when communicating the same idea.&lt;/p&gt;

&lt;p&gt;Another way to the hexagone&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLGl1Jc8ErU1w27y8-7Gdcloy1tHO7NriL" rel="noopener noreferrer"&gt;Alistair in the "hexagone" - YouTube playlist DDD - FR&lt;/a&gt; elaborates on his insights when developing and formalizing the architectural style that is widely known today by developers. For curious people, this is a video that explains the why's behind the naming, the decision and the need from Alistair to create the style.&lt;/p&gt;

&lt;h3&gt;
  
  
  Definition
&lt;/h3&gt;

&lt;p&gt;Let's start with the &lt;a href="https://alistair.cockburn.us/hexagonal-architecture" rel="noopener noreferrer"&gt;diagram from the architectural style creator Alistair Cockburn&lt;/a&gt; that has this image in his blog post:&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%2Ff9wdziejgzmug7qal2jz.png" 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%2Ff9wdziejgzmug7qal2jz.png" alt="Diagram representing the hexagonal architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hexagonal architecture is defined in different aspects. These aspects are something that was created to define this architectural style, and I believe they are the key:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ports, as the author describes "The term “port and adapters” picks up the ‘’purposes’’ of the parts of the drawing. A port identifies a purposeful conversation".&lt;/li&gt;
&lt;li&gt;adapters, you might have many adapters for a single port.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the &lt;a href="https://marabesi.com/software-architecture/hexagonal-architecture.html#strategic_monoliths_and_microservices" rel="noopener noreferrer"&gt;book Strategic Monoliths and Microservices &lt;/a&gt;&lt;br&gt;
Vaughn Vernon and Tomasz Jaskula also used a similar definition, on the other hand, what caught my attention to their definition is the way used to differentiate the layered architecture from hexagonal.&lt;/p&gt;

&lt;p&gt;Ports and Adapters are the one of the aspects of this architectural style that deserves attention. A driver adapter implements a driver port interface, translating requests from a specific technology into a technology-agnostic format that the driver port can understand and process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jmgarridopaz.github.io/content/hexagonalarchitecture.html" rel="noopener noreferrer"&gt;Paz&lt;/a&gt; uses the naming "Driver" to refer to the interface that will control how to interact with the application and "Driven" to refer to the interface that will act as an output boundary.&lt;/p&gt;



  A note on the implementation




In my implementation that is referenced later in this post, I used the naming "inbound" and "outbound" to refer to the
interfaces that are used to interact with the application. The inbound is the interface that is used to interact with
the application, while the outbound is the interface that is used to interact with the external systems:

- inbound: Driver
- outbound: Driven





&lt;p&gt;In that sense, the driver can be a CLI, a GUI, or even a REST API, while the driven can be a database, a message broker, or any external system that the application interacts with.&lt;/p&gt;
&lt;h3&gt;
  
  
  What are the disadvantages of hexagonal architecture?
&lt;/h3&gt;

&lt;p&gt;At first, the hexagonal architecture seems to be a magical approach that will automagically give testability to any application, at least this is what &lt;a href="https://marabesi.com/testing/2023/01/31/is-there-a-testable-architecture.html" rel="noopener noreferrer"&gt;some of the articles&lt;/a&gt; on the web sells the hexagonal architecture. Nevertheless, some of the implications that come when adopting hexagonal architecture are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The developer experience: as the implementation of hexagonal architecture depends on interpretation, it varies based on the programming language and the years of experience of the developer writing the code. Hexagonal architecture usually is not the first style that one starts with. It is MVC that comes embedded in different frameworks.&lt;/li&gt;
&lt;li&gt;The understanding of the developer on the libraries and the frameworks being used: the different ecosystems of different programming languages bring challenges as they offer a pre-created structure of how the problem should be solved. Understanding each piece of them is key to creating abstraction to create the inside and the outside of the hexagon. For example, Davi Vieira shared his opinions on implementing hexagonal architecture with Java in the book "Designing Hexagonal Architecture with Java".&lt;/li&gt;
&lt;li&gt;Other architectural styles are also testable: other styles are posed as "not testable" or that are difficult to test, regardless, frameworks are set to use the famous Model-View-Controller.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Being said that, the shift to using hex architecture is mostly due to the developer experience at hand. With experience, the other points mentioned will have less impact.&lt;/p&gt;
&lt;h3&gt;
  
  
  Related subjects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=u6oTg5oRH24" rel="noopener noreferrer"&gt;Gordon Skinner - Hexagonal Architecture in DDD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.goodreads.com/book/show/15756865-implementing-domain-driven-design" rel="noopener noreferrer"&gt;Implementing Domain-Driven-Design by Vaughn Vernon&lt;/a&gt; - Chapter 4.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to%20post_url%202020-10-17-software-architecture-patterns%20"&gt;Software architecture patterns&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;Stenber, J. (2014). Exploring the Hexagonal Architecture. &lt;a href="https://www.infoq.com/news/2014/10/exploring-hexagonal-architecture" rel="noopener noreferrer"&gt;https://www.infoq.com/news/2014/10/exploring-hexagonal-architecture&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vaughn Vernon, T. J. (2021). Strategic Monoliths and Microservices. The Addison-Wesley Signature Series.&lt;/p&gt;

&lt;p&gt;Vieira, D. (2021). Designing Hexagonal Architecture with Java: An architect’s guide to building maintainable and change-tolerant applications with Java and Quarkus. Packt Publishing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hexagonal in practice
&lt;/h2&gt;

&lt;p&gt;Let's dive into the implementation of this architectural style to translate the theory into concrete implementation. We will&lt;br&gt;
do that through a fictitious application that is used for scheduling posts on social media.&lt;/p&gt;
&lt;h3&gt;
  
  
  Problem statement
&lt;/h3&gt;

&lt;p&gt;Given the number of people who are generating content for social media and making it a business is increasing, the need for automated tools to support the day-to-day work of those people also increases. Creating, scheduling, and sending content to those platforms are some of the focuses of social publisher.&lt;/p&gt;
&lt;h3&gt;
  
  
  Social publisher
&lt;/h3&gt;

&lt;p&gt;To depict what I have implemented thinking about hexagonal architecture we will use this made up business that aims at posting&lt;br&gt;
content into social media, currently the application is used through the Command Line Interface and it was built using kotlin. Let's dive into the features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create posts and focus on the content&lt;/li&gt;
&lt;li&gt;Delete posts&lt;/li&gt;
&lt;li&gt;Schedule posts to be sent based on a date and time&lt;/li&gt;
&lt;li&gt;Send posts to social media (X.com is supported for the time being)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The source code for social publisher is available on &lt;a href="https://github.com/marabesi/social-publisher" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Structure overview
&lt;/h3&gt;

&lt;p&gt;The packages of the application were split into application and adapters. The aim was to be strict with the naming from the image and explanation from Alistair in his interpretation of the architecture. The application has all the business logic needed to fulfill the requirements of scheduling and posting. The adapters, on the other hand, were split into two: the inbound and the outbound. The idea is as follows:&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%2Fivhnms38kwbb85yzdvbl.png" 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%2Fivhnms38kwbb85yzdvbl.png" alt="Package diagram representing the hexagonal architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inbound are the adapters that offer input to the application. In this case, it is only the CLI. Outbound represents&lt;br&gt;
the output that the application writes to. In this case, the CLI as well as storing the data in CSV.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src/main/kotlin/
├── Main.kt
├── adapters
│   ├── inbound
│   │   └── cli
│   │       ├── CliFactory.kt
│   │       ├── Configuration.kt
│   │       ├── Post.kt
│   │       ├── Poster.kt
│   │       └── scheduler
│   │           ├── Scheduler.kt
│   │           ├── SchedulerCreate.kt
│   │           ├── SchedulerDelete.kt
│   │           └── SchedulerList.kt
│   └── outbound
│       ├── cli
│       │   └── CliOutput.kt
│       ├── csv
│       │   ├── FileSystemConfigurationRepository.kt
│       │   ├── FileSystemPostRepository.kt
│       │   └── FileSystemSchedulerRepository.kt
│       ├── inmemory
│       │   ├── ConfigurationInMemoryRepository.kt
│       │   ├── InMemoryPostRepository.kt
│       │   └── InMemorySchedulerRepository.kt
│       └── social
│           ├── CouldNotCreateTweetException.kt
│           ├── CreateTweet.kt
│           ├── DeleteTweet.kt
│           └── TwitterCredentialsValidator.kt
└── application
    ├── Messages.kt
    ├── Output.kt
    ├── configuration
    │   ├── ConfigurationGivenHasInvalidProperty.kt
    │   ├── Create.kt
    │   └── List.kt
    ├── entities
    │   ├── ScheduledItem.kt
    │   ├── SocialConfiguration.kt
    │   └── SocialPosts.kt
    ├── persistence
    │   ├── PostsRepository.kt
    │   ├── SchedulerRepository.kt
    │   └── configuration
    │       ├── ConfigurationRepository.kt
    │       └── MissingConfiguration.kt
    ├── post
    │   ├── Create.kt
    │   └── List.kt
    ├── poster
    │   └── Executor.kt
    ├── scheduler
    │   ├── Create.kt
    │   ├── List.kt
    │   ├── SocialMedia.kt
    │   └── filters
    │       ├── Criterion.kt
    │       ├── DateTimeValidation.kt
    │       ├── StartDate.kt
    │       └── UntilDate.kt
    └── socialnetwork
        ├── CreateTweet.kt
        ├── DeleteTweet.kt
        ├── MissingConfigurationSetup.kt
        └── SocialThirdParty.kt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As previously mentioned, the structure of the application focuses only on representing the architectural style to communicate&lt;br&gt;
with maintainers how the code should be structured.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing approach
&lt;/h3&gt;

&lt;p&gt;Given an already defined architectural style, the testing strategy also has already structured boundaries to be followed. In this structure, the application is tested based on the boundaries defined at the architectural layer.&lt;/p&gt;

&lt;p&gt;For example, adapters are tested in isolation, which helps with testability of edge cases and granular complexity. The inbound,&lt;br&gt;
which is used here, is tested through a CLI application. The outbound adapters, defined as the adapters that talk with the external world, are also tested in isolation. The last layer is the e2e testing that is done using the defined adapters in the configuration. Later on, I found that &lt;a href="http://www.natpryce.com/articles/000772.html" rel="noopener noreferrer"&gt;Nat Pryce depicts this in detail&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>opensource</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Thu, 20 Nov 2025 13:08:28 +0000</pubDate>
      <link>https://dev.to/marabesi/-4ah1</link>
      <guid>https://dev.to/marabesi/-4ah1</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/_vjk/the-tdd-ai-revolution-how-systematic-refactoring-beats-the-move-fast-and-break-things-mentality-12co" class="crayons-story__hidden-navigation-link"&gt;The TDD + AI Revolution: How Systematic Refactoring Beats the "Move Fast and Break Things" Mentality&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/_vjk" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F100128%2F6fbe85b3-c5e2-494b-a165-ea5eb819aecd.png" alt="_vjk profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/_vjk" class="crayons-story__secondary fw-medium m:hidden"&gt;
              v.j.k. 
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                v.j.k. 
                
              
              &lt;div id="story-author-preview-content-2619146" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/_vjk" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F100128%2F6fbe85b3-c5e2-494b-a165-ea5eb819aecd.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;v.j.k. &lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/_vjk/the-tdd-ai-revolution-how-systematic-refactoring-beats-the-move-fast-and-break-things-mentality-12co" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 23 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/_vjk/the-tdd-ai-revolution-how-systematic-refactoring-beats-the-move-fast-and-break-things-mentality-12co" id="article-link-2619146"&gt;
          The TDD + AI Revolution: How Systematic Refactoring Beats the "Move Fast and Break Things" Mentality
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tdd"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tdd&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cursor"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cursor&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/development"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;development&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/_vjk/the-tdd-ai-revolution-how-systematic-refactoring-beats-the-move-fast-and-break-things-mentality-12co" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt; reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/_vjk/the-tdd-ai-revolution-how-systematic-refactoring-beats-the-move-fast-and-break-things-mentality-12co#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            13 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>tdd</category>
      <category>cursor</category>
      <category>development</category>
    </item>
    <item>
      <title>2025 edition is live: https://thestateoftdd.org/2025</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Wed, 19 Nov 2025 20:27:15 +0000</pubDate>
      <link>https://dev.to/marabesi/2025-edition-is-live-httpsthestateoftddorg2025-5hic</link>
      <guid>https://dev.to/marabesi/2025-edition-is-live-httpsthestateoftddorg2025-5hic</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39" class="crayons-story__hidden-navigation-link"&gt;Shaping the state of Test-Driven Development&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/marabesi" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" alt="marabesi profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/marabesi" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Marabesi
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Marabesi
                
              
              &lt;div id="story-author-preview-content-2032110" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/marabesi" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Marabesi&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 10 '24&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39" id="article-link-2032110"&gt;
          Shaping the state of Test-Driven Development
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tdd"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tdd&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/development"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;development&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://thestateoftdd.org/2025/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;thestateoftdd.org&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




</description>
      <category>tdd</category>
      <category>development</category>
      <category>programming</category>
    </item>
    <item>
      <title>2025 edition is live: https://thestateoftdd.org/2025</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Sat, 11 Oct 2025 12:07:57 +0000</pubDate>
      <link>https://dev.to/marabesi/2025-edition-is-live-httpsthestateoftddorg2025-188g</link>
      <guid>https://dev.to/marabesi/2025-edition-is-live-httpsthestateoftddorg2025-188g</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39" class="crayons-story__hidden-navigation-link"&gt;Shaping the state of Test-Driven Development&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/marabesi" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" alt="marabesi profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/marabesi" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Marabesi
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Marabesi
                
              
              &lt;div id="story-author-preview-content-2032110" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/marabesi" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Marabesi&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 10 '24&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39" id="article-link-2032110"&gt;
          Shaping the state of Test-Driven Development
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tdd"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tdd&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/development"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;development&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/marabesi/shaping-the-state-of-test-driven-development-1i39#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://thestateoftdd.org/2025/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;thestateoftdd.org&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




</description>
      <category>tdd</category>
      <category>development</category>
      <category>programming</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Sat, 11 Oct 2025 12:06:52 +0000</pubDate>
      <link>https://dev.to/marabesi/-5fb1</link>
      <guid>https://dev.to/marabesi/-5fb1</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59" class="crayons-story__hidden-navigation-link"&gt;AI and TDD - A match that can work?&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/marabesi" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" alt="marabesi profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/marabesi" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Marabesi
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Marabesi
                
              
              &lt;div id="story-author-preview-content-2640249" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/marabesi" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Marabesi&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 30 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59" id="article-link-2640249"&gt;
          AI and TDD - A match that can work?
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tdd"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tdd&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/githubcopilot"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;githubcopilot&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/testing"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;testing&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>programming</category>
      <category>tdd</category>
      <category>githubcopilot</category>
      <category>testing</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Wed, 03 Sep 2025 19:34:41 +0000</pubDate>
      <link>https://dev.to/marabesi/-5gg7</link>
      <guid>https://dev.to/marabesi/-5gg7</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/marabesi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" alt="marabesi"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/marabesi/the-one-thing-vitest-has-better-support-than-jest-31en" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;The one thing Vitest has better support than Jest&lt;/h2&gt;
      &lt;h3&gt;Marabesi ・ Apr 22&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#jest&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#vitest&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>jest</category>
      <category>vitest</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Wed, 20 Aug 2025 18:29:54 +0000</pubDate>
      <link>https://dev.to/marabesi/-10dd</link>
      <guid>https://dev.to/marabesi/-10dd</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59" class="crayons-story__hidden-navigation-link"&gt;AI and TDD - A match that can work?&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/marabesi" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" alt="marabesi profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/marabesi" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Marabesi
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Marabesi
                
              
              &lt;div id="story-author-preview-content-2640249" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/marabesi" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Marabesi&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 30 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59" id="article-link-2640249"&gt;
          AI and TDD - A match that can work?
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tdd"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tdd&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/githubcopilot"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;githubcopilot&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/testing"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;testing&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/marabesi/ai-and-tdd-a-match-that-can-work-1d59#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>programming</category>
      <category>tdd</category>
      <category>githubcopilot</category>
      <category>testing</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Marabesi</dc:creator>
      <pubDate>Mon, 18 Aug 2025 18:52:04 +0000</pubDate>
      <link>https://dev.to/marabesi/-24eg</link>
      <guid>https://dev.to/marabesi/-24eg</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/marabesi/testing-reactjs-context-a-guide-with-test-doubles-3ap3" class="crayons-story__hidden-navigation-link"&gt;Testing ReactJS Context - A Guide with test-doubles&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/marabesi" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" alt="marabesi profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/marabesi" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Marabesi
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Marabesi
                
              
              &lt;div id="story-author-preview-content-2131818" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/marabesi" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F685103%2F5b20a6a8-bbb7-4885-8cb2-c2db94c09c50.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Marabesi&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/marabesi/testing-reactjs-context-a-guide-with-test-doubles-3ap3" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Dec 3 '24&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/marabesi/testing-reactjs-context-a-guide-with-test-doubles-3ap3" id="article-link-2131818"&gt;
          Testing ReactJS Context - A Guide with test-doubles
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/react"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;react&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mock"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mock&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/marabesi/testing-reactjs-context-a-guide-with-test-doubles-3ap3" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;3&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/marabesi/testing-reactjs-context-a-guide-with-test-doubles-3ap3#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>mock</category>
    </item>
  </channel>
</rss>
