<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cli on Backend Engineering Strategy Tools</title><link>https://backend-engineering-strategy-tools.github.io/site/tags/cli/</link><description>Recent content in Cli on Backend Engineering Strategy Tools</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Wed, 03 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://backend-engineering-strategy-tools.github.io/site/tags/cli/index.xml" rel="self" type="application/rss+xml"/><item><title>Rust</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/rust/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/rust/</guid><description>&lt;p&gt;Systems language with memory safety guarantees without a garbage collector. The ownership and borrow checker model enforces at compile time what other languages leave to the runtime or the programmer.&lt;/p&gt;
&lt;p&gt;The pitch: C/C++ performance and control, without the entire class of memory safety bugs that makes systems programming treacherous. In practice the borrow checker is the learning curve, it rejects code that would be valid in any other language until you understand why it is wrong.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="where-rust-is-winning"&gt;Where Rust is winning
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;CLI tooling&lt;/strong&gt;: a significant share of modern CLI tools are written in Rust. &lt;code&gt;ripgrep&lt;/code&gt;, &lt;code&gt;fd&lt;/code&gt;, &lt;code&gt;bat&lt;/code&gt;, &lt;code&gt;exa&lt;/code&gt;/&lt;code&gt;eza&lt;/code&gt;, &lt;code&gt;zoxide&lt;/code&gt;, &lt;code&gt;tokei&lt;/code&gt;. Startup time and binary distribution (single static binary) are the wins.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WebAssembly&lt;/strong&gt;: Rust compiles to WASM with first-class tooling (&lt;code&gt;wasm-pack&lt;/code&gt;, &lt;code&gt;wasm-bindgen&lt;/code&gt;). Running near-native code in the browser or at the edge.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Embedded / systems&lt;/strong&gt;: where C used to be the only option. The safety guarantees matter more, not less, when there is no OS underneath.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloud infrastructure tooling&lt;/strong&gt;: parts of the ecosystem are being rewritten in Rust. Firecracker (AWS Lambda&amp;rsquo;s VMM), parts of the Linux kernel, Cloudflare Workers runtime.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tooling"&gt;Tooling
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Cargo&lt;/strong&gt;: the build system and package manager. Handles dependencies, building, testing, and publishing. One of the better-designed package managers in any ecosystem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;rustup&lt;/strong&gt;: toolchain manager. Manages Rust versions and targets (cross-compilation).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;clippy&lt;/strong&gt;: linter. Catches more than the compiler, opinionated in useful ways.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;rustfmt&lt;/strong&gt;: formatter. Like &lt;code&gt;gofmt&lt;/code&gt;, one style, no debate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IDE:&lt;/strong&gt; VS Code with &lt;code&gt;rust-analyzer&lt;/code&gt; extension, or IntelliJ/CLion with the Rust plugin.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="the-learning-curve"&gt;The learning curve
&lt;/h2&gt;&lt;p&gt;The borrow checker is a genuine obstacle. Rust enforces at compile time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exactly one owner of any value&lt;/li&gt;
&lt;li&gt;Any number of immutable references OR one mutable reference — not both&lt;/li&gt;
&lt;li&gt;References cannot outlive the value they point to&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is unfamiliar to anyone coming from languages with a GC. The compiler error messages are unusually helpful, but expect to spend real time understanding ownership before writing idiomatic Rust.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://doc.rust-lang.org/book/" target="_blank" rel="noopener"
 &gt;The Rust Book&lt;/a&gt;: the standard introduction, free online&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/rust-lang/rustlings" target="_blank" rel="noopener"
 &gt;Rustlings&lt;/a&gt;: small exercises for learning by doing&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://crates.io/" target="_blank" rel="noopener"
 &gt;crates.io&lt;/a&gt;: the package registry&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blessed.rs/" target="_blank" rel="noopener"
 &gt;Blessed.rs&lt;/a&gt;: curated crate recommendations by category&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-trend-pattern"&gt;The trend pattern
