<?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: Luka Jioshvili</title>
    <description>The latest articles on DEV Community by Luka Jioshvili (@lazydoomslayer).</description>
    <link>https://dev.to/lazydoomslayer</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3290294%2F8e5e1879-5e33-45e1-897f-7e08fb78030c.jpg</url>
      <title>DEV Community: Luka Jioshvili</title>
      <link>https://dev.to/lazydoomslayer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lazydoomslayer"/>
    <language>en</language>
    <item>
      <title>How I Build Vue 3 Applications (Part 2): How I Decide Where Every Component Belongs</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Fri, 10 Jul 2026 14:31:44 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/how-i-build-vue-3-applications-part-2-how-i-decide-where-every-component-belongs-26ac</link>
      <guid>https://dev.to/lazydoomslayer/how-i-build-vue-3-applications-part-2-how-i-decide-where-every-component-belongs-26ac</guid>
      <description>&lt;p&gt;One of the hardest decisions in a growing Vue application isn't writing components.&lt;/p&gt;

&lt;p&gt;It's deciding &lt;strong&gt;who owns them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most projects don't struggle with this on day one.&lt;/p&gt;

&lt;p&gt;They struggle six months later, when hundreds of components exist and every new file raises the same question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where should this component live?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Over the years, I've settled on a simple decision process that helps me answer that question consistently.&lt;/p&gt;

&lt;p&gt;In this article, I'll walk through the questions I ask before creating any new component and explain how those answers determine where it belongs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why does the &lt;code&gt;components/&lt;/code&gt; folder eventually become a mess?
&lt;/h2&gt;

&lt;p&gt;At the beginning of a project, almost &lt;strong&gt;any component organization&lt;/strong&gt; feels reasonable.&lt;/p&gt;

&lt;p&gt;With only a handful of components, it's easy to remember where everything lives because &lt;strong&gt;your mental map is still small&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As the application grows, that changes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;New features introduce dialogs, cards, tables, forms, widgets, and other supporting components.&lt;/p&gt;

&lt;p&gt;Eventually, the &lt;code&gt;components/&lt;/code&gt; directory becomes a long list of unrelated files.&lt;/p&gt;

&lt;p&gt;Nothing is technically wrong.&lt;/p&gt;

&lt;p&gt;But every new component becomes a small architectural decision.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp9zuwotwhyugz4nydp6j.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp9zuwotwhyugz4nydp6j.png" alt="Component Folder Overview" width="800" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The problem isn't the number of components.&lt;/p&gt;

&lt;p&gt;It's what happens to &lt;strong&gt;your mental model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of immediately knowing where something belongs, you start relying on search. Related components become scattered, and the business context begins to disappear.&lt;/p&gt;

&lt;p&gt;You're no longer thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"I'm working on Billing."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead, you're jumping between dialogs, tables, widgets, and cards just to understand a single feature.&lt;/p&gt;

&lt;p&gt;As the project grows, understanding the impact of a change becomes harder, making accidental regressions more likely.&lt;/p&gt;

&lt;p&gt;For me, this isn't just a folder problem.&lt;/p&gt;

&lt;p&gt;It's a &lt;strong&gt;cognitive problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As I mentioned in &lt;strong&gt;Part 1&lt;/strong&gt;, I want to understand &lt;strong&gt;what I'm looking at before opening a file&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The same principle applies to components.&lt;/p&gt;

&lt;p&gt;So before I create a new component, I don't ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Which folder should I put this in?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead, I ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Who owns this component?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once I can answer that question, choosing where it belongs becomes almost obvious.&lt;/p&gt;




&lt;h2&gt;
  
  
  What makes a component a UI component?
&lt;/h2&gt;

&lt;p&gt;The first question I ask whenever I create a new component is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can another feature reuse it?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is &lt;strong&gt;yes&lt;/strong&gt;, it belongs in &lt;code&gt;components/ui&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;UI components are &lt;strong&gt;business-agnostic&lt;/strong&gt;. They shouldn't know anything about billing, users, products, sessions, or any other feature.&lt;/p&gt;

&lt;p&gt;Instead, they provide reusable building blocks that every feature can compose.&lt;/p&gt;

&lt;p&gt;Common examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Buttons&lt;/li&gt;
&lt;li&gt;Inputs&lt;/li&gt;
&lt;li&gt;Dialogs&lt;/li&gt;
&lt;li&gt;Tooltips&lt;/li&gt;
&lt;li&gt;Avatars&lt;/li&gt;
&lt;li&gt;Checkboxes&lt;/li&gt;
&lt;li&gt;Badges&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good rule of thumb is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If I could copy this component into another project without changing its behavior, it's probably a UI component.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the decision tree I mentally follow whenever I create a component.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffzyxb2jbbvskvtv1o07u.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffzyxb2jbbvskvtv1o07u.png" alt="Decisitons" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that decision is made, the folder structure becomes almost obvious.&lt;/p&gt;

&lt;p&gt;Here's what that looks like:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy71dgmw0k73iov0lwqjo.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy71dgmw0k73iov0lwqjo.png" alt="Structure" width="800" height="638"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the folders are organized by &lt;strong&gt;UI responsibility&lt;/strong&gt;, not by business domain.&lt;/p&gt;

&lt;p&gt;Buttons live together.&lt;/p&gt;

&lt;p&gt;Inputs live together.&lt;/p&gt;

&lt;p&gt;Dialogs live together.&lt;/p&gt;

&lt;p&gt;Icons live together.&lt;/p&gt;

&lt;p&gt;Every category answers the same question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What kind of UI element is this?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal isn't to create the perfect hierarchy, it's to make new components obvious to place and existing ones easy to discover.&lt;/p&gt;




&lt;h2&gt;
  
  
  Feature Components
&lt;/h2&gt;

&lt;p&gt;If the component isn't reusable across the application, I ask another question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Is it owned by a single business feature?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is &lt;strong&gt;yes&lt;/strong&gt;, it belongs in &lt;code&gt;components/features&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Feature components represent &lt;strong&gt;actual product functionality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Unlike UI components, they understand the business they're built for.&lt;/p&gt;

&lt;p&gt;That means they're free to depend on services, stores, composables, domain models, and business rules, because &lt;strong&gt;that feature owns them&lt;/strong&gt;.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnybjjigj9yzqi2rghsjo.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnybjjigj9yzqi2rghsjo.png" alt="Feature Components" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These components aren't designed to be shared across unrelated parts of the application.&lt;/p&gt;

&lt;p&gt;They're designed to solve &lt;strong&gt;one business problem&lt;/strong&gt; well.&lt;/p&gt;

&lt;p&gt;A good rule I follow is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If another feature needs this component, I don't immediately move it to &lt;code&gt;ui&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Duplicating a small component is often cheaper than introducing a premature abstraction.&lt;/p&gt;

&lt;p&gt;Only after a component proves it's truly shared do I consider promoting it into &lt;code&gt;components/ui&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layout Components
&lt;/h2&gt;

&lt;p&gt;Not every component belongs to a business feature.&lt;/p&gt;

&lt;p&gt;Some components define &lt;strong&gt;the application's shell&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Business features live &lt;strong&gt;inside&lt;/strong&gt; them not the other way around.&lt;/p&gt;

&lt;p&gt;A simple rule I use is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If removing every business feature still leaves this component useful, it's probably a layout component.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's what that relationship looks like:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjsfiw42pjd4rwinc5umd.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjsfiw42pjd4rwinc5umd.png" alt="Application Shell" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Layout components aren't owned by Billing, Products, or Users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;They're owned by the application itself.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Transition Components
&lt;/h2&gt;

&lt;p&gt;Some components exist for one reason only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Animation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They shouldn't contain business logic.&lt;/p&gt;

&lt;p&gt;They shouldn't know anything about billing, users, products, or sessions.&lt;/p&gt;

&lt;p&gt;Their only responsibility is providing reusable animations on top of Vue's &lt;code&gt;&amp;lt;Transition&amp;gt;&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FadeTransition&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ExpandYTransition&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ExpandXTransition&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Separating them keeps animations consistent throughout the application while avoiding duplicated transition code.&lt;/p&gt;

&lt;p&gt;More importantly, it creates &lt;strong&gt;one source of truth&lt;/strong&gt; for how things move.&lt;/p&gt;

&lt;p&gt;I don't want five slightly different fade animations scattered throughout the project.&lt;/p&gt;

&lt;p&gt;I want one.&lt;/p&gt;

&lt;p&gt;If I decide to tweak the animation timing, easing, or behavior, I change it once and every feature benefits.&lt;/p&gt;

&lt;p&gt;Here's what that looks like in practice.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwel977fdhs2ex24ddcbg.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwel977fdhs2ex24ddcbg.png" alt="Transition Components" width="799" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's why transition components have their own home.&lt;/p&gt;

