<?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: LazyDoomSlayer</title>
    <description>The latest articles on DEV Community by LazyDoomSlayer (@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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3290294%2F417480d0-37f4-4ddd-a1f5-43e6ee26bb30.png</url>
      <title>DEV Community: LazyDoomSlayer</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>I Don’t Blog to Teach: I Blog to Track My Own Journey</title>
      <dc:creator>LazyDoomSlayer</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>LazyDoomSlayer</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="475"&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>LazyDoomSlayer</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>LazyDoomSlayer</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>LazyDoomSlayer</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>LazyDoomSlayer</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>LazyDoomSlayer</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>