&lt;/h2&gt;&lt;p&gt;Language adoption tends to follow ecosystem trends rather than purely technical merit. I started with Java. Then OpenStack brought Python into infrastructure work. Then Kubernetes arrived and its ecosystem was written in Go — so Go became the language of the cloud-native world by proximity as much as by choice.&lt;/p&gt;
&lt;p&gt;Rust looks like the next turn of that cycle. The &amp;ldquo;rewrite it in Rust&amp;rdquo; trend is real and growing — CLI tooling, parts of the Linux kernel, browser engines, cloud infrastructure. If the pattern holds, the ecosystem will pull Rust into more places where it becomes the pragmatic choice rather than the deliberate one.&lt;/p&gt;
&lt;p&gt;Haven&amp;rsquo;t given it a serious attempt yet. Worth doing — not because Rust is clearly the right tool for the things currently being built, but because being ahead of the ecosystem trend rather than behind it is how you end up with useful experience when the moment arrives. The tooling is good, the learning resources are good, and the borrow checker will teach you something about memory regardless of whether you end up writing Rust in production.&lt;/p&gt;</description></item><item><title>Terminal Multiplexers</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/dev-environment/terminal-multiplexers/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/dev-environment/terminal-multiplexers/</guid><description>&lt;p&gt;This note explores the choice between &lt;code&gt;Zellij&lt;/code&gt; and &lt;code&gt;tmux&lt;/code&gt; for terminal multiplexing.&lt;/p&gt;
&lt;h2 id="why-use-a-terminal-multiplexer"&gt;Why use a terminal multiplexer?
&lt;/h2&gt;&lt;p&gt;Terminal multiplexers allow you to run multiple terminal sessions within a single window, detach from them, and reattach later. This is incredibly useful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Persistent sessions (e.g., long-running processes continue even if your SSH connection drops).&lt;/li&gt;
&lt;li&gt;Organizing multiple tasks (tabs, panes).&lt;/li&gt;
&lt;li&gt;Remote development.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tmux"&gt;Tmux
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://github.com/tmux/tmux" target="_blank" rel="noopener"
 &gt;https://github.com/tmux/tmux&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt; &lt;code&gt;tmux&lt;/code&gt; is a long-standing and extremely powerful terminal multiplexer. It&amp;rsquo;s highly configurable and has a vast user base.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mature and stable.&lt;/li&gt;
&lt;li&gt;Very flexible and customizable.&lt;/li&gt;
&lt;li&gt;Widely adopted, lots of resources and plugins.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configuration can be complex and requires significant effort to set up to personal taste.&lt;/li&gt;
&lt;li&gt;Default keybindings can be arcane.&lt;/li&gt;
&lt;li&gt;Can feel a bit dated in terms of user experience compared to newer alternatives.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="zellij"&gt;Zellij
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://zellij.dev/" target="_blank" rel="noopener"
 &gt;https://zellij.dev/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt; &lt;code&gt;Zellij&lt;/code&gt; is a newer, more modern terminal workspace and multiplexer, designed with a focus on good defaults and a more intuitive user experience.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Modern design and user interface.&lt;/li&gt;
&lt;li&gt;Sensible defaults that often require less configuration out of the box.&lt;/li&gt;
&lt;li&gt;Built-in layout management.&lt;/li&gt;
&lt;li&gt;Rust-based, often praised for performance and safety.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Newer, so the ecosystem of plugins and community support is smaller than &lt;code&gt;tmux&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;May not have the sheer depth of customization options available in &lt;code&gt;tmux&lt;/code&gt; (though this is also a pro for simplicity).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="initial-thoughts--direction"&gt;Initial Thoughts / Direction
&lt;/h2&gt;&lt;p&gt;Given the preference for good defaults and minimal tinkering, &lt;code&gt;Zellij&lt;/code&gt; is the stronger contender — modern take on multiplexing without the configuration overhead of &lt;code&gt;tmux&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="current-status"&gt;Current status
&lt;/h2&gt;&lt;p&gt;Not using either. The setup cost hasn&amp;rsquo;t been worth it yet — plain terminal, one thing per tab works fine for now.&lt;/p&gt;
&lt;p&gt;The main argument for multiplexers is session persistence: if your connection drops or terminal closes, the session keeps running server-side. That matters most when SSHing into remote servers and running things interactively. That pattern is largely avoided here in favour of CI/CD pipelines — if something needs to run remotely, it runs in a pipeline, not in a terminal session.&lt;/p&gt;
&lt;p&gt;Working locally with a modern terminal (iTerm2, Wezterm, etc.) that has native tabs and split panes, the marginal gain is genuinely small day-to-day. Rational laziness — the cost-benefit only flips when remote work or session persistence becomes a real part of the workflow.&lt;/p&gt;
&lt;p&gt;Will revisit if that assumption changes.&lt;/p&gt;</description></item><item><title>Terminal Setup Notes (macOS): Kitty → Ghostty Exploration</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/dev-environment/terminal/</link><pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/dev-environment/terminal/</guid><description>&lt;p&gt;I&amp;rsquo;ve been using &lt;strong&gt;kitty&lt;/strong&gt; as my main terminal for a while. It&amp;rsquo;s fast, stable, and very capable — but I&amp;rsquo;ve realized I don&amp;rsquo;t actually enjoy tweaking terminal configs or maintaining a highly customized setup.&lt;/p&gt;
&lt;p&gt;So I&amp;rsquo;m exploring simpler alternatives with good defaults.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="current-direction-ghostty"&gt;Current direction: Ghostty
&lt;/h2&gt;&lt;p&gt;Trying out: &lt;strong&gt;Ghostty&lt;/strong&gt;&lt;br&gt;
&lt;a class="link" href="https://ghostty.org/" target="_blank" rel="noopener"
 &gt;https://ghostty.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Why:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clean macOS-native feel&lt;/li&gt;