&lt;p&gt;Their responsibility isn't business logic.&lt;/p&gt;

&lt;p&gt;It's making the entire application feel consistent.&lt;/p&gt;




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

&lt;p&gt;There is no single "correct" way to organize components.&lt;/p&gt;

&lt;p&gt;Every application grows differently, every team develops its own conventions, and every architecture evolves over time.&lt;/p&gt;

&lt;p&gt;The approach I've shared isn't about finding the perfect folder structure.&lt;/p&gt;

&lt;p&gt;It's about reducing the number of decisions you have to make every day.&lt;/p&gt;

&lt;p&gt;For me, that starts with a single question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Who owns this component?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once I can answer that, where it belongs is usually obvious.&lt;/p&gt;

&lt;p&gt;That simple shift has made my Vue applications easier to navigate, easier to maintain, and easier to scale as they grow.&lt;/p&gt;

&lt;p&gt;Like the hybrid folder structure from Part 1, this isn't a universal rule, it's simply the approach I've refined over the years, and it continues to evolve with every project.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I Build Vue 3 Applications (Part 1): Why I Use a Hybrid Folder Structure</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Mon, 06 Jul 2026 13:05:23 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/how-i-build-vue-3-applications-part-1-why-i-use-a-hybrid-folder-structure-48c2</link>
      <guid>https://dev.to/lazydoomslayer/how-i-build-vue-3-applications-part-1-why-i-use-a-hybrid-folder-structure-48c2</guid>
      <description>&lt;p&gt;When a Vue project starts, almost any folder structure works. With only a handful of components and pages, it’s easy to find what you’re looking for.&lt;/p&gt;

&lt;p&gt;The challenge begins as the application grows. More features are added, more developers join the project, and suddenly finding the right file takes longer than writing it.&lt;/p&gt;

&lt;p&gt;Over the years, I’ve experimented with different ways of organizing Vue applications. Instead of choosing between a &lt;strong&gt;responsibility-first&lt;/strong&gt; structure (&lt;code&gt;components&lt;/code&gt;, &lt;code&gt;services&lt;/code&gt;, &lt;code&gt;stores&lt;/code&gt;…) and a &lt;strong&gt;feature-first&lt;/strong&gt; structure (&lt;code&gt;billing&lt;/code&gt;, &lt;code&gt;users&lt;/code&gt;, &lt;code&gt;products&lt;/code&gt;…), I settled on combining both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My approach is simple: organize the project by responsibility at the root, then organize business-specific code by feature inside those responsibilities.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I call this a &lt;strong&gt;hybrid folder structure&lt;/strong&gt;, and in this article I’ll explain why it has worked well for me.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Two Common Approaches
&lt;/h2&gt;

&lt;p&gt;In my experience, most Vue project structures fall into &lt;strong&gt;one of two categories&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Some teams organize everything by &lt;strong&gt;responsibility&lt;/strong&gt; (or file type), while others organize everything by &lt;strong&gt;feature&lt;/strong&gt; (or domain). Both approaches have their strengths, and both have trade-offs.&lt;/p&gt;

&lt;p&gt;Let's look at each one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Organizing by Responsibility
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;responsibility-first&lt;/strong&gt; structure groups files by &lt;strong&gt;what they do&lt;/strong&gt;.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fig8z9d5jk1p02pzc6xcb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fig8z9d5jk1p02pzc6xcb.png" alt="Responsibility Overview" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is probably the most common structure you'll see in Vue projects. It's &lt;strong&gt;simple&lt;/strong&gt;, &lt;strong&gt;familiar&lt;/strong&gt;, and easy for new developers to navigate. If you're looking for a component, you open &lt;code&gt;components/&lt;/code&gt;. If you need a Pinia store, you know exactly where to find it.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;small and medium-sized projects&lt;/strong&gt;, this works extremely well.&lt;/p&gt;

&lt;p&gt;However, as the application grows, a &lt;strong&gt;single feature&lt;/strong&gt; becomes spread across multiple directories. Implementing or modifying one feature often means jumping between &lt;code&gt;components/&lt;/code&gt;, &lt;code&gt;services/&lt;/code&gt;, &lt;code&gt;store/&lt;/code&gt;, &lt;code&gt;types/&lt;/code&gt;, and &lt;code&gt;composables/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The structure is &lt;strong&gt;predictable&lt;/strong&gt;, but the feature itself becomes &lt;strong&gt;fragmented&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Trade-off&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finding a specific &lt;strong&gt;type of file&lt;/strong&gt; is easy.&lt;br&gt;
Working on a specific &lt;strong&gt;business feature&lt;/strong&gt; becomes harder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Organizing by Feature
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;feature-first&lt;/strong&gt; structure takes the opposite approach.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8c8y2qi3qtx11vuyzts1.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8c8y2qi3qtx11vuyzts1.png" alt="Feature Overfiew" width="799" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything related to a &lt;strong&gt;business feature&lt;/strong&gt; lives together. Components, composables, services, stores, and types are colocated inside the same directory.&lt;/p&gt;

&lt;p&gt;This makes working on a &lt;strong&gt;single feature&lt;/strong&gt; very convenient because almost everything you need is in one place.&lt;/p&gt;

&lt;p&gt;However, I personally found that this approach introduces a different challenge. &lt;strong&gt;Not everything in an application belongs to a single business feature.&lt;/strong&gt; Shared UI components, layouts, transitions, global composables, application configuration, and other &lt;strong&gt;cross-cutting concerns&lt;/strong&gt; still need their own place.&lt;/p&gt;

&lt;p&gt;For the kinds of applications I build, a &lt;strong&gt;purely feature-based&lt;/strong&gt; structure felt like solving one problem while creating another.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Trade-off&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Working on a specific &lt;strong&gt;feature&lt;/strong&gt; is easy.&lt;br&gt;
Organizing &lt;strong&gt;shared application code&lt;/strong&gt; becomes more challenging.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;After working with both approaches, I found myself naturally combining them.&lt;/p&gt;

&lt;p&gt;I wanted the &lt;strong&gt;predictability&lt;/strong&gt; of a &lt;strong&gt;responsibility-first&lt;/strong&gt; structure while keeping &lt;strong&gt;feature-specific code&lt;/strong&gt; grouped together.&lt;/p&gt;

&lt;p&gt;That eventually led me to the hybrid structure I use today.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hybrid Structure I Use
&lt;/h2&gt;

&lt;p&gt;My approach follows one simple principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Responsibility first. Feature second.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At the root of the project, I organize files by &lt;strong&gt;responsibility&lt;/strong&gt;.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxd1e8l3s7dwzc0b1t0a1.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxd1e8l3s7dwzc0b1t0a1.png" alt="Project Sturcture Overview" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every top-level folder answers the first question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What kind of file is this?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;components/&lt;/code&gt; contains UI components.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;composables/&lt;/code&gt; contains reusable reactive logic.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;services/&lt;/code&gt; contains business operations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;store/&lt;/code&gt; contains Pinia stores.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;types/&lt;/code&gt; contains TypeScript contracts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, organizing by responsibility only solves &lt;strong&gt;half of the problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It tells me &lt;strong&gt;what&lt;/strong&gt; a file is, but not &lt;strong&gt;which feature&lt;/strong&gt; it belongs to.&lt;/p&gt;

&lt;p&gt;That's where the second part of my approach comes in.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa3jpzykd3qkcjmpdtpiq.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa3jpzykd3qkcjmpdtpiq.png" alt="Src overview" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside each responsibility, I organize code by &lt;strong&gt;feature&lt;/strong&gt; or &lt;strong&gt;business domain&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, components related to billing stay together, pricing services stay together, and product composables stay together.&lt;/p&gt;

&lt;p&gt;This keeps feature-specific code close together without sacrificing the predictability of the project's top-level structure.&lt;/p&gt;

&lt;p&gt;The result is neither a purely &lt;strong&gt;responsibility-first&lt;/strong&gt; nor a purely &lt;strong&gt;feature-first&lt;/strong&gt; architecture.&lt;/p&gt;

&lt;p&gt;Instead, it follows one simple principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Responsibility first. Feature second.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  File Names Are Part of the Architecture
&lt;/h2&gt;

&lt;p&gt;One thing I care about a lot is file naming.&lt;/p&gt;

&lt;p&gt;I use suffixes like:&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="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;helper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;guard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may look like a small detail, but it improves searchability a lot.&lt;/p&gt;

&lt;p&gt;When I search for product, I can quickly understand what each file does:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5k6s51ruggs12c0f5moq.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5k6s51ruggs12c0f5moq.png" alt="Searching into" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I should be able to understand what a file probably does before opening it.&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;There is no single "correct" way to organize a Vue application.&lt;/p&gt;

&lt;p&gt;Every team, product, and codebase has different requirements.&lt;/p&gt;

