<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Topgrade on Chris Titus Tech | Tech Content Creator</title><link>https://christitus.com/tags/topgrade/</link><description>Recent content in Topgrade on Chris Titus Tech | Tech Content Creator</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><managingEditor>Chris Titus</managingEditor><webMaster>Chris Titus</webMaster><lastBuildDate>Tue, 28 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://christitus.com/tags/topgrade/index.xml" rel="self" type="application/rss+xml"/><item><title>Topgrade Linux</title><link>https://christitus.com/topgrade-linux/</link><pubDate>Tue, 28 Apr 2026 00:00:00 +0000</pubDate><author>Chris Titus</author><guid>https://christitus.com/topgrade-linux/</guid><description>&lt;p&gt;Most Linux users only run their package manager and call it a day. That updates your system packages, but it often leaves the rest of your machine in a partially updated state. If you use &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;cargo&lt;/code&gt;, &lt;code&gt;flatpak&lt;/code&gt;, &lt;code&gt;snap&lt;/code&gt;, &lt;code&gt;brew&lt;/code&gt;, &lt;code&gt;oh-my-zsh&lt;/code&gt;, VS Code extensions, or even dotfile repos, those pieces can all drift out of date separately.&lt;/p&gt;
&lt;p&gt;Topgrade exists to solve this exact problem. It gives you one command to update almost everything you actually use.&lt;/p&gt;
&lt;p&gt;Keeping your machine consistently updated is not just about getting shiny new versions. It is about reducing weird breakage from version mismatch, closing security holes faster, and spending less time doing repetitive maintenance.&lt;/p&gt;
&lt;h2 id="what-topgrade-is"&gt;What Topgrade Is&lt;/h2&gt;
&lt;p&gt;Topgrade is a command-line tool that runs update commands across multiple package managers and tools in sequence. Instead of remembering ten different commands, you run one:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;topgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Topgrade handles things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System package managers (&lt;code&gt;apt&lt;/code&gt;, &lt;code&gt;dnf&lt;/code&gt;, &lt;code&gt;pacman&lt;/code&gt;, &lt;code&gt;zypper&lt;/code&gt;, &lt;code&gt;eopkg&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Language package managers (&lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;cargo&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt;, &lt;code&gt;gem&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Universal package managers (&lt;code&gt;flatpak&lt;/code&gt;, &lt;code&gt;snap&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Tooling ecosystems (&lt;code&gt;rustup&lt;/code&gt;, &lt;code&gt;asdf&lt;/code&gt;, &lt;code&gt;sdkman&lt;/code&gt;, &lt;code&gt;mise&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Repository pulls (dotfiles or any local git repos)&lt;/li&gt;
&lt;li&gt;Shell and plugin ecosystems (Oh My Zsh, Fish plugins, Vim/Neovim plugins, etc.)&lt;/li&gt;
&lt;li&gt;VS Code extensions&lt;/li&gt;
&lt;li&gt;Container images (&lt;code&gt;docker&lt;/code&gt;, &lt;code&gt;podman&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Firmware via &lt;code&gt;fwupd&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The exact behavior depends on your distro and what tools you have installed, but the core idea is the same: centralize updates.&lt;/p&gt;
&lt;h2 id="the-problem-with-just-do-system-updates"&gt;The Problem with &amp;ldquo;Just Do System Updates&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;When people say &amp;ldquo;I update regularly,&amp;rdquo; they usually mean one command:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Debian/Ubuntu: &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Fedora: &lt;code&gt;sudo dnf upgrade&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Arch: &lt;code&gt;sudo pacman -Syu&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That is good, but incomplete for most power users.&lt;/p&gt;
&lt;h3 id="you-are-only-updating-one-layer"&gt;You Are Only Updating One Layer&lt;/h3&gt;
&lt;p&gt;Modern Linux setups have multiple software layers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS packages&lt;/li&gt;
&lt;li&gt;Userland language packages&lt;/li&gt;
&lt;li&gt;Third-party tools installed outside distro repos&lt;/li&gt;
&lt;li&gt;Application stores (&lt;code&gt;flatpak&lt;/code&gt;, &lt;code&gt;snap&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Git-managed configs and scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If only one layer is current, your system is still effectively behind.&lt;/p&gt;
&lt;h3 id="human-memory-is-the-bottleneck"&gt;Human Memory Is the Bottleneck&lt;/h3&gt;
&lt;p&gt;Nobody wants a giant sticky note of update commands. Even experienced users forget steps when busy.&lt;/p&gt;
&lt;p&gt;Topgrade removes this memory tax. You no longer need to think, &amp;ldquo;Did I update &lt;code&gt;cargo&lt;/code&gt; crates this week? Did I pull dotfiles?&amp;rdquo;&lt;/p&gt;
&lt;h3 id="drift-causes-hard-to-debug-issues"&gt;Drift Causes Hard-to-Debug Issues&lt;/h3&gt;
&lt;p&gt;Many random issues come from version drift between tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A CLI tool expects newer dependencies than your local setup has&lt;/li&gt;
&lt;li&gt;A shell plugin manager is old while the shell itself is new&lt;/li&gt;
&lt;li&gt;User-level packages lag behind system-level updates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Topgrade reduces this drift by making full-stack updates routine.&lt;/p&gt;
&lt;h2 id="installation"&gt;Installation&lt;/h2&gt;
&lt;p&gt;Topgrade is available through a wide range of package managers. Pick whichever fits your setup:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Arch Linux (AUR)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;yay -S topgrade-bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# or build from source:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;yay -S topgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Fedora / RHEL / AlmaLinux (Copr)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf copr &lt;span class="nb"&gt;enable&lt;/span&gt; lilay/topgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install topgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Debian / Ubuntu (via deb-get)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;deb-get install topgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# macOS or Linux (Homebrew)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install topgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# NixOS / Nix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nix-env -iA nixpkgs.topgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Alpine Linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apk add topgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Void Linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo xbps-install -S topgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Python (pip / pipx / uv)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pipx install topgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Via Cargo (always gets latest release)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cargo install topgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="notices tip" &gt;&lt;p&gt;If your distro repo version is old, installing via &lt;code&gt;cargo&lt;/code&gt; or &lt;code&gt;pipx&lt;/code&gt; is the fastest way to get the latest release without waiting for a package maintainer.&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;You can also grab a pre-built self-updating binary directly from the &lt;a href="https://github.com/topgrade-rs/topgrade/releases"&gt;releases page&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="first-run-what-to-expect"&gt;First Run: What to Expect&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;topgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You may be prompted for &lt;code&gt;sudo&lt;/code&gt; depending on what update steps need elevated privileges. The first run can take a while because it catches up everything at once — that is normal.&lt;/p&gt;
&lt;h3 id="useful-flags"&gt;Useful Flags&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flag&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--dry-run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Preview what would run without making changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-y&lt;/code&gt; / &lt;code&gt;--yes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Skip all confirmation prompts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--only &amp;lt;step&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run only specific steps (e.g. &lt;code&gt;--only system flatpak&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--disable &amp;lt;step&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Skip specific steps for this run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--edit-config&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Open your config file in &lt;code&gt;$EDITOR&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--config-reference&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Print all available config options&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--remote-host-limit &amp;lt;host&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Limit remote execution to specific hosts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="safety-how-to-use-it-responsibly"&gt;Safety: How to Use It Responsibly&lt;/h2&gt;
&lt;p&gt;Topgrade is powerful, so use it with a sane workflow.&lt;/p&gt;
&lt;h3 id="start-with-a-dry-run"&gt;Start with a Dry Run&lt;/h3&gt;
&lt;p&gt;Preview what it would do before committing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;topgrade --dry-run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is especially useful the first time you set it up, or after making major changes to your configuration.&lt;/p&gt;
&lt;h3 id="keep-backups-and-snapshots"&gt;Keep Backups and Snapshots&lt;/h3&gt;
&lt;p&gt;Before major updates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Snapshot with Btrfs/Timeshift/ZFS if available&lt;/li&gt;
&lt;li&gt;Backup important config and data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No update tool replaces backups.&lt;/p&gt;
&lt;h3 id="exclude-what-you-do-not-want"&gt;Exclude What You Do Not Want&lt;/h3&gt;
&lt;p&gt;You can configure Topgrade to skip specific steps you do not trust or do not need. That lets you keep one-command convenience while controlling risk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended exclusion for cautious users — firmware updates:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I had firmware updates break my system before, so I prefer to review them separately. Disable them in your config:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;~/.config/topgrade.toml&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;misc&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Skip firmware updates entirely&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;disable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;firmware&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;firmware&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# If firmware step does run, only show available updates — do not install&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;upgrade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="notices note" &gt;&lt;p&gt;The double-exclusion is intentional. &lt;code&gt;disable&lt;/code&gt; skips the step outright; &lt;code&gt;upgrade = false&lt;/code&gt; under &lt;code&gt;[firmware]&lt;/code&gt; acts as a fallback safety net so that even if the step runs, nothing actually gets flashed.&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;For a one-off skip without editing your config:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;topgrade --disable firmware
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="read-the-output"&gt;Read the Output&lt;/h3&gt;
&lt;p&gt;Treat updates like maintenance, not background noise. If one step fails, investigate before your next cycle. Topgrade reports each step&amp;rsquo;s result clearly — use it.&lt;/p&gt;
&lt;h2 id="configuration"&gt;Configuration&lt;/h2&gt;
&lt;p&gt;Topgrade&amp;rsquo;s config lives at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.config/topgrade.toml&lt;/code&gt; (primary location)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.config/topgrade/topgrade.toml&lt;/code&gt; (alternative; both are checked)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the first run with no config present, Topgrade creates one for you automatically. Open and edit it with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;topgrade --edit-config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Print every available option with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;topgrade --config-reference
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="key-configuration-options"&gt;Key Configuration Options&lt;/h3&gt;
&lt;p&gt;Here is a practical subset of the most useful settings:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;misc&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Cache sudo credentials upfront to avoid mid-run password prompts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;pre_sudo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Steps to always skip&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;disable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;firmware&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;snap&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Steps to run before all others&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;chezmoi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Steps to run after all others&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;last&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;flatpak&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Ignore failures for noisy or unreliable steps&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;ignore_failures&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pip3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Clean up old temp files after a run&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;cleanup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Send a desktop notification when done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;notify_end&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;on_failure&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Pull these repos every time you run topgrade&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;repos&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;~/dotfiles&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;~/src/*/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Pull in parallel (default: 5)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;max_concurrency&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Rebase and autostash instead of plain merge&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--rebase --autostash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;linux&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Arch: choose your AUR helper (autodetect, paru, yay, pikaur, etc.)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;arch_package_manager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;paru&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Extra args passed to yay/paru&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;yay_arguments&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--nodevel&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;flatpak&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Update system-wide Flatpak installs (requires sudo)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;use_sudo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;python&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Update pip packages (disabled by default)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;enable_pip_review&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;firmware&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Only show available firmware updates, do not install&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;upgrade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Full syntax and every available option: &lt;a href="https://github.com/topgrade-rs/topgrade/blob/main/config.example.toml"&gt;https://github.com/topgrade-rs/topgrade/blob/main/config.example.toml&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="custom-commands"&gt;Custom Commands&lt;/h3&gt;
&lt;p&gt;You can hook your own scripts into the update pipeline using &lt;code&gt;pre_commands&lt;/code&gt;, &lt;code&gt;post_commands&lt;/code&gt;, or &lt;code&gt;commands&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Runs before anything else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pre_commands&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;Backup dotfiles&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;chezmoi git -- push&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Runs after everything else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;post_commands&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;Reload shell&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;exec $SHELL&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Custom named steps that appear in the Topgrade run&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;Update Python env&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;~/dev/.venv/bin/pip install -U pip&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="remote-execution"&gt;Remote Execution&lt;/h3&gt;
&lt;p&gt;If you maintain multiple machines, Topgrade can SSH into them and run updates before acting locally:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;misc&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;remote_topgrades&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;homeserver&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;nas&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;ssh_arguments&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;-o ConnectTimeout=2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Limit to a single host ad hoc:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;topgrade --remote-host-limit homeserver
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="recommended-update-workflow"&gt;Recommended Update Workflow&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;For desktops and workstations:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;topgrade --dry-run&lt;/code&gt; if you have made major config changes&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;topgrade&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Reboot when kernel, drivers, or core libraries update&lt;/li&gt;
&lt;li&gt;Quickly test key workflows: browser, editor, shell, audio, GPU apps&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;For servers and critical machines:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Snapshot or backup first&lt;/li&gt;
&lt;li&gt;Run Topgrade with a limited scope: &lt;code&gt;topgrade --only system&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Validate services and logs after the update&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Topgrade is a force multiplier, but your operational discipline still matters.&lt;/p&gt;
&lt;h2 id="when-you-might-not-want-topgrade"&gt;When You Might Not Want Topgrade&lt;/h2&gt;
&lt;p&gt;Topgrade is not mandatory for every scenario:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minimal systems that only use a single package manager&lt;/li&gt;
&lt;li&gt;Locked-down enterprise environments with strict patch management pipelines&lt;/li&gt;
&lt;li&gt;Users who want explicit manual control over every update decision&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your stack is simple, manual updates are fine. But for most modern Linux users running layered tooling across multiple ecosystems, Topgrade saves real time and reduces silent drift.&lt;/p&gt;
&lt;h2 id="topgrade-vs-manual-updates"&gt;Topgrade vs Manual Updates&lt;/h2&gt;
&lt;p&gt;Manual updates are fine when your environment is tiny.&lt;/p&gt;
&lt;p&gt;Topgrade wins when your environment is real-world:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multiple package ecosystems&lt;/li&gt;
&lt;li&gt;Frequent toolchain changes&lt;/li&gt;
&lt;li&gt;Several machines to maintain&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The benefit is not just speed. It is reliability through repeatability.&lt;/p&gt;
&lt;h2 id="final-thoughts"&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;If you are serious about Linux reliability, &amp;ldquo;just update the system packages&amp;rdquo; is no longer enough.&lt;/p&gt;
&lt;p&gt;Topgrade gives you a practical middle ground between fully manual maintenance and fragile home-rolled shell scripts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One command&lt;/li&gt;
&lt;li&gt;Broad coverage across every ecosystem you actually use&lt;/li&gt;
&lt;li&gt;Configurable behavior and custom hooks&lt;/li&gt;
&lt;li&gt;Better long-term system hygiene&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Use it weekly, keep backups, and stop letting half your toolchain lag behind.&lt;/p&gt;
&lt;h2 id="walkthrough-video"&gt;Walkthrough Video&lt;/h2&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/YuozYQ6kILg?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;</description></item></channel></rss>