&lt;li&gt;GPU-accelerated and fast&lt;/li&gt;
&lt;li&gt;Tabs + splits built in&lt;/li&gt;
&lt;li&gt;Designed for sane defaults (low configuration overhead)&lt;/li&gt;
&lt;li&gt;Keyboard-first workflow works well out of the box&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;My only config change:&lt;/strong&gt; Remapped tab switching shortcut (default &lt;code&gt;][&lt;/code&gt; to &lt;code&gt;alt-[/]&lt;/code&gt; for easier access on a Swedish keyboard layout).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Goal:&lt;br&gt;
Less time configuring terminal → more time working.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="why-the-switch"&gt;Why the switch
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Simplified setup:&lt;/strong&gt; I found myself spending less time tweaking and more time working.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Perceived responsiveness:&lt;/strong&gt; Both are fast, but Ghostty felt marginally snappier in heavy-usage scenarios.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clean design:&lt;/strong&gt; The aesthetic and functional minimalism resonated more with my current preferences.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="what-im-moving-away-from-for-now"&gt;What I&amp;rsquo;m moving away from (for now)
&lt;/h2&gt;&lt;h2 id="kitty"&gt;kitty
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://sw.kovidgoyal.net/kitty/" target="_blank" rel="noopener"
 &gt;https://sw.kovidgoyal.net/kitty/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What I liked:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Very fast, GPU-accelerated rendering&lt;/li&gt;
&lt;li&gt;Highly configurable via a single &lt;code&gt;kitty.conf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Excellent font rendering — ligatures, custom fonts&lt;/li&gt;
&lt;li&gt;Extensible with Kitten modules (tabs, scrollback, multiplexing)&lt;/li&gt;
&lt;li&gt;Stable and mature&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why I&amp;rsquo;m moving on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Too much customization surface area&lt;/li&gt;
&lt;li&gt;I don&amp;rsquo;t actually enjoy tuning it&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="other-tools-ive-looked-at"&gt;Other tools I&amp;rsquo;ve looked at
&lt;/h2&gt;&lt;h2 id="warp"&gt;Warp
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://warp.dev/" target="_blank" rel="noopener"
 &gt;https://warp.dev/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Warp feels like a &amp;ldquo;terminal reinvented&amp;rdquo; (more IDE-like, block-based UI, AI features). It&amp;rsquo;s interesting, but feels a bit too opinionated and visually heavy for my taste.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="other-terminal-emulators-briefly-noted"&gt;Other Terminal Emulators (briefly noted)