&lt;p&gt;This hybrid approach has worked well for me because it keeps the project predictable while making feature-specific code easy to find and maintain. More importantly, it gives me a simple mental model that scales as the application grows.&lt;/p&gt;

&lt;p&gt;This is simply the approach I've refined over the years, and it continues to evolve with every project.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Building Software Beyond the Browser</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Thu, 14 May 2026 07:53:02 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/building-software-beyond-the-browser-175j</link>
      <guid>https://dev.to/lazydoomslayer/building-software-beyond-the-browser-175j</guid>
      <description>&lt;p&gt;For the last 3 years, most of my work lived inside the browser.&lt;/p&gt;

&lt;p&gt;Vue.js SPA development, Nuxt applications, frontend architecture, SEO optimizations the usual frontend ecosystem.&lt;/p&gt;

&lt;p&gt;And honestly, after some time, I started feeling limited.&lt;/p&gt;

&lt;p&gt;Not because frontend development became bad or boring, but because I felt like I was mostly moving inside the same boundaries over and over again.&lt;/p&gt;

&lt;p&gt;The only thing that still looked extremely interesting to me on the frontend side was probably Three.js, but I never really found a practical place where I could meaningfully use it.&lt;/p&gt;

&lt;p&gt;At some point, I realized I wanted to build software that could do more than a browser tab allows.&lt;/p&gt;

&lt;p&gt;I wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;direct operating system interaction&lt;/li&gt;
&lt;li&gt;process management&lt;/li&gt;
&lt;li&gt;local-first tooling&lt;/li&gt;
&lt;li&gt;background tasks&lt;/li&gt;
&lt;li&gt;hardware communication&lt;/li&gt;
&lt;li&gt;system utilities&lt;/li&gt;
&lt;li&gt;applications that continue running outside the browser lifecycle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That curiosity slowly pushed me toward Rust.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem That Started Harbor Sweep
&lt;/h2&gt;

&lt;p&gt;Ironically, Harbor Sweep started because of a very small and annoying workflow issue.&lt;/p&gt;

&lt;p&gt;I was dealing with a Windows/JetBrains-related bug where ports sometimes remained occupied even after shutting down services or closing development environments.&lt;/p&gt;

&lt;p&gt;Technically, solving it in PowerShell was easy.&lt;/p&gt;

&lt;p&gt;But doing it repeatedly every day became annoying enough that I decided to build a small utility for myself.&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%2Fv9ia03jbmggsumtx6o30.jpg" 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%2Fv9ia03jbmggsumtx6o30.jpg" alt="Gui version of application" width="800" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first, it was just meant to save me a few seconds.&lt;/p&gt;

&lt;p&gt;Nothing more.&lt;/p&gt;

&lt;p&gt;But eventually, that small utility became my Rust playground.&lt;/p&gt;

&lt;p&gt;I kept adding features, improving workflows, experimenting with architecture, and trying ideas I normally could not explore inside traditional SPA development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovering TUI Applications
&lt;/h2&gt;

&lt;p&gt;Around that same period, I attended my first RustMeet in Gliwice.&lt;/p&gt;

&lt;p&gt;That event changed my perspective a lot.&lt;/p&gt;

&lt;p&gt;Until then, Rust still felt somewhat “distant” to me interesting, but maybe overhyped.&lt;/p&gt;

&lt;p&gt;The meetup made me realize people were actually building real systems, tools, and infrastructure with it.&lt;/p&gt;

&lt;p&gt;At that point, Harbor Sweep already had a GUI version.&lt;/p&gt;

&lt;p&gt;Then Orhun Parmaksız casually suggested:&lt;br&gt;
“Why not build it as a terminal UI application?”&lt;/p&gt;

&lt;p&gt;That idea immediately clicked for me.&lt;/p&gt;

&lt;p&gt;So I started experimenting with Ratatui.&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%2Fdqq984ew3kdxvdl8y5gb.jpg" 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%2Fdqq984ew3kdxvdl8y5gb.jpg" alt="Screenshot Basic Application TUi" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And honestly, building terminal applications felt surprisingly refreshing.&lt;/p&gt;

&lt;p&gt;You start thinking differently when the entire interface becomes keyboard-driven and event-based.&lt;/p&gt;

&lt;p&gt;The focus shifts from visual browser components to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;application state&lt;/li&gt;
&lt;li&gt;rendering loops&lt;/li&gt;
&lt;li&gt;event handling&lt;/li&gt;
&lt;li&gt;terminal constraints&lt;/li&gt;
&lt;li&gt;responsiveness&lt;/li&gt;
&lt;li&gt;workflow efficiency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It felt much closer to the operating system itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desktop Software Changed My Engineering Mindset
&lt;/h2&gt;

&lt;p&gt;The deeper I went into Rust and desktop development, the more I realized how different the engineering mindset becomes outside the browser.&lt;/p&gt;

&lt;p&gt;In frontend development, many low-level details are abstracted away.&lt;/p&gt;

&lt;p&gt;With desktop and systems-oriented software, suddenly you start thinking about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;threads&lt;/li&gt;
&lt;li&gt;async workflows&lt;/li&gt;
&lt;li&gt;long-running processes&lt;/li&gt;
&lt;li&gt;local persistence&lt;/li&gt;
&lt;li&gt;OS APIs&lt;/li&gt;
&lt;li&gt;notifications&lt;/li&gt;
&lt;li&gt;background schedulers&lt;/li&gt;
&lt;li&gt;process management&lt;/li&gt;
&lt;li&gt;direct system interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The browser sandbox disappears.&lt;/p&gt;

&lt;p&gt;And with that freedom comes a completely different type of responsibility.&lt;/p&gt;

&lt;p&gt;What surprised me most is that learning Rust itself was not the hardest part for me.&lt;/p&gt;

&lt;p&gt;The documentation is genuinely excellent.&lt;/p&gt;

&lt;p&gt;And modern AI tooling helps a lot when you need practical explanations instead of spending hours watching crash courses.&lt;/p&gt;

&lt;p&gt;Async Rust is still something I continue learning, but overall, the language itself felt much more approachable than I originally expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Was Actually Hard
&lt;/h2&gt;

&lt;p&gt;The hardest part was not ownership or the borrow checker.&lt;/p&gt;

&lt;p&gt;It was shipping software properly.&lt;/p&gt;

&lt;p&gt;Packaging, installers, release pipelines, platform-specific behavior, distribution systems like Chocolatey or Snapcraft that was the part that forced me to adjust the most.&lt;/p&gt;

&lt;p&gt;Debugging also feels very different outside frontend environments.&lt;/p&gt;

&lt;p&gt;In browser development, the tooling is incredibly mature and immediate.&lt;/p&gt;

&lt;p&gt;Desktop applications force you to think closer to the operating system itself, and debugging often becomes much more low-level and environment-dependent.&lt;/p&gt;

&lt;p&gt;That transition took far more adaptation than the language syntax ever did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond the Browser
&lt;/h2&gt;

&lt;p&gt;Looking back now, Harbor Sweep started as a lazy workaround for an annoying workflow problem.&lt;/p&gt;

&lt;p&gt;But over time, it slowly changed how I think about software engineering entirely.&lt;/p&gt;

&lt;p&gt;What originally started as:&lt;br&gt;
“I want to stop manually killing processes.”&lt;/p&gt;

&lt;p&gt;Eventually became:&lt;br&gt;
“I want to build software that works closer to the machine.”&lt;/p&gt;

&lt;p&gt;And honestly, that journey has been one of the most interesting parts of my engineering career so far.&lt;/p&gt;

&lt;h2&gt;
  
  
  References &amp;amp; Related Projects
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Project List in Linkdin: &lt;a href="https://www.linkedin.com/in/luka-jioshvili/details/projects/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/luka-jioshvili/details/projects/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Harbor Sweep GUI Version — &lt;a href="https://github.com/LazyDoomSlayer/harboor-sweep" rel="noopener noreferrer"&gt;https://github.com/LazyDoomSlayer/harboor-sweep&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Harbor Sweep TUI Version — &lt;a href="https://github.com/LazyDoomSlayer/harboor-sweep-tui" rel="noopener noreferrer"&gt;https://github.com/LazyDoomSlayer/harboor-sweep-tui&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ratatui — &lt;a href="https://github.com/ratatui/ratatui" rel="noopener noreferrer"&gt;https://github.com/ratatui/ratatui&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tauri v2 — &lt;a href="https://tauri.app" rel="noopener noreferrer"&gt;https://tauri.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;RustMeet Gliwice — &lt;a href="https://www.linkedin.com/company/rustmeet" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/rustmeet&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Orhun Parmaksız — &lt;a href="https://github.com/orhun" rel="noopener noreferrer"&gt;https://github.com/orhun&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>tauri</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The 80% You Don’t See: What Tracking My Work Taught Me</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Fri, 24 Apr 2026 07:49:53 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/the-80-you-dont-see-what-tracking-my-work-taught-me-260k</link>
      <guid>https://dev.to/lazydoomslayer/the-80-you-dont-see-what-tracking-my-work-taught-me-260k</guid>
      <description>&lt;p&gt;I started tracking my work recently.&lt;br&gt;
Not with some system.&lt;br&gt;
Not with some productivity guru method.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Just… writing things down.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Here’s what came out of it.
&lt;/h2&gt;

&lt;p&gt;It wasn’t some big realization.&lt;/p&gt;

&lt;p&gt;More like small things… stacking up.&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%2F46jy2qtslulz81cisoxt.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%2F46jy2qtslulz81cisoxt.png" alt="my thoughts about tracking" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Q: Why did you start tracking your work in the first place?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
I think it’s needed.&lt;/p&gt;

&lt;p&gt;You need to appreciate your own progress even if nobody else sees it.&lt;br&gt;
Also, I wanted to understand:&lt;/p&gt;

&lt;p&gt;At this pace… where am I actually going?&lt;/p&gt;




&lt;p&gt;Q: What did you think you were doing well before tracking?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
Nothing specific.&lt;/p&gt;

&lt;p&gt;But now I think more.&lt;br&gt;
I compare more.&lt;br&gt;
And that makes it easier to decide what’s actually worth doing.&lt;/p&gt;




&lt;p&gt;Q: What did tracking immediately prove wrong?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
That tracking is some “online coach” thing.&lt;/p&gt;

&lt;p&gt;It’s not.&lt;/p&gt;

&lt;p&gt;It’s just:&lt;/p&gt;

&lt;p&gt;evaluating your own steps without judging yourself.&lt;/p&gt;

&lt;p&gt;Just understanding why you made certain decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Friction &amp;amp; Reality
&lt;/h3&gt;

&lt;p&gt;It started to feel like a 20/80 kind of thing.&lt;/p&gt;

&lt;p&gt;You see the 20%.&lt;/p&gt;

&lt;p&gt;But most of the work lives in the 80%.&lt;/p&gt;

&lt;p&gt;Ever had that feeling?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You think you worked all day…&lt;br&gt;
but can’t explain what you actually did.&lt;/p&gt;
&lt;/blockquote&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%2Fffivahd5zm70mb4nq7io.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%2Fffivahd5zm70mb4nq7io.png" alt="overview my idea" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Q: When you say “I worked all day” what does that actually mean?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
Depends.&lt;/p&gt;

&lt;p&gt;Sometimes “all day” == a few hours of real productivity.&lt;br&gt;
Other times, I can go 8 hours straight on my own projects.&lt;/p&gt;

&lt;p&gt;So yeah… “all day” doesn’t mean much by itself.&lt;/p&gt;




&lt;p&gt;Q: How much of your time is real output?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
At work -&amp;gt; a few hours of focused, real output.&lt;br&gt;
On my own stuff -&amp;gt; I can lock in for much longer.&lt;/p&gt;

&lt;p&gt;Different energy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Patterns I Didn’t Expect
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not in a dramatic way.&lt;br&gt;
Just… quietly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Q: What pattern kept repeating?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
I kept asking myself:&lt;/p&gt;

&lt;p&gt;“Why am I not exploring things more?”&lt;/p&gt;

&lt;p&gt;I do other hobbies gaming, exploring music, random stuff&lt;br&gt;
but sometimes I skip the kind of work I actually enjoy&lt;br&gt;
(side projects, deeper exploration).&lt;/p&gt;




&lt;p&gt;Q: What surprised you about your behavior?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
I started questioning how I push myself:&lt;/p&gt;

&lt;p&gt;“Am I pushing in the right direction… or just pushing?”&lt;/p&gt;

&lt;p&gt;Also had this thought:&lt;/p&gt;

&lt;p&gt;maybe I could present something at a Rust conference one day.&lt;/p&gt;

&lt;p&gt;And these posts… might actually help with that.&lt;/p&gt;




&lt;p&gt;Q: What did you not want to admit?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
That I actually have experience.&lt;/p&gt;

&lt;p&gt;I’m not some “big” developer.&lt;br&gt;
But I do have things worth sharing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Quiet Realization
&lt;/h3&gt;

&lt;p&gt;Q: Did tracking ever “hit” you hard?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
Not really.&lt;/p&gt;

&lt;p&gt;It’s more like a background process.&lt;br&gt;
I don’t think about it daily.&lt;/p&gt;

&lt;p&gt;Only when I sit down to reflect like writing this.&lt;/p&gt;




&lt;p&gt;What Actually Got Better&lt;/p&gt;

&lt;p&gt;Q: What did tracking help you understand?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
My habits.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what’s actually bad&lt;/li&gt;
&lt;li&gt;what’s just human&lt;/li&gt;
&lt;li&gt;what’s needed to not burn out&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not everything unproductive is “wrong”.&lt;/p&gt;

&lt;p&gt;Some of it is just… necessary.&lt;/p&gt;




&lt;p&gt;Q: Did anything become clearer?&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
Yes.&lt;/p&gt;

&lt;p&gt;I started focusing on things that actually have an effect.&lt;/p&gt;

&lt;p&gt;Small things. Real things.&lt;/p&gt;

&lt;p&gt;Not “big ideas influenced by media”.&lt;/p&gt;

&lt;p&gt;I see people around me chasing huge things.&lt;br&gt;
I’m building something simple but useful.&lt;/p&gt;

&lt;p&gt;No AI hype.&lt;br&gt;
Just coding and solving problems.&lt;/p&gt;

&lt;p&gt;And honestly… that feels better.&lt;/p&gt;




&lt;h3&gt;
  
  
  Final Thought
&lt;/h3&gt;

&lt;p&gt;Q: Tracking my work didn’t make me more productive. It made me realize…&lt;/p&gt;

&lt;p&gt;A:&lt;br&gt;
…my habits.&lt;/p&gt;

&lt;p&gt;My progress.&lt;/p&gt;

&lt;p&gt;And that I should actually appreciate my own effort.&lt;/p&gt;

&lt;p&gt;Even small wins.&lt;br&gt;
Even messy ones.&lt;/p&gt;

&lt;p&gt;Because they add up.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What’s one thing you noticed about yourself?&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Don’t Blog to Teach: I Blog to Track My Own Journey</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Tue, 07 Apr 2026 18:30:41 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/i-dont-blog-to-teach-i-blog-to-track-my-own-journey-3mm</link>
      <guid>https://dev.to/lazydoomslayer/i-dont-blog-to-teach-i-blog-to-track-my-own-journey-3mm</guid>
      <description>&lt;p&gt;You see a lot of advice around blogging as a developer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build your personal brand.&lt;br&gt;
Grow an audience.&lt;br&gt;
Share knowledge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s not why I started.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real reason
&lt;/h2&gt;

&lt;p&gt;I didn’t start blogging because I forget things.&lt;br&gt;
Actually, I don’t.&lt;/p&gt;

&lt;p&gt;But that’s not the point.&lt;/p&gt;

&lt;p&gt;What I do want is a clear view of my own roadmap, what I learned, when I learned it, and how I was thinking at that moment.&lt;/p&gt;

&lt;p&gt;Not just final solutions.&lt;/p&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the confusion&lt;/li&gt;
&lt;li&gt;the decisions&lt;/li&gt;
&lt;li&gt;the small realizations&lt;/li&gt;
&lt;li&gt;the progress over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s the part you lose if you don’t write things down.&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%2F8nchfgtwk6i2jwv47wos.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%2F8nchfgtwk6i2jwv47wos.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The question people asked me
&lt;/h2&gt;

&lt;p&gt;When I started posting, some friends asked me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why are you even writing blogs? Are you trying to impress someone?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And honestly, I get it.&lt;/p&gt;

&lt;p&gt;From the outside, it can look like that.&lt;/p&gt;

&lt;p&gt;But no.&lt;/p&gt;

&lt;p&gt;I’m not trying to impress anyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What blogging actually is for me
&lt;/h2&gt;

&lt;p&gt;For me, blogging is simple.&lt;/p&gt;

&lt;p&gt;It’s a way to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;track my progress&lt;/li&gt;
&lt;li&gt;document how my thinking evolves&lt;/li&gt;
&lt;li&gt;keep a record of what I’m building and learning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s basically a timeline of my developer journey.&lt;/p&gt;

&lt;p&gt;Something I can revisit later and understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;where I was&lt;/li&gt;
&lt;li&gt;what I struggled with&lt;/li&gt;
&lt;li&gt;what eventually clicked&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;As developers, we move fast.&lt;/p&gt;