&lt;/h2&gt;&lt;p&gt;While Kitty and Ghostty are modern GPU-accelerated terminals, it&amp;rsquo;s worth acknowledging other terminal emulators that have been foundational or offer different philosophies.&lt;/p&gt;
&lt;h3 id="xterm-and-related-ttys"&gt;xterm (and related TTYs)
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://www.x.org/releases/X11R7.6/doc/man/man1/xterm.1.xhtml" target="_blank" rel="noopener"
 &gt;https://www.x.org/releases/X11R7.6/doc/man/man1/xterm.1.xhtml&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The classic X Window System terminal emulator. While not as feature-rich or graphically advanced as modern options, &lt;code&gt;xterm&lt;/code&gt; (and its derivatives like &lt;code&gt;urxvt&lt;/code&gt;, &lt;code&gt;st&lt;/code&gt;, etc.) represent the minimalist, highly customizable end of the spectrum. They often prioritize resource efficiency and adherence to traditional Unix principles. Good for when you need something simple and rock-solid, but usually requires more effort to get a pleasant default experience.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="current-philosophy"&gt;Current philosophy
&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;m optimizing for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;minimal clutter&lt;/li&gt;
&lt;li&gt;fast keyboard workflow&lt;/li&gt;
&lt;li&gt;good defaults (not deep config systems)&lt;/li&gt;
&lt;li&gt;fewer moving parts&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="current-setup-direction"&gt;Current setup direction
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Terminal: &lt;strong&gt;Ghostty&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Tabs: built-in (no extra tooling yet)&lt;/li&gt;
&lt;li&gt;Multiplexing: not using tmux/Zellij for now&lt;/li&gt;
&lt;li&gt;Keeping things intentionally simple&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="open-question"&gt;Open question
&lt;/h2&gt;&lt;p&gt;If Ghostty tabs feel too minimal in real use, I may revisit:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zellij (for structured sessions)&lt;/li&gt;
&lt;li&gt;tmux (unlikely unless necessary)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For now, keeping it simple on purpose.&lt;/p&gt;</description></item><item><title>Bash</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/bash/</link><pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/bash/</guid><description>&lt;p&gt;Bash is unavoidable in DevOps work — CI/CD pipelines, container entrypoints, system init scripts, and quick automation all end up as shell scripts eventually. Knowing how to write it well saves a lot of pain.&lt;/p&gt;
&lt;h2 id="tooling"&gt;Tooling
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Linting:&lt;/strong&gt; &lt;a class="link" href="https://www.shellcheck.net/" target="_blank" rel="noopener"
 &gt;ShellCheck&lt;/a&gt;: catches common mistakes and anti-patterns. Run it in CI, or install the IDE plugin. Most of what it flags is genuinely wrong.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IDE:&lt;/strong&gt; Any editor works. ShellCheck integrations exist for VS Code, IntelliJ, Vim, and most others.&lt;/p&gt;
&lt;h2 id="good-habits"&gt;Good habits
&lt;/h2&gt;&lt;p&gt;Set these at the top of every non-trivial script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;set -euo pipefail
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-e&lt;/code&gt; — exit on error&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-u&lt;/code&gt; — error on unset variables&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o pipefail&lt;/code&gt;: catch errors in pipes, not just the last command&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Use &lt;code&gt;shellcheck&lt;/code&gt; before committing. Most Bash bugs it catches are subtle and only surface under specific conditions in production.&lt;/p&gt;
&lt;h2 id="when-to-reach-for-python-instead"&gt;When to reach for Python instead
&lt;/h2&gt;&lt;p&gt;When the script grows beyond ~50 lines, needs associative arrays, JSON parsing, or HTTP calls — switch to Python. Bash is great glue; it&amp;rsquo;s a poor application language.&lt;/p&gt;
&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.shellcheck.net/" target="_blank" rel="noopener"
 &gt;ShellCheck&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.gnu.org/software/bash/manual/" target="_blank" rel="noopener"
 &gt;Bash Reference Manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://google.github.io/styleguide/shellguide.html" target="_blank" rel="noopener"
 &gt;Google Shell Style Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Go</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/golang/</link><pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/golang/</guid><description>&lt;p&gt;Go is my go-to language for backend services, CLI tools, and DevOps tooling. The standard library covers most of what you need, the compiler is fast, and the concurrency model (goroutines + channels) makes it well suited for infrastructure-adjacent work.&lt;/p&gt;