&lt;p&gt;We jump between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tools&lt;/li&gt;
&lt;li&gt;frameworks&lt;/li&gt;
&lt;li&gt;problems&lt;/li&gt;
&lt;li&gt;ideas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if you don’t forget things, you lose context.&lt;/p&gt;

&lt;p&gt;You forget:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;why you chose a specific approach&lt;/li&gt;
&lt;li&gt;what confused you at the time&lt;/li&gt;
&lt;li&gt;what changed your understanding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That context is valuable.&lt;/p&gt;

&lt;p&gt;And that’s exactly what I want to keep.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this will help
&lt;/h2&gt;

&lt;p&gt;Right now, I’m just getting started.&lt;/p&gt;

&lt;p&gt;But I already know this will matter when I document things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;my homelab setup&lt;/li&gt;
&lt;li&gt;infrastructure experiments&lt;/li&gt;
&lt;li&gt;my shift from frontend (Vue) into Rust and systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because later, I won’t just care about what I did.&lt;/p&gt;

&lt;p&gt;I’ll care about how I got there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;So no, I’m not blogging to teach.&lt;/p&gt;

&lt;p&gt;I’m blogging to track my own journey.&lt;/p&gt;

&lt;p&gt;To see how I evolve over time.&lt;/p&gt;

&lt;p&gt;If someone finds it useful along the way, that’s just a bonus.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>rust</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>From Vue to Rust: Why a Frontend Developer Started Writing Systems Tools</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Fri, 13 Mar 2026 18:46:56 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/from-vue-to-rust-why-a-frontend-developer-started-writing-systems-tools-2204</link>
      <guid>https://dev.to/lazydoomslayer/from-vue-to-rust-why-a-frontend-developer-started-writing-systems-tools-2204</guid>
      <description>&lt;h2&gt;
  
  
  Hook
&lt;/h2&gt;

&lt;p&gt;After spending several years working primarily with Vue and TypeScript, I started paying closer attention to the tools that power the developer ecosystem.&lt;/p&gt;

&lt;p&gt;While exploring modern terminal workflows and developer tooling, I kept encountering the same language again and again: &lt;strong&gt;Rust&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Tools like &lt;strong&gt;ripgrep&lt;/strong&gt; (used for fast searching in editors like Neovim), &lt;strong&gt;zoxide&lt;/strong&gt;, &lt;strong&gt;exa&lt;/strong&gt;, terminal applications like &lt;strong&gt;lazygit&lt;/strong&gt;, GPU-accelerated terminals like &lt;strong&gt;Alacritty&lt;/strong&gt;, and TUI frameworks such as &lt;strong&gt;Ratatui&lt;/strong&gt; are all part of the growing Rust ecosystem.&lt;/p&gt;

&lt;p&gt;Beyond terminal tools, Rust is also powering projects like the &lt;strong&gt;Zed editor&lt;/strong&gt;, the &lt;strong&gt;Biome JavaScript toolchain&lt;/strong&gt;, and desktop frameworks like &lt;strong&gt;Tauri&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Seeing Rust appear across so many modern developer tools made me curious:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What would it be like for a frontend developer to start building tools in Rust?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Background as a Frontend Developer
&lt;/h2&gt;

&lt;p&gt;My professional work is mostly in the frontend ecosystem. Over the past few years I’ve been working with &lt;strong&gt;Vue and TypeScript&lt;/strong&gt;, building web applications and focusing on the user-facing side of software.&lt;/p&gt;

&lt;p&gt;Like many frontend developers, most of my tooling and scripting traditionally lived in the &lt;strong&gt;Node.js ecosystem&lt;/strong&gt;. From build tools to small automation scripts, JavaScript was usually the default choice.&lt;/p&gt;

&lt;p&gt;But over time I started becoming more interested in developer tooling itself things like CLI utilities, terminal workflows, and small system-level tools that improve everyday development.&lt;/p&gt;

&lt;p&gt;That curiosity is what eventually led me to start exploring Rust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Decided to Try Rust
&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%2Fwedxhzm8cifocsckqcpn.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%2Fwedxhzm8cifocsckqcpn.png" alt="Why I Decided to Try Rust" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My first real reason to try Rust came from experimenting with &lt;strong&gt;desktop applications using Tauri&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As someone coming from the frontend world, Tauri felt like a natural bridge. I could still use web technologies for the interface, while Rust handled the system-level parts of the application. That combination made Rust feel much more approachable than jumping straight into systems programming.&lt;/p&gt;

&lt;p&gt;After that first step, curiosity started taking over.&lt;/p&gt;

&lt;p&gt;I began exploring other areas where Rust is commonly used building &lt;strong&gt;CLI tools&lt;/strong&gt;, experimenting with &lt;strong&gt;terminal user interfaces using Ratatui&lt;/strong&gt;, and generally trying to understand how Rust applications interact more closely with the system.&lt;/p&gt;

&lt;p&gt;Several things about Rust were appealing at the same time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory safety&lt;/strong&gt; without a garbage collector&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; of compiled binaries&lt;/li&gt;
&lt;li&gt;The ability to produce a &lt;strong&gt;single standalone executable&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;And honestly, the challenge of learning something very different from the JavaScript ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust felt like a language that encouraged thinking differently about how software is structured, especially compared to the object-oriented patterns I was used to from other languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Surprised Me When Learning Rust
&lt;/h2&gt;

&lt;p&gt;Starting with Rust was not as smooth as learning another JavaScript framework or library.&lt;/p&gt;

&lt;p&gt;Coming from a background where most of my experience was with object-oriented patterns and higher-level abstractions, Rust initially felt very different. Concepts like &lt;strong&gt;ownership&lt;/strong&gt;, &lt;strong&gt;borrowing&lt;/strong&gt;, and strict compile-time checks were confusing at first.&lt;/p&gt;

&lt;p&gt;The shift in thinking was probably the biggest challenge. Instead of relying on runtime behavior or flexible patterns, Rust encourages you to be explicit about how data moves through your program.&lt;/p&gt;

&lt;p&gt;At the beginning this can feel frustrating, but something interesting happens over time: the compiler starts to feel less like an obstacle and more like a guide.&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%2Fh9z3m44awah8uxhadpk1.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%2Fh9z3m44awah8uxhadpk1.png" alt="Rust compiler as teacher" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rust’s compiler is extremely strict, but it also provides detailed feedback. Many mistakes that would normally show up as runtime bugs are caught much earlier during compilation.&lt;/p&gt;