&lt;h2 id="tooling"&gt;Tooling
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;IDE:&lt;/strong&gt; &lt;a class="link" href="https://www.jetbrains.com/go/" target="_blank" rel="noopener"
 &gt;GoLand&lt;/a&gt;: JetBrains&amp;rsquo; Go-specific IDE. Solid refactoring, built-in debugger, good test runner integration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Formatting:&lt;/strong&gt; &lt;code&gt;gofmt&lt;/code&gt; / &lt;code&gt;goimports&lt;/code&gt;: no debates about style, just run it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linting:&lt;/strong&gt; &lt;a class="link" href="https://golangci-lint.run/" target="_blank" rel="noopener"
 &gt;golangci-lint&lt;/a&gt;: meta-linter that runs a configurable set of linters in one pass. Worth wiring into CI.&lt;/p&gt;
&lt;h2 id="testing"&gt;Testing
&lt;/h2&gt;&lt;p&gt;Testing is built into the standard library — &lt;code&gt;go test ./...&lt;/code&gt; is all you need to get started. Table-driven tests are the idiomatic pattern for covering multiple cases cleanly.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TestAdd&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;t&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;testing&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;T&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;cases&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; []&lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt;{ &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;want&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; }{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cases&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;got&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;); &lt;span style="color:#a6e22e"&gt;got&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;want&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;t&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Errorf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Add(%d, %d) = %d, want %d&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;got&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;want&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://go.dev/" target="_blank" rel="noopener"
 &gt;go.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://go.dev/doc/effective_go" target="_blank" rel="noopener"
 &gt;Effective Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://gobyexample.com/" target="_blank" rel="noopener"
 &gt;Go by Example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>K9s &amp; Lens</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/frameworks-tools/k9s/</link><pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/frameworks-tools/k9s/</guid><description>&lt;p&gt;You run everything with &lt;code&gt;kubectl&lt;/code&gt;. Get pods, describe, logs, exec, delete, apply — fifty times a day across five namespaces. It works, but every command is a context switch: type, wait, read, type again. &lt;code&gt;-n namespace&lt;/code&gt; on every single invocation.&lt;/p&gt;
&lt;p&gt;So you use K9s. A terminal UI that shows your entire cluster in one view. Switch namespaces and clusters in a keystroke, tail logs in real time, exec into a pod without constructing the command — everything you reach for in &lt;code&gt;kubectl&lt;/code&gt;, but without the friction.&lt;/p&gt;
&lt;h2 id="k9s"&gt;K9s
&lt;/h2&gt;&lt;p&gt;K9s is a TUI (terminal UI) for Kubernetes. It stays in your terminal, updates live, and is keyboard-driven throughout.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install derailed/k9s/k9s
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;k9s &lt;span style="color:#75715e"&gt;# connect to current context&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;k9s --context prod &lt;span style="color:#75715e"&gt;# specific context&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;k9s -n monitoring &lt;span style="color:#75715e"&gt;# start in a specific namespace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="navigation"&gt;Navigation
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Key&lt;/th&gt;
 &lt;th&gt;Action&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;:pod&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Jump to pods view&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;:deploy&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Deployments&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;:svc&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Services&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;:ns&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Switch namespace&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Filter/search&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;l&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Logs&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;e&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Edit resource YAML&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Describe&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Shell into pod&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;ctrl-d&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Delete&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;?&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Help / full keybinding list&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Most resource types are reachable by typing &lt;code&gt;:&lt;/code&gt; followed by the resource name — &lt;code&gt;:configmap&lt;/code&gt;, &lt;code&gt;:secret&lt;/code&gt;, &lt;code&gt;:ingress&lt;/code&gt;, &lt;code&gt;:pvc&lt;/code&gt;, and so on.&lt;/p&gt;
&lt;h3 id="why-tui-over-gui"&gt;Why TUI over GUI
&lt;/h3&gt;&lt;p&gt;K9s lives in the terminal alongside your other tools. No window switching, works over SSH, starts instantly, and the keyboard-driven workflow is faster once it is in muscle memory. For day-to-day cluster work it is the right default.&lt;/p&gt;
&lt;h2 id="lens"&gt;Lens
&lt;/h2&gt;&lt;p&gt;Lens is a desktop GUI for Kubernetes — a full IDE-style interface with a visual cluster overview, resource browsing, metrics charts, log streaming, and terminal access built in.&lt;/p&gt;
&lt;p&gt;It is the better choice when you need to onboard someone who is not yet comfortable with the terminal, or when you want a visual overview to share with a non-technical stakeholder. For engineers doing operational work all day, K9s is faster.&lt;/p&gt;
&lt;p&gt;Worth noting: Lens has moved toward a commercial model (Lens Desktop Pro). &lt;strong&gt;&lt;a class="link" href="https://github.com/MuhammedKalkan/OpenLens" target="_blank" rel="noopener"
 &gt;OpenLens&lt;/a&gt;&lt;/strong&gt; is the open-source build of the same codebase, without the account requirement.&lt;/p&gt;
&lt;h2 id="kubectx--kubens"&gt;kubectx / kubens
&lt;/h2&gt;&lt;p&gt;If K9s is more than you need and you just want to stop typing &lt;code&gt;--context&lt;/code&gt; and &lt;code&gt;-n&lt;/code&gt; on every command, &lt;code&gt;kubectx&lt;/code&gt; and &lt;code&gt;kubens&lt;/code&gt; solve exactly that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectx &lt;span style="color:#75715e"&gt;# list contexts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectx prod &lt;span style="color:#75715e"&gt;# switch to prod context&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectx - &lt;span style="color:#75715e"&gt;# switch back to previous context&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubens &lt;span style="color:#75715e"&gt;# list namespaces&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubens monitoring &lt;span style="color:#75715e"&gt;# switch default namespace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No TUI, no GUI — just fast context and namespace switching that persists for the rest of your terminal session. Install alongside K9s; they complement each other.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install kubectx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://k9scli.io/" target="_blank" rel="noopener"
 &gt;K9s documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/derailed/k9s" target="_blank" rel="noopener"
 &gt;K9s GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://k8slens.dev/" target="_blank" rel="noopener"
 &gt;Lens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/MuhammedKalkan/OpenLens" target="_blank" rel="noopener"
 &gt;OpenLens&lt;/a&gt; — open-source Lens build&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ahmetb/kubectx" target="_blank" rel="noopener"
 &gt;kubectx/kubens&lt;/a&gt; — fast context and namespace switching&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Python</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/python/</link><pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/languages/python/</guid><description>&lt;p&gt;Python is my scripting and automation language of choice. I reach for it when Bash starts getting unwieldy — data processing, API interactions, infrastructure automation scripts, and one-off tooling.&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;2024 note:&lt;/strong&gt; For anything beyond quick scripts I&amp;rsquo;m increasingly reaching for Go instead. Better performance, a single compiled binary, and stronger typing make Go a more honest choice for tools that end up running in production. Python still wins for data work and anything where the ecosystem matters (ML, pandas, etc.).&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="tooling"&gt;Tooling
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;IDE:&lt;/strong&gt; &lt;a class="link" href="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener"
 &gt;PyCharm&lt;/a&gt;: JetBrains&amp;rsquo; Python IDE. Good for larger projects. For scripts and smaller work, IntelliJ IDEA with the Python plugin does the job.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Formatting:&lt;/strong&gt; &lt;a class="link" href="https://black.readthedocs.io/" target="_blank" rel="noopener"
 &gt;Black&lt;/a&gt;: opinionated formatter, no configuration needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linting:&lt;/strong&gt; &lt;a class="link" href="https://docs.astral.sh/ruff/" target="_blank" rel="noopener"
 &gt;Ruff&lt;/a&gt;: extremely fast linter and formatter, replacing Flake8 + isort in most setups.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dependency management:&lt;/strong&gt; &lt;a class="link" href="https://docs.astral.sh/uv/" target="_blank" rel="noopener"
 &gt;uv&lt;/a&gt;: modern, fast package manager replacing pip/virtualenv for most workflows.&lt;/p&gt;
&lt;h2 id="where-i-use-it"&gt;Where I use it
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Infrastructure automation and scripting alongside Ansible&lt;/li&gt;
&lt;li&gt;Data processing and log analysis&lt;/li&gt;
&lt;li&gt;CLI tooling for internal workflows&lt;/li&gt;
&lt;li&gt;Quick API clients and integration scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.python.org/3/" target="_blank" rel="noopener"
 &gt;docs.python.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://realpython.com/" target="_blank" rel="noopener"
 &gt;Real Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>