&lt;p&gt;That experience changes how you think about writing software.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Rust Makes Sense (and When It Doesn't)
&lt;/h2&gt;

&lt;p&gt;One thing I learned while exploring Rust is that it isn’t meant to replace every tool or language in your workflow.&lt;/p&gt;

&lt;p&gt;For example, JavaScript and TypeScript are still excellent choices for building web applications, especially when rapid development and a large ecosystem are important. In frontend development, the productivity and flexibility of the JavaScript ecosystem are hard to beat.&lt;/p&gt;

&lt;p&gt;Rust, however, shines in slightly different areas.&lt;/p&gt;

&lt;p&gt;Because Rust compiles to a standalone binary and focuses heavily on performance and safety, it works extremely well for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CLI tools&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;terminal applications&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;developer tooling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;system-level utilities&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;desktop applications with frameworks like Tauri&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These kinds of programs often benefit from fast startup times, efficient resource usage, and strong guarantees around memory safety.&lt;/p&gt;

&lt;p&gt;For me, Rust didn’t replace the tools I was already using it simply opened a new category of problems that I could explore and build solutions for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where My Rust Journey Is Going Next
&lt;/h2&gt;

&lt;p&gt;Learning Rust has changed the way I think about building software.&lt;/p&gt;

&lt;p&gt;Even though my primary work is still focused on frontend development with Vue and TypeScript, Rust introduced me to a different layer of the software stack one that is closer to the system and focused on performance, reliability, and tooling.&lt;/p&gt;

&lt;p&gt;Right now I’m continuing to experiment with Rust by building small tools, exploring &lt;strong&gt;Tauri for desktop applications&lt;/strong&gt;, and learning more about &lt;strong&gt;terminal user interfaces using Ratatui&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a frontend developer, Rust might feel unfamiliar at first, but that unfamiliarity is exactly what makes the journey interesting.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Stay Rusty 🦀&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rust</category>
      <category>webdev</category>
      <category>tauri</category>
      <category>ratatui</category>
    </item>
    <item>
      <title>run.sh Diaries #5: Make It Yours – Forking, Tweaking &amp; Extending the Setup</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Thu, 12 Mar 2026 10:40:29 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/runsh-diaries-5-make-it-yours-forking-tweaking-extending-the-setup-40g4</link>
      <guid>https://dev.to/lazydoomslayer/runsh-diaries-5-make-it-yours-forking-tweaking-extending-the-setup-40g4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR&lt;br&gt;
In this final post, I’ll show you how to take my Ubuntu WSL bootstrap and make it your own.&lt;/p&gt;

&lt;p&gt;Whether you want to add dotfiles, set up Git identity, or install completely different tools, this structure makes it easy to fork, extend, and personalize.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Customization Matters
&lt;/h2&gt;

&lt;p&gt;This project works for me, but &lt;strong&gt;you should own your environment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;My goal from the beginning was to make this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modular (each tool gets its own script)&lt;/li&gt;
&lt;li&gt;Transparent (readable Bash, no black-box logic)&lt;/li&gt;
&lt;li&gt;Easy to tweak (just edit configs or scripts)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn’t a framework, it’s a blueprint.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Add or Remove Packages
&lt;/h2&gt;

&lt;p&gt;You can edit &lt;a href="https://github.com/LazyDoomSlayer/os-bootstraps/blob/main/ubuntu/packages.conf" rel="noopener noreferrer"&gt;&lt;code&gt;packages.conf&lt;/code&gt;&lt;/a&gt; to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add tools you always install (e.g. &lt;code&gt;jq&lt;/code&gt;, &lt;code&gt;htop&lt;/code&gt;, &lt;code&gt;gh&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Remove things you don’t use (e.g. &lt;code&gt;yazi&lt;/code&gt;, &lt;code&gt;btop&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SYSTEM_UTILS_APT&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
  wget curl jq htop
&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;DEV_TOOLS_SNAP&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
  nvim
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These arrays are passed into helper functions from &lt;code&gt;utils.sh&lt;/code&gt;, which handle install logic cleanly.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Add Your Own Scripts
&lt;/h2&gt;

&lt;p&gt;To add new tooling (like Go, Deno, or Rust), follow this pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new file like &lt;code&gt;go-setup.sh&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add install logic using &lt;code&gt;apt&lt;/code&gt;, Snap, curl, or custom methods&lt;/li&gt;
&lt;li&gt;Append it to the &lt;code&gt;SCRIPTS=(...)&lt;/code&gt; array in &lt;code&gt;run.sh&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;readonly &lt;/span&gt;&lt;span class="nv"&gt;SCRIPTS&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
  ...
  &lt;span class="s2"&gt;"go-setup.sh"&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Include Dotfiles or Shell Config
&lt;/h2&gt;

&lt;p&gt;Want to bootstrap your &lt;code&gt;.bashrc&lt;/code&gt;, &lt;code&gt;.tmux.conf&lt;/code&gt;, or &lt;code&gt;.gitconfig&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone your dotfiles repo in a new &lt;code&gt;dotfiles-setup.sh&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Symlink them or append to existing configs&lt;/li&gt;
&lt;li&gt;Set aliases, functions, or themes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is also a good place to add default Git config, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"you@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Handle Secrets and Git Identity
&lt;/h2&gt;

&lt;p&gt;Avoid committing private tokens or configs. Instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep a local &lt;code&gt;~/.local-setup.sh&lt;/code&gt; script with personal logic&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;.local-setup.sh&lt;/code&gt; to your &lt;code&gt;.gitignore&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Source it at the end of &lt;code&gt;run.sh&lt;/code&gt; (if it exists)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local-setup.sh"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running local custom setup..."&lt;/span&gt;
  bash &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local-setup.sh"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. WSL-Specific Optimizations
&lt;/h2&gt;

&lt;p&gt;Some tweaks worth adding if you run WSL full time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;.wslconfig&lt;/code&gt; on Windows for better resource limits&lt;/li&gt;
&lt;li&gt;Add mounts or performance tweaks in &lt;code&gt;/etc/wsl.conf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Disable unnecessary services that don’t apply in WSL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can even add a WSL check to &lt;code&gt;run.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-qi&lt;/span&gt; microsoft /proc/version &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running under WSL"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fork It, Extend It, Own It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This whole project is meant to be cloned, forked, and hacked.&lt;/li&gt;
&lt;li&gt;Start with mine, and make it match your exact stack and preferences.&lt;/li&gt;
&lt;li&gt;If you build something cool from this, I’d love to see it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Recap
&lt;/h2&gt;

&lt;p&gt;Over the last 5 posts, you’ve seen how I:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Automated my WSL Ubuntu setup from scratch&lt;/li&gt;
&lt;li&gt;Wrote modular Bash scripts with smart defaults&lt;/li&gt;
&lt;li&gt;Bootstrapped a full terminal dev stack&lt;/li&gt;
&lt;li&gt;Installed Node, Python, and Docker with zero hassle&lt;/li&gt;
&lt;li&gt;Built a foundation that anyone can extend&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Takeaway?&lt;/p&gt;

&lt;p&gt;Automate the boring stuff, personalize the rest, and keep improving it. &lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>linux</category>
    </item>
    <item>
      <title>run.sh Diaries #4: From Zero to Coding-Ready with Node, Python &amp; Docker</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Tue, 03 Mar 2026 14:00:56 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/runsh-diaries-4-from-zero-to-coding-ready-with-node-python-docker-h9</link>
      <guid>https://dev.to/lazydoomslayer/runsh-diaries-4-from-zero-to-coding-ready-with-node-python-docker-h9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR&lt;br&gt;
This post covers how my WSL bootstrap sets up Node.js, Python, and Docker and the core tools I use for frontend, backend, scripting, and container work.&lt;br&gt;
Each tool has its own setup script, designed to be modular, idempotent, and fast.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why These Tools?
&lt;/h2&gt;

&lt;p&gt;My day-to-day work (and open source projects) span across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend apps (Vue, Nuxt, TypeScript)&lt;/li&gt;
&lt;li&gt;Scripts, automation, CLI tools (Python)&lt;/li&gt;
&lt;li&gt;Testing infrastructure, running services, and debugging (Docker)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So my bootstrap includes all of them by default and no more grabbing install commands from old gists or StackOverflow every time I set up WSL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node.js Setup – &lt;a href="https://github.com/LazyDoomSlayer/os-bootstraps/blob/main/ubuntu/node-setup.sh" rel="noopener noreferrer"&gt;&lt;code&gt;node-setup.sh&lt;/code&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I install &lt;strong&gt;Node.js LTS (v22)&lt;/strong&gt; using &lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;&lt;code&gt;nvm&lt;/code&gt;&lt;/a&gt; because it's the most flexible method for switching versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the script does:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Installs or updates NVM&lt;/li&gt;
&lt;li&gt;Loads it into the shell&lt;/li&gt;
&lt;li&gt;Installs Node.js v22 and sets it as default&lt;/li&gt;
&lt;li&gt;Installs global tools: &lt;code&gt;pnpm&lt;/code&gt; and &lt;code&gt;yarn&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Disables Yarn telemetry&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why this approach?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Versioning via NVM makes switching Node versions trivial&lt;/li&gt;
&lt;li&gt;I use &lt;code&gt;pnpm&lt;/code&gt; for speed and monorepos, and &lt;code&gt;yarn&lt;/code&gt; where needed
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvm &lt;span class="nb"&gt;install &lt;/span&gt;22
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; pnpm yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output is printed to verify versions and check everything succeeded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python Setup – &lt;a href="https://github.com/LazyDoomSlayer/os-bootstraps/blob/main/ubuntu/python-setup.sh" rel="noopener noreferrer"&gt;&lt;code&gt;python-setup.sh&lt;/code&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Python is everywhere and whether I’m scripting quick tools, using CLI apps, or running data scripts.&lt;/p&gt;

&lt;h3&gt;
  
  
  What this setup covers:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Installs Python via APT&lt;/li&gt;
&lt;li&gt;Installs &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;venv&lt;/code&gt;, and upgrades &lt;code&gt;setuptools&lt;/code&gt;, &lt;code&gt;wheel&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;Prepares the environment for creating isolated Python workspaces&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This setup is intentionally minimal and  just enough to bootstrap Python for development, automation, and further customization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Docker Setup – &lt;a href="https://github.com/LazyDoomSlayer/os-bootstraps/blob/main/ubuntu/docker-setup.sh" rel="noopener noreferrer"&gt;&lt;code&gt;docker-setup.sh&lt;/code&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I use Docker for containers when testing services or building isolated environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the script does:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Installs Docker via APT (using official repo)&lt;/li&gt;
&lt;li&gt;Adds the current user to the &lt;code&gt;docker&lt;/code&gt; group (so no need for &lt;code&gt;sudo&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Enables the Docker service&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why this matters:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WSL2 supports Docker with great performance&lt;/li&gt;
&lt;li&gt;You shouldn’t have to use &lt;code&gt;sudo&lt;/code&gt; to run &lt;code&gt;docker&lt;/code&gt; in dev environments&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Docker is optional, but including it makes the bootstrap future-proof if I need containers down the line.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  One Bootstrap to Install Them All
&lt;/h2&gt;

&lt;p&gt;All of these are automatically set up when I run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./run.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don’t have to worry about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which method to use (&lt;code&gt;nvm&lt;/code&gt;, APT, Snap, curl?)&lt;/li&gt;
&lt;li&gt;Forgetting steps like adding users to Docker groups&lt;/li&gt;
&lt;li&gt;Repeating things across different machines&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Future Improvements
&lt;/h2&gt;

&lt;p&gt;Things I might add later:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Version pinning via &lt;code&gt;.nvmrc&lt;/code&gt; or &lt;code&gt;.tool-versions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Python virtualenv examples (or Poetry setup)&lt;/li&gt;
&lt;li&gt;Docker Compose install&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next: Make It Yours
&lt;/h2&gt;

&lt;p&gt;In run.sh Diaries #5, I’ll show you how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add your own scripts&lt;/li&gt;
&lt;li&gt;Customize package lists&lt;/li&gt;
&lt;li&gt;Include dotfiles or Git config&lt;/li&gt;
&lt;li&gt;Extend the bootstrap for your own stack&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>linux</category>
    </item>
    <item>
      <title>run.sh Diaries #3: My Terminal Stack – tmux, zoxide, and lazygit</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Tue, 24 Feb 2026 07:45:26 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/runsh-diaries-3-my-terminal-stack-tmux-zoxide-and-lazygit-4hmm</link>
      <guid>https://dev.to/lazydoomslayer/runsh-diaries-3-my-terminal-stack-tmux-zoxide-and-lazygit-4hmm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR&lt;br&gt;
This post walks through the terminal tools I bootstrap with my WSL setup: &lt;code&gt;tmux&lt;/code&gt; for multitasking, &lt;code&gt;zoxide&lt;/code&gt; for lightning-fast directory switching, and &lt;code&gt;lazygit&lt;/code&gt; for painless Git management. &lt;br&gt;
These aren’t just cool tools and they’re essentials in my terminal-first workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why a Terminal Stack?
&lt;/h2&gt;

&lt;p&gt;I’ve said it before: I prefer a &lt;strong&gt;terminal-first&lt;/strong&gt; workflow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modern IDEs? Too heavy.&lt;/li&gt;
&lt;li&gt;GUI Git clients? Slow and mouse-driven.&lt;/li&gt;
&lt;li&gt;I want &lt;strong&gt;speed&lt;/strong&gt;, &lt;strong&gt;control&lt;/strong&gt;, and tools that work over SSH, WSL, or raw Linux.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I built my environment around powerful CLI tools that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launch instantly&lt;/li&gt;
&lt;li&gt;Don’t eat memory&lt;/li&gt;
&lt;li&gt;Let me work efficiently in any shell or session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s break down the tools I install automatically via my bootstrap scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/tmux/tmux" rel="noopener noreferrer"&gt;tmux&lt;/a&gt; – Terminal Multiplexing
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;tmux&lt;/code&gt; lets me split one terminal into multiple panes and windows. I use it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run multiple shells or logs side-by-side&lt;/li&gt;
&lt;li&gt;Persist sessions even after closing the terminal&lt;/li&gt;
&lt;li&gt;Combine editor + server + shell in one view&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why I love it:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Clean, scriptable config&lt;/li&gt;
&lt;li&gt;Always available in headless setups&lt;/li&gt;
&lt;li&gt;Works beautifully with &lt;code&gt;neovim&lt;/code&gt;, &lt;code&gt;fzf&lt;/code&gt;, and my dotfiles&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/tmux-plugins/tpm" rel="noopener noreferrer"&gt;TPM&lt;/a&gt; – Tmux Plugin Manager
&lt;/h2&gt;

&lt;p&gt;My &lt;code&gt;tpm-setup.sh&lt;/code&gt; script installs &lt;a href="https://github.com/tmux-plugins/tpm" rel="noopener noreferrer"&gt;TPM&lt;/a&gt; (Tmux Plugin Manager) which makes installing and updating tmux plugins painless. It lives in &lt;code&gt;~/.tmux/plugins&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/ajeetdsouza/zoxide" rel="noopener noreferrer"&gt;`zoxide&lt;/a&gt;&lt;code&gt; – Smarter &lt;/code&gt;cd`
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ajeetdsouza/zoxide" rel="noopener noreferrer"&gt;&lt;code&gt;zoxide&lt;/code&gt;&lt;/a&gt; is a fast, smarter alternative to &lt;code&gt;cd&lt;/code&gt;. You just type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;z GitHub
z os-bootstraps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;…and it jumps to your most-used directories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why I use it:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tracks recent paths automatically&lt;/li&gt;
&lt;li&gt;Works across shells&lt;/li&gt;
&lt;li&gt;Insanely efficient once you get used to it&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/jesseduffield/lazygit" rel="noopener noreferrer"&gt;lazygit&lt;/a&gt; – Git, But Better
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/jesseduffield/lazygit" rel="noopener noreferrer"&gt;&lt;code&gt;lazygit&lt;/code&gt;&lt;/a&gt; is a TUI-based Git interface I use daily to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switch branches&lt;/li&gt;
&lt;li&gt;Stage/commit&lt;/li&gt;
&lt;li&gt;Resolve merge conflicts&lt;/li&gt;
&lt;li&gt;Review logs and diffs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s keyboard-first, extremely fast, and integrates perfectly into a &lt;code&gt;tmux&lt;/code&gt; workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  All of These Are Auto-Installed
&lt;/h2&gt;

&lt;p&gt;Once I run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./run.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My terminal stack: &lt;code&gt;tmux&lt;/code&gt;, &lt;code&gt;zoxide&lt;/code&gt;, &lt;code&gt;lazygit&lt;/code&gt;, &lt;code&gt;neovim&lt;/code&gt;, and more is ready to go. No more downloading, aliasing, or reconfiguring things manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next: Languages and Containers
&lt;/h2&gt;

&lt;p&gt;In run.sh Diaries #4, I’ll walk you through how I set up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt; with NVM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt; environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; with user group access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And how it all ties into real-world frontend + backend dev work.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>linux</category>
    </item>
    <item>
      <title>run.sh Diaries #2: The Bash Behind the Bootstrap</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Tue, 17 Feb 2026 07:54:15 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/runsh-diaries-2-the-bash-behind-the-bootstrap-1e9</link>
      <guid>https://dev.to/lazydoomslayer/runsh-diaries-2-the-bash-behind-the-bootstrap-1e9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk through the internal logic of how my WSL bootstrap works and let’s focus on &lt;code&gt;run.sh&lt;/code&gt;, &lt;code&gt;utils.sh&lt;/code&gt;, and &lt;code&gt;packages.conf&lt;/code&gt;. You’ll learn how I made the setup modular, safe to re-run, and easy to extend.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Big Picture
&lt;/h3&gt;

&lt;p&gt;In &lt;a href="https://dev.to/lazydoomslayer/runsh-diaries-1-automating-my-ubuntu-dev-environment-1gpi"&gt;Part 1&lt;/a&gt;, I talked about why I built this and now let’s explore &lt;strong&gt;how it works&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At the heart of it is a simple philosophy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don’t repeat yourself.&lt;/p&gt;

&lt;p&gt;Don’t install what’s already there.&lt;/p&gt;

&lt;p&gt;Keep everything scriptable and modular.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The setup revolves around three key components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;run.sh&lt;/code&gt; – the orchestrator&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;utils.sh&lt;/code&gt; – helper functions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;packages.conf&lt;/code&gt; – what to install&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s break each down.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;code&gt;run.sh&lt;/code&gt; – The Orchestrator
&lt;/h2&gt;

&lt;p&gt;This script is the &lt;strong&gt;entry point&lt;/strong&gt; of the whole bootstrap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Responsibilities:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Define the list of setup scripts to run&lt;/li&gt;
&lt;li&gt;Execute them one by one&lt;/li&gt;
&lt;li&gt;Log their progress&lt;/li&gt;
&lt;li&gt;Fail fast if something breaks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Structure:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;readonly &lt;/span&gt;&lt;span class="nv"&gt;SCRIPTS&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
  &lt;span class="s2"&gt;"node-setup.sh"&lt;/span&gt;
  &lt;span class="s2"&gt;"rust-setup.sh"&lt;/span&gt;
  &lt;span class="s2"&gt;"docker-setup.sh"&lt;/span&gt;
  &lt;span class="s2"&gt;"lazygit-setup.sh"&lt;/span&gt;
  &lt;span class="s2"&gt;"python-setup.sh"&lt;/span&gt;
  &lt;span class="s2"&gt;"zoxide-setup.sh"&lt;/span&gt;
  &lt;span class="s2"&gt;"tmux-config-setup.sh"&lt;/span&gt;
  &lt;span class="s2"&gt;"tpm-setup.sh"&lt;/span&gt;
  &lt;span class="s2"&gt;"nvim-setup.sh"&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each script is passed into the &lt;code&gt;run_script()&lt;/code&gt; function from &lt;code&gt;utils.sh&lt;/code&gt;, which:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checks if the file exists&lt;/li&gt;
&lt;li&gt;Makes it executable&lt;/li&gt;
&lt;li&gt;Runs it and logs its completion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. &lt;code&gt;utils.sh&lt;/code&gt; – The Bash Toolkit
&lt;/h2&gt;

&lt;p&gt;This file contains reusable helpers that keep the logic clean and DRY.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Functions:
&lt;/h3&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;is_installed_apt&lt;/code&gt; / &lt;code&gt;is_installed_snap&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Check if a package is already installed before trying to install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  dpkg-query &lt;span class="nt"&gt;-W&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'${Status}'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"install ok installed"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;install_apt_packages&lt;/code&gt; / &lt;code&gt;install_snap_packages&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Take a list of packages, filter out the ones already installed, and install only what’s needed.&lt;/p&gt;

&lt;p&gt;Includes logic to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;apt-get update&lt;/code&gt; only if required&lt;/li&gt;
&lt;li&gt;Handle Snap not being installed&lt;/li&gt;
&lt;li&gt;Try both normal and &lt;code&gt;-classic&lt;/code&gt; Snap installs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;die&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A simple exit-on-error function to fail cleanly and loudly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;die&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ERROR: &lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In the future, I plan to add features like color-coded logging, verbosity levels, timestamps, and WSL detection. But for now, the current setup does exactly what I need: simple, readable, and effective.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. &lt;code&gt;packages.conf&lt;/code&gt; – Centralized Package List
&lt;/h2&gt;

&lt;p&gt;This is where all core APT and Snap packages are defined and grouped by category for clarity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SYSTEM_UTILS_APT&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
  wget curl fzf build-essential fd-find ripgrep
&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;DEV_TOOLS_SNAP&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
  nvim
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each package list is passed into the installer functions in &lt;code&gt;utils.sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This structure makes it easy to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add/remove tools cleanly&lt;/li&gt;
&lt;li&gt;See what’s included at a glance&lt;/li&gt;
&lt;li&gt;Extend with new categories later&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Structure Works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modularity:&lt;/strong&gt; each setup script does one job&lt;/li&gt;
&lt;li&gt;Reusability: helpers prevent duplication&lt;/li&gt;
&lt;li&gt;Clarity: it’s easy to understand what gets installed and how&lt;/li&gt;
&lt;li&gt;Safety: checks prevent reinstalling or breaking existing tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Want to Try It?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️Security Reminder&lt;/p&gt;

&lt;p&gt;Never run scripts from the internet — including mine — without reading and understanding them first.&lt;br&gt;
Even if you trust the source, it's good practice to inspect any Bash script before executing it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I care about security too and my WSL bootstrap project is open source, transparent, and written to be as readable and modular as possible. Fork it, inspect it, tweak it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/LazyDoomSlayer/os-bootstraps
&lt;span class="nb"&gt;cd &lt;/span&gt;os-bootstraps/ubuntu
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x run.sh
./run.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Install time:&lt;/strong&gt; ~5 minutes on a VM with 8GB RAM, 8-core CPU, and 50Mbps connection.&lt;/p&gt;

&lt;p&gt;First-time runs may take longer if your system hasn’t been updated with &lt;code&gt;apt-get update &amp;amp;&amp;amp; upgrade&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Everything else happens automatically. Grab a coffee. ☕&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next: The CLI Stack
&lt;/h2&gt;

&lt;p&gt;In Part 3, I’ll show you the terminal tools I bootstrap like &lt;code&gt;tmux&lt;/code&gt;, &lt;code&gt;zoxide&lt;/code&gt;, &lt;code&gt;lazygit&lt;/code&gt;, and &lt;code&gt;neovim&lt;/code&gt; and how they fit into my daily workflow.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Want to go full terminal-first? This next part is for you.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>linux</category>
    </item>
    <item>
      <title>run.sh Diaries #1: Automating My Ubuntu Dev Environment</title>
      <dc:creator>Luka Jioshvili</dc:creator>
      <pubDate>Sun, 08 Feb 2026 16:05:44 +0000</pubDate>
      <link>https://dev.to/lazydoomslayer/runsh-diaries-1-automating-my-ubuntu-dev-environment-1gpi</link>
      <guid>https://dev.to/lazydoomslayer/runsh-diaries-1-automating-my-ubuntu-dev-environment-1gpi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR&lt;br&gt;
I got tired of setting up WSL manually across multiple machines and installing Node, Python, Docker, CLI tools, and tweaking configs. So I built a Bash-based bootstrap project that installs and configures everything I need in one go.&lt;/p&gt;

&lt;p&gt;Checkout GitHub repo here: &lt;a href="https://github.com/LazyDoomSlayer/os-bootstraps" rel="noopener noreferrer"&gt;https://github.com/LazyDoomSlayer/os-bootstraps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I just run &lt;code&gt;./run.sh&lt;/code&gt; on a fresh Ubuntu WSL install, drink coffee ☕, and get coding in minutes. This post explains why I built it and how you can adapt it too.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction - Why I Built This Ubuntu WSL Bootstrap
&lt;/h2&gt;

&lt;p&gt;WSL gives me a fast Linux dev environment on Windows without needing full VMs and is perfect for scripting, Docker, and open source tooling.&lt;/p&gt;

&lt;p&gt;I’m a frontend developer turned full-stack builder with over 3 years of experience. I split my time between product development, open source contributions, and deep dives into infrastructure, CLI tools, and automation. My current stack revolves around &lt;strong&gt;JavaScript/TypeScript&lt;/strong&gt;, &lt;strong&gt;Vue&lt;/strong&gt;, and increasingly &lt;strong&gt;Rust&lt;/strong&gt;, &lt;strong&gt;Python&lt;/strong&gt;, and TUI/GUI apps.&lt;/p&gt;

&lt;p&gt;Outside of work, I’m building and maintaining my open source projects, experimenting with Rust tooling, and working with CLI-first workflows. That’s where &lt;strong&gt;Ubuntu on WSL&lt;/strong&gt; comes in, it's my daily dev environment for &lt;strong&gt;Node.js projects&lt;/strong&gt;, &lt;strong&gt;scripting&lt;/strong&gt;, &lt;strong&gt;Rust tools&lt;/strong&gt;, and even light container work.&lt;/p&gt;

&lt;p&gt;But here’s the thing...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I got &lt;em&gt;really&lt;/em&gt; tired of setting it all up. Over and over.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Problem - Setup Fatigue
&lt;/h2&gt;

&lt;p&gt;Despite having plenty of memory and a modern machine, I prefer a &lt;strong&gt;terminal-first workflow&lt;/strong&gt;  &lt;code&gt;tmux&lt;/code&gt;, &lt;code&gt;neovim&lt;/code&gt;, and CLI tools, because modern IDEs often feel &lt;em&gt;bloated&lt;/em&gt; and &lt;em&gt;sluggish&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I use WSL every day, but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I have &lt;strong&gt;multiple devices&lt;/strong&gt; (laptop, workstation, test VMs)&lt;/li&gt;
&lt;li&gt;I often test out &lt;strong&gt;different config setups&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;And every time I reinstall Ubuntu or start fresh, I waste &lt;strong&gt;1–2 hours&lt;/strong&gt; manually installing packages, tweaking configs, and setting up tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's the same repetitive process: install APT packages, tweak shell config, add Node, Python, Docker, plugins...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Honestly? I'd rather drink ☕coffee and let the machine set itself up.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The LazyDev Solution
&lt;/h2&gt;

&lt;p&gt;Eventually I asked myself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why the hell am I not automating this?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I did. And because I go by &lt;strong&gt;LazyDoomSlayer&lt;/strong&gt;, I took the lazy-but-smart route. I built a modular &lt;code&gt;run.sh&lt;/code&gt; bootstrap using Bash.&lt;/p&gt;

&lt;p&gt;This was my &lt;strong&gt;first real-world Bash scripting project&lt;/strong&gt; outside of university coursework, and it solved two big problems at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Helped me &lt;strong&gt;automate&lt;/strong&gt; something I do frequently&lt;/li&gt;
&lt;li&gt;Helped me &lt;strong&gt;learn Bash scripting&lt;/strong&gt; through practical use&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;Now I can spin up a clean, fully bootstrapped Ubuntu WSL dev box in minutes with my exact terminal stack, dev tools, and config with just by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./run.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Takeaway?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Automate once. Save hours later. Learn by doing. &lt;br&gt;
Drink coffee while it runs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What’s Next: The Bash Behind the Bootstrap
&lt;/h2&gt;

&lt;p&gt;In Part 2, I’ll show you internal logic how my WSL bootstrap works.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
