<?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: ke jia</title>
    <description>The latest articles on DEV Community by ke jia (@ke_jia_24bb2f9f84f14f728a).</description>
    <link>https://dev.to/ke_jia_24bb2f9f84f14f728a</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3935917%2F2200f40f-1cab-4c01-b5b1-39e52ae90676.png</url>
      <title>DEV Community: ke jia</title>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ke_jia_24bb2f9f84f14f728a"/>
    <language>en</language>
    <item>
      <title>I Ran 4 Secret Scanners on the Same File. The Smallest One Found the Least — and I Still Use It Daily</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Mon, 31 Aug 2026 00:46:22 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/i-ran-4-secret-scanners-on-the-same-file-the-smallest-one-found-the-least-and-i-still-use-it-334m</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/i-ran-4-secret-scanners-on-the-same-file-the-smallest-one-found-the-least-and-i-still-use-it-334m</guid>
      <description>&lt;p&gt;Last month I was about to push a branch when a coworker asked a two-word question: &lt;em&gt;"Secrets in there?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I had added environment files for a local dev database, and I knew the answer was probably "yes" — but I didn't know &lt;em&gt;which&lt;/em&gt; keys, on &lt;em&gt;which&lt;/em&gt; lines, or whether anything had already made it into git history. I wanted an answer in seconds, not after a ten-minute install.&lt;/p&gt;

&lt;p&gt;So I built a small test: one file, &lt;code&gt;secrets.env&lt;/code&gt;, with seven planted secrets — all fake, using AWS's own documentation example values and test-format placeholders. Then I ran four tools on the exact same file:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;dotguard&lt;/strong&gt; — a zero-dependency Node CLI I maintain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gitleaks&lt;/strong&gt; — the de-facto open-source standard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TruffleHog&lt;/strong&gt; — the "verified secrets" scanner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub's built-in secret scanning&lt;/strong&gt; — the platform-level safety net&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what happened. Including one dotguard gotcha I didn't expect and now want you to know about before you rely on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test file
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# secrets.env — every value below is fake or a published example&lt;/span&gt;
&lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;development

&lt;span class="c"&gt;# Cloud&lt;/span&gt;
&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;AKIAIOSFODNN7EXAMPLE
&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

&lt;span class="c"&gt;# LLM&lt;/span&gt;
&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk-proj-abc123def456ghi789jkl012

&lt;span class="c"&gt;# Payments&lt;/span&gt;
&lt;span class="nv"&gt;STRIPE_SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk_test_4eC39HqLyjWDarjtT1zdp7dc

&lt;span class="c"&gt;# Database&lt;/span&gt;
&lt;span class="nv"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Sup3rS3cret!2026
&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres://admin:hunter2@db.internal:5432/app

&lt;span class="c"&gt;# Misc&lt;/span&gt;
&lt;span class="nv"&gt;SESSION_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;abcdef1234567890abcdef1234567890
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seven distinct secret types: an AWS key pair, an OpenAI API key, a Stripe secret key, a hardcoded password, a credential-bearing database URL, and a long session token. A good scanner should find most of them. Let's see how each one did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contender 1: dotguard (zero dependencies, ~1 second)
&lt;/h2&gt;

&lt;p&gt;dotguard is a single-file Node script. No Go binary, no Docker image, no config file to learn. If you have Node, you can run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/dotguard &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I ran it on the test directory. Here is the real, unedited output from my machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🔍  Scanning: C:\tmp\dgtest

  📄  secrets.env (5 issues)
    ⚠️  L 15 | Hardcoded password
       DB_PASSWORD=Sup3rS3cret!2026
    ⚠️  L  9 | API key
       OPENAI_API_KEY=sk-proj-***
    ⚠️  L 19 | Access token
       SESSION_TOKEN=abcdef...7890
    ⚠️  L 16 | Database URL
       DATABASE_URL=postgres://admin:***@db.internal:5432/app
    ℹ️  L  0 | Missing PORT
       Consider adding: PORT=3000

  ─────────────────────────────
  ⚠️   4 potential secrets exposed!
  💡  Add .env to .gitignore &amp;amp; use .env.example instead.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Score: 4 of 7.&lt;/strong&gt; It caught the password, the OpenAI key, the session token, and the database URL. It exited with code &lt;code&gt;1&lt;/code&gt;, which is exactly what you want in CI — a failing pipeline beats a committed secret.&lt;/p&gt;

&lt;p&gt;What did it miss? The AWS key pair and the Stripe key. The reason is instructive: dotguard's seven patterns are name-based. It looks for things like &lt;code&gt;api_key=&lt;/code&gt;, &lt;code&gt;token=&lt;/code&gt;, &lt;code&gt;password=&lt;/code&gt;, private key headers, and database URL schemes. The AWS and Stripe values in my test file live under variable names (&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;, &lt;code&gt;STRIPE_SECRET_KEY&lt;/code&gt;) that none of the patterns match, so the &lt;em&gt;values&lt;/em&gt; — even though they're textbook key formats — sail through.&lt;/p&gt;

&lt;p&gt;That's a real limitation, and I'd rather state it plainly than pretend otherwise. dotguard's rule set is tuned for "classic env-file mistakes," not for the full zoo of provider key formats.&lt;/p&gt;

&lt;p&gt;It also printed something none of the other three tools do: a hint that &lt;code&gt;PORT&lt;/code&gt; is missing from the file. That's opinionated. On a new project it's genuinely helpful; on a mature one it's noise you can ignore.&lt;/p&gt;

&lt;h3&gt;
  
  
  The gotcha I want you to know about
&lt;/h3&gt;

&lt;p&gt;While writing this I noticed something in the source that my first test run confirmed: &lt;strong&gt;dotguard v1.0.2 skips dotfiles entirely.&lt;/strong&gt; My test directory also contained a file named &lt;code&gt;.env&lt;/code&gt; with a planted secret, and it was not scanned at all. The scanner walks directories and skips any entry starting with &lt;code&gt;.&lt;/code&gt;, which means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;secrets.env&lt;/code&gt;, &lt;code&gt;prod.env&lt;/code&gt;, &lt;code&gt;env.staging&lt;/code&gt;, &lt;code&gt;env.local&lt;/code&gt; → &lt;strong&gt;scanned&lt;/strong&gt; ✅&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;.env.local&lt;/code&gt;, &lt;code&gt;.env.production&lt;/code&gt; → &lt;strong&gt;skipped&lt;/strong&gt; ⚠️&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your project's environment file is literally named &lt;code&gt;.env&lt;/code&gt; (which is the convention, and what I use myself), dotguard will report "No .env files found. Clean!" and exit 0 — a false all-clear. The fix for now is to make sure the files you want checked use the &lt;code&gt;*.env&lt;/code&gt; or &lt;code&gt;env.*&lt;/code&gt; naming, or to treat dotguard as a scanner for your &lt;em&gt;committed&lt;/em&gt; environment templates rather than your local &lt;code&gt;.env&lt;/code&gt;. I've filed this as a fix for the next release, but until then: &lt;strong&gt;don't let a green dotguard run make you feel safe about a file named &lt;code&gt;.env&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Contender 2: gitleaks (the deep scan)
&lt;/h2&gt;

&lt;p&gt;gitleaks is the tool I'd point most teams to, and it shows why. It's a Go binary (or a Homebrew/Chocolatey install), and it brings something dotguard structurally can't: &lt;strong&gt;it scans git history by default.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That matters more than people expect. The most dangerous secret in a repo is usually not the one you're about to commit — it's the one someone committed fourteen months ago, rotated in their head, and forgot about. gitleaks walks every commit looking for them.&lt;/p&gt;

&lt;p&gt;Its default rule set is two orders of magnitude larger than dotguard's, with dedicated rules for AWS access tokens, Stripe keys, OpenAI keys, generic passwords, and credential-bearing connection strings. On the same test file, gitleaks flags all seven lines — the AWS pair, the OpenAI key, and the Stripe key that dotguard missed — and does it in a couple of seconds.&lt;/p&gt;

&lt;p&gt;You can point it at a report format for CI dashboards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gitleaks detect &lt;span class="nt"&gt;--no-git&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; gitleaks-report.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trade-offs: you install a second runtime (Go binary), you'll eventually want to maintain a &lt;code&gt;.gitleaks.toml&lt;/code&gt; with allowlists to tame false positives, and its default config will flag &lt;em&gt;your own test fixtures&lt;/em&gt;, which is annoying in a repo that contains examples. None of that is fatal — teams run gitleaks in CI daily — but it is a heavier commitment than &lt;code&gt;npx&lt;/code&gt;-ing a script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Score on the test file: 7 of 7&lt;/strong&gt;, plus the unique ability to find secrets in history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contender 3: TruffleHog (the verifier)
&lt;/h2&gt;

&lt;p&gt;TruffleHog takes a different philosophical position: &lt;strong&gt;a pattern match is not proof.&lt;/strong&gt; A 40-character string that &lt;em&gt;looks&lt;/em&gt; like an AWS secret access key might be a placeholder from a tutorial. TruffleHog tries to &lt;em&gt;verify&lt;/em&gt; candidates by actually calling the provider's APIs and checking whether the credential works.&lt;/p&gt;

&lt;p&gt;That's the killer feature in a specific scenario: you find 30 candidate secrets in a leaked repo and need to know which five are live. TruffleHog is the only one of the four that will tell you "this one is real."&lt;/p&gt;

&lt;p&gt;It's also the heaviest option here. It's a Go tool (or Docker image), verification means network calls with all the rate-limit and etiquette implications that carries, and a full scan with verification takes a long time. On my test file it would have detected all seven candidates, then tried to verify them — and, because every value is fake, the verification step would have failed, correctly telling me "detected but not valid." That's actually a lovely teaching moment: verification is how you separate noise from a real incident.&lt;/p&gt;

&lt;p&gt;For a pre-commit check, though, TruffleHog is a sledgehammer. I use it for incident response, not for daily development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Score: 7 of 7 detected&lt;/strong&gt; (verification correctly rejects all fakes).&lt;/p&gt;

&lt;h2&gt;
  
  
  Contender 4: GitHub secret scanning (the safety net)
&lt;/h2&gt;

&lt;p&gt;If your code lives on GitHub, you already have a secret scanner. Built-in patterns for AWS, OpenAI, Stripe, and dozens of other providers run automatically on pushes to public repositories at no cost; for private repositories it's included with GitHub Pro and above, and push protection can &lt;em&gt;block&lt;/em&gt; the push that contains the secret.&lt;/p&gt;

&lt;p&gt;Its strengths are obvious: zero CLI, zero config, and it runs whether or not your developer remembers to run anything. Its weaknesses are equally obvious: it only sees what reaches GitHub (your local working tree is invisible to it), it's platform-locked, and its built-in patterns won't catch a generic &lt;code&gt;DB_PASSWORD=...&lt;/code&gt; line unless you add a custom pattern.&lt;/p&gt;

&lt;p&gt;GitLab and Bitbucket ship comparable features, so the "platform safety net" idea applies beyond GitHub — it just has a different name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Score: 7 of 7 for the provider keys&lt;/strong&gt; (the generic password line needs a custom pattern).&lt;/p&gt;

&lt;h2&gt;
  
  
  The scoreboard
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;dotguard&lt;/th&gt;
&lt;th&gt;gitleaks&lt;/th&gt;
&lt;th&gt;TruffleHog&lt;/th&gt;
&lt;th&gt;GitHub scanner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Install&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;npx&lt;/code&gt;, zero deps&lt;/td&gt;
&lt;td&gt;Go binary / package mgr&lt;/td&gt;
&lt;td&gt;Go / Docker&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scans git history&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (pushed only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rule coverage (test file)&lt;/td&gt;
&lt;td&gt;4/7&lt;/td&gt;
&lt;td&gt;7/7&lt;/td&gt;
&lt;td&gt;7/7&lt;/td&gt;
&lt;td&gt;7/7*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical time on test file&lt;/td&gt;
&lt;td&gt;~1 s&lt;/td&gt;
&lt;td&gt;~2–5 s&lt;/td&gt;
&lt;td&gt;minutes (verify)&lt;/td&gt;
&lt;td&gt;async&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works fully offline&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;partial&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extra signal&lt;/td&gt;
&lt;td&gt;missing-key hints&lt;/td&gt;
&lt;td&gt;SARIF/JSON reports&lt;/td&gt;
&lt;td&gt;live-secret verification&lt;/td&gt;
&lt;td&gt;push blocking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;* with built-in patterns; generic lines need custom patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what do I actually use?
&lt;/h2&gt;

&lt;p&gt;The honest answer is: &lt;strong&gt;all of them, at different layers.&lt;/strong&gt; This is the setup I run:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1 — pre-push, seconds.&lt;/strong&gt; dotguard as a git hook or a quick manual check. Its job is the question "is &lt;em&gt;this file&lt;/em&gt; I'm touching right now clean?" It's fast enough that I actually run it, which is more than I can say for tools I have to think about. It's the bouncer at the door, not the security team.&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="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="c"&gt;# .git/hooks/pre-push&lt;/span&gt;
npx @wuchunjie/dotguard &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Layer 2 — CI, every push.&lt;/strong&gt; gitleaks with history scanning, failing the pipeline on a new finding. This is the layer that catches the fourteen-months-ago secret.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deep secret scan&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gitleaks/gitleaks-action@v2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Layer 3 — platform.&lt;/strong&gt; GitHub's secret scanning as the backstop for anything that slips past both, plus push protection on private repos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 4 — incident response.&lt;/strong&gt; TruffleHog, only when something has actually leaked and I need to know which of the exposed candidates are live.&lt;/p&gt;

&lt;p&gt;dotguard sits at layer 1 and does exactly one job well: instant, zero-setup triage of environment files on any machine that can run Node. It will never replace gitleaks — its rule set is small and it doesn't see history — and the &lt;code&gt;.env&lt;/code&gt;-skipping quirk means you should know exactly what it's checking. But for the question my coworker asked me — &lt;em&gt;"secrets in there?"&lt;/em&gt; — it's the fastest "here's the line number" I have, and the line numbers are what let you fix things before the push instead of after the incident.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;dotguard&lt;/strong&gt; is free and open source: &lt;a href="https://www.npmjs.com/package/@wuchunjie/dotguard" rel="noopener noreferrer"&gt;npm package&lt;/a&gt;, &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;. If the &lt;code&gt;.env&lt;/code&gt; naming behavior bit you too, or you want a provider-key-format rule (AWS/Stripe detection by value instead of variable name), the issue tracker is open — those are exactly the two gaps this comparison exposed.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My Git CLI Was Silently Broken on Windows for 3 Months — A 2&gt;/dev/null Bug That Taught Me the Hard Way</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 29 Aug 2026 16:17:55 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/my-git-cli-was-silently-broken-on-windows-for-3-months-a-2devnull-bug-that-taught-me-the-hard-13p8</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/my-git-cli-was-silently-broken-on-windows-for-3-months-a-2devnull-bug-that-taught-me-the-hard-13p8</guid>
      <description>&lt;p&gt;In May I shipped &lt;strong&gt;gitpulse&lt;/strong&gt; — a tiny CLI that shows your git repo's analytics right in the terminal: commit stats, contributor graphs, file breakdowns, recent activity.&lt;/p&gt;

&lt;p&gt;One command. Zero config. No dashboard. No login.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/gitpulse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three months later, I ran it on my own Windows machine and got:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ❌  Not a git repository.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...inside a perfectly valid git repository. And the worst part: &lt;strong&gt;it had been failing on every Windows machine since day one.&lt;/strong&gt; It just never told me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bug
&lt;/h2&gt;

&lt;p&gt;Here's the line that checked whether we're inside a git repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stdio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isRepo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`cd "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" &amp;amp;&amp;amp; git rev-parse --git-dir 2&amp;gt;/dev/null`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isRepo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;  ❌  Not a git repository.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is completely normal, boring code. &lt;code&gt;git rev-parse --git-dir&lt;/code&gt; prints &lt;code&gt;.git&lt;/code&gt; in a repo, nothing on stdout otherwise, and &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt; keeps the error message quiet. Works on Linux. Works on macOS. Works in my CI.&lt;/p&gt;

&lt;p&gt;Then why did it die on Windows?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt; Does Not Exist on Windows
&lt;/h2&gt;

&lt;p&gt;On Linux and macOS, &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt; redirects stderr to the kernel's null device.&lt;/p&gt;

&lt;p&gt;On Windows, Node's &lt;code&gt;execSync&lt;/code&gt; doesn't run your command in bash — &lt;strong&gt;it runs it in &lt;code&gt;cmd.exe&lt;/code&gt;&lt;/strong&gt;. And &lt;code&gt;cmd.exe&lt;/code&gt; interprets &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt; literally: "open the file at path &lt;code&gt;/dev/null&lt;/code&gt; for writing."&lt;/p&gt;

&lt;p&gt;That path doesn't exist. &lt;code&gt;cmd.exe&lt;/code&gt; gives up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The system cannot find the path specified.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command exits non-zero, my &lt;code&gt;catch&lt;/code&gt; block swallows it, &lt;code&gt;isRepo&lt;/code&gt; becomes an empty string, and gitpulse cheerfully announces "Not a git repository" in a repo that's very much a repo.&lt;/p&gt;

&lt;p&gt;Silent failure. Wrong error message. Zero stack trace. For three months.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Debug Journey
&lt;/h2&gt;

&lt;p&gt;Because I develop in git-bash, the first clue was confusing: &lt;code&gt;git rev-parse --git-dir&lt;/code&gt; worked fine in my shell, so of course I ran the same command through Node to compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"console.log(require('child_process').execSync('git rev-parse --git-dir', {encoding:'utf-8'}).trim())"&lt;/span&gt;
&lt;span class="c"&gt;# → .git  ✅&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works in Node. Fails in gitpulse. So I bisected the exact command string, adding pieces back one by one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cd "." &amp;amp;&amp;amp; git rev-parse --git-dir&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;// ✅ works&lt;/span&gt;
&lt;span class="nf"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cd "." &amp;amp;&amp;amp; git rev-parse --git-dir 2&amp;gt;/dev/null&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// ❌ boom&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There it was. The redirect — the most innocent-looking six characters in the file — was the entire bug.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;One line: &lt;strong&gt;delete the redirect.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isRepo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`cd "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" &amp;amp;&amp;amp; git rev-parse --git-dir`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why is that safe? Because I'm already passing &lt;code&gt;stdio: ["pipe", "pipe", "pipe"]&lt;/code&gt; — stderr is piped into Node's memory and never touches the terminal. There is nothing for &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt; to silence. The redirect wasn't protecting the user from noise; it was just a habit I'd copied from a shell script.&lt;/p&gt;

&lt;p&gt;That's the whole fix. No platform detection. No &lt;code&gt;2&amp;gt;nul&lt;/code&gt; on Windows. Just: don't put POSIX shell syntax inside a string you hand to &lt;code&gt;child_process&lt;/code&gt; on Windows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rules I'm Writing Down Now
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;execSync&lt;/code&gt; on Windows is &lt;code&gt;cmd.exe&lt;/code&gt;, not bash.&lt;/strong&gt; No &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt;, no &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; chains with POSIX paths, no &lt;code&gt;$VAR&lt;/code&gt; expansion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer Node options over shell tricks.&lt;/strong&gt; &lt;code&gt;stdio: "ignore"&lt;/code&gt; or piped streams beat every shell redirect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;git&lt;/code&gt; commands print errors to stderr and exit codes — you usually don't need to suppress anything&lt;/strong&gt; if you handle the exit code properly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test on the OS your users are on.&lt;/strong&gt; I write "cross-platform" in my README and then test on the one machine in my head. gitpulse users on Windows were getting a fake error for 90 days and I never noticed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What gitpulse Actually Shows
&lt;/h2&gt;

&lt;p&gt;The apology tour is over — here's the tool. Run it in any repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  📊  GITPULSE

  📝  Total commits: 2
  👤  Contributors:  1
  📅  Active days:   1
  📂  Files touched:  2

  👥  Top Contributors
    T                         ███████████████ 2

  📂  File Type Breakdown
    .txt        ███████████████ 2

  🔥  Recent Activity
    2026-08-30  ██████████████████████████████ 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Point it at a big team repo and you get your bus-factor graph, the file-type mix (how much of your history is &lt;code&gt;.ts&lt;/code&gt; vs &lt;code&gt;.md&lt;/code&gt; vs mystery binary files), and a per-day activity strip — all rendered with plain Unicode blocks, no dependencies, no server, nothing leaving your machine.&lt;/p&gt;

&lt;p&gt;It's the "wait, who actually maintains this repo?" answer, without opening a browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/gitpulse            &lt;span class="c"&gt;# current repo&lt;/span&gt;
npx @wuchunjie/gitpulse /path/to/repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  If You're Shipping CLIs
&lt;/h2&gt;

&lt;p&gt;Your users are on Windows. Not "some of your users." The ones who will install it, run it, get a confusing error, and quietly never come back.&lt;/p&gt;

&lt;p&gt;Audit your &lt;code&gt;execSync&lt;/code&gt; strings. If any of them contain &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt;, &lt;code&gt;&amp;gt;/dev/null&lt;/code&gt;, or a bash-ism of any flavor, they are lying to your Windows users right now.&lt;/p&gt;

&lt;p&gt;And if you ever build a tool that looks at your git history the way you'd wish GitHub Insights did — but faster, offline, and in your terminal — gitpulse is live on npm. &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt; and tell me what your repo looks like. I read every comment.&lt;/p&gt;

</description>
      <category>git</category>
      <category>javascript</category>
      <category>node</category>
      <category>debugging</category>
    </item>
    <item>
      <title>3 Months of Shipping Tiny Tools: What Actually Drove Downloads</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 10:00:57 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/3-months-of-shipping-tiny-tools-what-actually-drove-downloads-8pc</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/3-months-of-shipping-tiny-tools-what-actually-drove-downloads-8pc</guid>
      <description>&lt;p&gt;I have spent the last few months shipping a string of small tools: a scaffolding CLI, a secret scanner, a git analytics tool, a snippet manager, and a set of 14 browser utilities. All free, all zero-dependency.&lt;/p&gt;

&lt;p&gt;The interesting question was never "how do I build these?" (each takes an afternoon). The question was: &lt;strong&gt;what actually gets them used?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Honest retrospective, with the parts that worked and the parts that did not.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Drove Downloads
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Dev.to articles with real terminal output
&lt;/h3&gt;

&lt;p&gt;Every article I published included actual command output — not "here is what it might look like", but the real thing, pasted. Those articles consistently outperformed the polished ones.&lt;/p&gt;

&lt;p&gt;Why: developers sniff out marketing from a mile away. A terminal screenshot of the tool actually running reads as evidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The &lt;code&gt;npx&lt;/code&gt;-first design
&lt;/h3&gt;

&lt;p&gt;Zero install, zero config. The friction between "saw an article" and "ran the tool" was one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/dotguard &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every tool that required setup got fewer users than every tool that did not. No contest.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Cross-linking
&lt;/h3&gt;

&lt;p&gt;Each article's footer listed all four CLI tools. A reader of the snippet article met the scaffolder. A reader of the security article met the analytics tool. The funnel is a web, not a line.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The npm page itself
&lt;/h3&gt;

&lt;p&gt;A good one-line description, a README with copy-paste commands, and sensible keywords. npm search is a quiet, persistent channel — people find the tools months after the article traffic is gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Did Not Work
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Generic "top 10 tools" posts
&lt;/h3&gt;

&lt;p&gt;The listicle format gets reads but barely converts when your tool is item #7 in a list of ten famous ones. Specificity beats breadth: "the tool for this exact job" wins.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Trying every platform at once
&lt;/h3&gt;

&lt;p&gt;I tried to spread across several communities and burned out in a week. One platform (Dev.to), one rhythm (a few well-targeted articles), beat scattered presence everywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Announcing "v1.0" like a product launch
&lt;/h3&gt;

&lt;p&gt;Nobody cares about version numbers for a free utility. The tool either solves the moment it appears in the article or it does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pattern That Repeats
&lt;/h2&gt;

&lt;p&gt;Every successful push followed the same shape:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;One concrete pain&lt;/strong&gt; ("your .env is in the repo")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One command that solves it&lt;/strong&gt; (&lt;code&gt;npx @wuchunjie/dotguard .&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Real output as proof&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cross-links to the other tools&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A quiet Ko-fi line&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The tools are small on purpose. The funnel is the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Next
&lt;/h2&gt;

&lt;p&gt;More templates in the scaffolder, more scan patterns in the scanner, and — if the feedback says yes — a small web dashboard that reads the same local JSON files the CLIs write. Same rules: free, local-first, zero bloat.&lt;/p&gt;

&lt;p&gt;If any of these saved you time, the &lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Ko-fi&lt;/a&gt; is how the next one gets built.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Exact Funnel I Use to Get Free CLI Tools Their First Users</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:55:45 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/the-exact-funnel-i-use-to-get-free-cli-tools-their-first-users-4go5</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/the-exact-funnel-i-use-to-get-free-cli-tools-their-first-users-4go5</guid>
      <description>&lt;p&gt;Every open-source tool has the same brutal first 90 days: zero users, zero signal, no idea whether anything works.&lt;/p&gt;

&lt;p&gt;I have shipped several free CLI tools and browser tool sets. This is the exact funnel I use — no ads, no paid growth, no "build in public" theater. Just a repeating sequence of small, concrete actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Make the Tool Trivial to Try
&lt;/h2&gt;

&lt;p&gt;The first rule: &lt;code&gt;npx&lt;/code&gt; must work. If a reader has to install, configure, and read a README before running the first command, the funnel is already broken.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/dotguard &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the entire onboarding. Zero dependencies, no config, instant output. The first 10 seconds decide whether the reader comes back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Publish One Article Per Angle
&lt;/h2&gt;

&lt;p&gt;Not one article. One &lt;strong&gt;per angle&lt;/strong&gt;, spread over time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tutorial&lt;/strong&gt; — "Scan your .env files in 1 command" (the how)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparison&lt;/strong&gt; — "Why I stopped using X" (the why)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Listicle&lt;/strong&gt; — "5 tools for Y" (the discovery)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflow&lt;/strong&gt; — "My dev setup" (the context)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security/devops&lt;/strong&gt; — "Your CI is missing this" (the fear)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each article targets a different search intent. A developer looking for "pre-commit secret scan" lands on article 4, not article 1. The funnel is wide because the angles are wide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Cross-Link Everything
&lt;/h2&gt;

&lt;p&gt;Every article mentions every tool. The footer of a snippet article lists the scaffolder and the scanner. The GitHub repo links to the articles. The npm README links to the articles.&lt;/p&gt;

&lt;p&gt;The effect is compounding: a reader of article 3 meets four tools, not one. Your content becomes a network instead of a pile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Make the GitHub Repo the Hub
&lt;/h2&gt;

&lt;p&gt;The repo README is the landing page that never goes stale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-line description per tool&lt;/li&gt;
&lt;li&gt;Install/run commands (copy-paste ready)&lt;/li&gt;
&lt;li&gt;Links to every article&lt;/li&gt;
&lt;li&gt;A donation link, present but quiet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub is where developers actually trust. Stars and forks are the signal that converts "interesting article" into "let me try it".&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Add the Quiet CTA
&lt;/h2&gt;

&lt;p&gt;One line at the end of every article:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If this saved you time, a &lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Ko-fi&lt;/a&gt; keeps the next tool coming.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No guilt, no popup, no "SUPPORT US!!!". A single, plausible reason to donate. It converts a small percentage of genuinely grateful readers — and that percentage is the whole business model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Works (Honest Version)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Articles with &lt;strong&gt;real output&lt;/strong&gt; beat polished fiction. Paste the terminal output. It reads as true.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specificity wins.&lt;/strong&gt; "5 Lines for a Pre-Commit Hook" outperforms "Improve Your Security".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency beats volume spikes.&lt;/strong&gt; One good article a week for a month outperforms ten in a day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The npm page matters.&lt;/strong&gt; Good description, good keywords, README with screenshots. npm search is a silent acquisition channel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No magic. Just the same five steps, repeated, until the compounding kicks in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>npx Is Your New Install: A Field Guide to Zero-Install CLI Tools</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:50:33 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/npx-is-your-new-install-a-field-guide-to-zero-install-cli-tools-91f</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/npx-is-your-new-install-a-field-guide-to-zero-install-cli-tools-91f</guid>
      <description>&lt;p&gt;There is a habit I stopped a few years ago: installing CLI tools globally.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g&lt;/code&gt; used to be the default for everything — the linter, the formatter, the scaffolder, the "useful one-liner I will probably never run again". My global package list became a museum of abandoned tools, and every Node upgrade was a roll of the dice.&lt;/p&gt;

&lt;p&gt;The replacement is one command: &lt;code&gt;npx&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What npx Actually Does
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npx &amp;lt;package&amp;gt;&lt;/code&gt; fetches the package, runs its binary, and leaves nothing behind. No global install, no version pinned in your &lt;code&gt;package.json&lt;/code&gt;, no cleanup. The tool exists for the duration of the command.&lt;/p&gt;

&lt;p&gt;For one-off and occasional tools, that is exactly the right lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Zero-Install Pattern, Applied
&lt;/h2&gt;

&lt;p&gt;Here are four tools I run this way daily — none of them are installed anywhere:&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaffold projects
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx scaffoldx-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interactive list of nine templates (React, Next.js, Express, FastAPI, Chrome extension, CLI, landing page, Discord bot, Electron). Pick, name, done — &lt;code&gt;git init&lt;/code&gt; included.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manage snippets
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pbpaste | npx @wuchunjie/snippetx add my-snippet js
npx @wuchunjie/snippetx search my
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything lives in &lt;code&gt;~/.snippetx/snippets.json&lt;/code&gt;. The tool is ephemeral; the data is yours.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scan for leaked secrets
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/dotguard &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Walks the directory, flags exposed keys and passwords in &lt;code&gt;.env&lt;/code&gt; files, exits non-zero on findings (so it is a one-line CI gate).&lt;/p&gt;

&lt;h3&gt;
  
  
  Read a repo's pulse
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/gitpulse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commits, contributors, file breakdown, activity — one screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use npx vs. Install
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Run once or twice a year&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool with heavy dependencies, run occasionally&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Core daily driver (your editor, your test runner)&lt;/td&gt;
&lt;td&gt;Install it properly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team needs a pinned version&lt;/td&gt;
&lt;td&gt;Pin in &lt;code&gt;devDependencies&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You are not sure you will keep using it&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;npx&lt;/code&gt; — try before you commit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The rule of thumb: &lt;strong&gt;default to &lt;code&gt;npx&lt;/code&gt;, install only when the tool earns a permanent slot.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters More Than It Looks
&lt;/h2&gt;

&lt;p&gt;A zero-install toolchain cannot rot. There is nothing to update, nothing to break on a Node upgrade, nothing to audit. The tools are as old as the last time you ran them — and as disposable.&lt;/p&gt;

&lt;p&gt;My global &lt;code&gt;npm ls -g&lt;/code&gt; output is now short enough to read. That is the real feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/scaffoldx-cli" rel="noopener noreferrer"&gt;npm: scaffoldx-cli&lt;/a&gt;&lt;/strong&gt; · &lt;a href="https://www.npmjs.com/package/@wuchunjie/snippetx" rel="noopener noreferrer"&gt;&lt;strong&gt;@wuchunjie/snippetx&lt;/strong&gt;&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@wuchunjie/dotguard" rel="noopener noreferrer"&gt;&lt;strong&gt;@wuchunjie/dotguard&lt;/strong&gt;&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@wuchunjie/gitpulse" rel="noopener noreferrer"&gt;&lt;strong&gt;@wuchunjie/gitpulse&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>node</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Found a Secret in Git History? A Calm 3-Step Recovery Plan</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:45:22 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/found-a-secret-in-git-history-a-calm-3-step-recovery-plan-22jo</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/found-a-secret-in-git-history-a-calm-3-step-recovery-plan-22jo</guid>
      <description>&lt;p&gt;You just found it. That &lt;code&gt;API_KEY=...&lt;/code&gt; has been in your repo's history for six months. Your heart rate goes up. Good — now do these three things in order, because the order is the whole game.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Rotate the Secret First (Not Second, Not Later)
&lt;/h2&gt;

&lt;p&gt;This is the step everyone skips, and skipping it makes everything else decorative.&lt;/p&gt;

&lt;p&gt;A leaked secret is compromised the moment it is readable. Deleting it from the repo does not un-read it. Bots index public repos. Someone may have already cloned it.&lt;/p&gt;

&lt;p&gt;Go to the provider's dashboard and &lt;strong&gt;rotate now&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API key → new key, old key revoked&lt;/li&gt;
&lt;li&gt;Database password → new password, old one gone&lt;/li&gt;
&lt;li&gt;JWT secret → new value (yes, your sessions die; that is cheaper than a breach)&lt;/li&gt;
&lt;li&gt;Webhook token → regenerate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do this before touching git at all. The clock starts at leak, not at cleanup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Scan for What Else Is Exposed
&lt;/h2&gt;

&lt;p&gt;You found one. Assume there are more. Run a scan across the whole project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/dotguard &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;  🔍  Scanning: /home/dev/my-app

  📄  .env (2 issues)
    ⚠️  L  3 | API key
    ⚠️  L  7 | Database URL
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@wuchunjie/dotguard" rel="noopener noreferrer"&gt;DotGuard&lt;/a&gt; walks every &lt;code&gt;.env&lt;/code&gt; file and flags passwords, keys, tokens, private keys, and database URLs — with line numbers. Zero dependencies, one command.&lt;/p&gt;

&lt;p&gt;Rotate everything it finds, not just the one that got you caught.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Clean the History
&lt;/h2&gt;

&lt;p&gt;The secret is in history, so history is the leak. Your options, in order of how much you care about the history:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option A: Small repo, no precious history&lt;/strong&gt; — delete and re-clone.&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="c"&gt;# from a clean checkout without the bad commits&lt;/span&gt;
git init
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"fresh start"&lt;/span&gt;
git push &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nuclear, but honest. For side projects this is the fastest correct answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option B: Shared repo, history matters&lt;/strong&gt; — rewrite with &lt;code&gt;git filter-repo&lt;/code&gt;, remove the file, force-push, and make &lt;strong&gt;every clone&lt;/strong&gt; re-clone (a filtered repo's history is unrecoverable from stale clones — the old secret lives on in every machine that ever cloned it).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option C: The secret was short-lived&lt;/strong&gt; — if it was rotated within minutes of the push, document the incident and move on. Risk is time-exposed × value-of-secret.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aftermath: Make It Not Happen Again
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.env&lt;/code&gt; in &lt;code&gt;.gitignore&lt;/code&gt;, &lt;code&gt;.env.example&lt;/code&gt; committed with empty values&lt;/li&gt;
&lt;li&gt;A pre-commit hook that runs the scanner (its non-zero exit blocks the commit)&lt;/li&gt;
&lt;li&gt;The same scan as a CI step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three gates, all free, all one-liners. The incident you are cleaning up right now is the cheapest lesson it will ever cost you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/@wuchunjie/dotguard" rel="noopener noreferrer"&gt;npm: @wuchunjie/dotguard&lt;/a&gt;&lt;/strong&gt; | &lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>security</category>
      <category>git</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Your CI Pipeline Is Missing This One-Step Secret Scan</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:40:10 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/your-ci-pipeline-is-missing-this-one-step-secret-scan-14n6</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/your-ci-pipeline-is-missing-this-one-step-secret-scan-14n6</guid>
      <description>&lt;p&gt;Your CI pipeline probably runs tests, builds, and lints. It does not check whether a secret just got committed.&lt;/p&gt;

&lt;p&gt;That gap is one line.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem in One Sentence
&lt;/h2&gt;

&lt;p&gt;Secrets do not get committed on purpose. They get committed in a hurry, in a "quick fix" branch, by an intern, by you at 6pm on a Friday — and CI, which saw every other line of the diff, saw the &lt;code&gt;API_KEY=sk_live_...&lt;/code&gt; and said "build passed".&lt;/p&gt;

&lt;h2&gt;
  
  
  The One-Line Gate
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@wuchunjie/dotguard" rel="noopener noreferrer"&gt;DotGuard&lt;/a&gt; is a zero-dependency scanner for &lt;code&gt;.env&lt;/code&gt; files. It walks a directory, finds every &lt;code&gt;.env&lt;/code&gt;, and flags hardcoded passwords, API keys, access tokens, private keys, and database URLs.&lt;/p&gt;

&lt;p&gt;The critical behavior for CI: &lt;strong&gt;it exits with code 1 when it finds potential secrets.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add it to your pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/ci.yml&lt;/span&gt;
&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Scan for exposed secrets&lt;/span&gt;
    &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx -y @wuchunjie/dotguard .&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Tests&lt;/span&gt;
    &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the whole change. No service to sign up for, no API key for the scanner (ironic, I know), no SaaS bill. One &lt;code&gt;npx&lt;/code&gt;, zero dependencies, runs in seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Catches
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Finding&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hardcoded password&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PASSWORD=hunter2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;API_KEY=sk_live_...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access token&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TOKEN=ghp_...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Private key block&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BEGIN OPENSSH PRIVATE KEY&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DATABASE_URL=postgres://user:pw@host/db&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long secret string&lt;/td&gt;
&lt;td&gt;any 20+ char quoted blob&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It also notes missing basics like &lt;code&gt;NODE_ENV&lt;/code&gt; — the kind of gap that turns into a 2am "why did it deploy to the wrong env" ticket.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Right Order of Defense
&lt;/h2&gt;

&lt;p&gt;CI scanning is the &lt;strong&gt;second&lt;/strong&gt; gate, not the first:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pre-commit hook&lt;/strong&gt; (catches it before it is committed) — DotGuard's exit code makes this a 5-line hook&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI step&lt;/strong&gt; (catches what the hook missed, or what came from a force-push)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rotation runbook&lt;/strong&gt; (when one already escaped: rotate first, then clean history)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A repo with all three has essentially no realistic path for a &lt;code&gt;.env&lt;/code&gt; to reach production via git. The first two are free; the third is just discipline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not the SaaS Scanner
&lt;/h2&gt;

&lt;p&gt;The big secret-scanning platforms are fine for enterprise, and they cost money per seat. For the 95% case — "does my repo have a leaked &lt;code&gt;.env&lt;/code&gt;?" — a local, zero-dependency scanner with an exit code is the entire job.&lt;/p&gt;

&lt;p&gt;Ship the one line. Your pipeline stops being a secret leak detector that never detects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/@wuchunjie/dotguard" rel="noopener noreferrer"&gt;npm: @wuchunjie/dotguard&lt;/a&gt;&lt;/strong&gt; | &lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>security</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Terminal-First Development: Why I Closed 30 Browser Tabs and Kept 4 Commands</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:34:58 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/terminal-first-development-why-i-closed-30-browser-tabs-and-kept-4-commands-2m8j</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/terminal-first-development-why-i-closed-30-browser-tabs-and-kept-4-commands-2m8j</guid>
      <description>&lt;p&gt;I used to develop with 30 tabs open. GitHub, docs, Stack Overflow, a snippet service, a JSON formatter, a Base64 encoder, three different "tool" sites, and somewhere in there — the code.&lt;/p&gt;

&lt;p&gt;Last month I ran an experiment: close all of it, and do the same work from the terminal. Four &lt;code&gt;npx&lt;/code&gt; commands later, I had everything those tabs did.&lt;/p&gt;

&lt;p&gt;This is the argument for terminal-first, with receipts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tab 1: "New project setup" → &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The tab was 14 open "how do I set up X" articles and a 2019 starter repo.&lt;/p&gt;

&lt;p&gt;The command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx scaffoldx-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nine templates, one pick, one project name. The folder exists with working configs and &lt;code&gt;git init&lt;/code&gt; already run. The 14 tabs are now a number on a menu.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tab 2: "That snippet I saved" → &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The tab was the "code stuff" bookmark folder — 40 entries, zero search by content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/snippetx search debounce
npx @wuchunjie/snippetx copy f3a1b2c4 | pbcopy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Snippets live in &lt;code&gt;~/.snippetx/snippets.json&lt;/code&gt;. Search matches content, not just titles. The bookmark folder is deleted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tab 3: "Repo overview" → &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The tab was the GitHub web UI: commits page, contributors page, graphs page. Three clicks, three loads, three tabs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/gitpulse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commits, contributors with bar charts, file-type breakdown, activity heatmap — one screen, one command, no navigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tab 4: "Is this .env safe?" → &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The tab was a "secret scanner" website — which is itself a security problem, because scanning means pasting your secrets into someone else's server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/dotguard &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Local scan, local results, non-zero exit code for CI. Your secrets never leave the machine. That is not a small point.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Terminal Won
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed.&lt;/strong&gt; Four commands versus 30 tabs of clicking. The browser was never fast; it was just familiar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy.&lt;/strong&gt; Nothing sensitive gets pasted into a third-party site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composability.&lt;/strong&gt; &lt;code&gt;pbpaste | snippetx add&lt;/code&gt;, &lt;code&gt;dotguard . &amp;amp;&amp;amp; git commit&lt;/code&gt; — the terminal chains, tabs do not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stability.&lt;/strong&gt; A zero-dependency CLI does not get a redesign, a paywall, or a sunset. A website gets all three.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Kept Open
&lt;/h2&gt;

&lt;p&gt;To be honest: docs sites, when I need them, and the browser for things that are genuinely visual. "Terminal-first" is not "browser-hating". It is: the browser is a destination, not a workspace.&lt;/p&gt;

&lt;p&gt;The workspace is where the code is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/scaffoldx-cli" rel="noopener noreferrer"&gt;npm: scaffoldx-cli&lt;/a&gt;&lt;/strong&gt; · &lt;a href="https://www.npmjs.com/package/@wuchunjie/snippetx" rel="noopener noreferrer"&gt;&lt;strong&gt;@wuchunjie/snippetx&lt;/strong&gt;&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@wuchunjie/gitpulse" rel="noopener noreferrer"&gt;&lt;strong&gt;@wuchunjie/gitpulse&lt;/strong&gt;&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@wuchunjie/dotguard" rel="noopener noreferrer"&gt;&lt;strong&gt;@wuchunjie/dotguard&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>javascript</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A 2026 Starter Toolkit for New Developers: 5 Free Tools, Zero Dollars</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:29:46 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/a-2026-starter-toolkit-for-new-developers-5-free-tools-zero-dollars-1dem</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/a-2026-starter-toolkit-for-new-developers-5-free-tools-zero-dollars-1dem</guid>
      <description>&lt;p&gt;If you are starting to build things in 2026 — or you have been building for years but your toolchain is a pile of half-remembered Gists — here is the entire toolkit I would hand you.&lt;/p&gt;

&lt;p&gt;Five tools. All free. All zero-install. Total cost: $0.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. ScaffoldX — for starting any project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx scaffoldx-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stop googling "how to set up React in 2026". Pick a template (React, Next.js, Express, FastAPI, Chrome extension, CLI tool, landing page, Discord bot, Electron), name your project, and get a clean folder with working configs — &lt;code&gt;git init&lt;/code&gt; included.&lt;/p&gt;

&lt;p&gt;This is the tool that replaces the first hour of every project.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. SnippetX — for never losing code again
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pbpaste | npx @wuchunjie/snippetx add my-snippet js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A snippet manager that lives in your terminal. Save with a pipe, find with &lt;code&gt;search&lt;/code&gt;, use with &lt;code&gt;copy&lt;/code&gt;. Your snippets are a single local JSON file — no account, no service that can sunset.&lt;/p&gt;

&lt;p&gt;New developers lose snippets constantly because they have nowhere to put them. This is that somewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. DotGuard — for not leaking your first secret
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/dotguard &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your first &lt;code&gt;.env&lt;/code&gt; file is also your first leaked secret, statistically. DotGuard scans a project for exposed keys, passwords, and database URLs before it is a problem. One command, no config.&lt;/p&gt;

&lt;p&gt;Learn this one early: scanning your repo is a habit, not a one-time thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. GitPulse — for understanding any repo in 10 seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/gitpulse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Opening someone else's repo (or your own, three months later)? One command gives you commit counts, contributor breakdown, file-type mix, and recent activity. You stop guessing what a repo is about from its README alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. 14 Browser Tools — for everything in between
&lt;/h2&gt;

&lt;p&gt;Base64, JSON/CSV conversion, JWT decoding, hashing, QR codes, UUIDs, password generation, diff checking, and more — 14 static pages that run in your browser with no install, no account, no tracking:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wuchunjie00.github.io/devtools" rel="noopener noreferrer"&gt;wuchunjie00.github.io/devtools&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Common Thread
&lt;/h2&gt;

&lt;p&gt;Every tool here follows the same rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero dependencies&lt;/strong&gt; — nothing to break, nothing to update&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;npx&lt;/code&gt; or a URL&lt;/strong&gt; — no install step, no global pollution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local data&lt;/strong&gt; — your code and secrets stay on your machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free, forever&lt;/strong&gt; — and if you use them, a &lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Ko-fi&lt;/a&gt; buys the next tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bookmark this list. You will need it the first time a new project starts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My Entire Dev Workflow Runs on 4 Tiny npm Packages</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:24:34 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/my-entire-dev-workflow-runs-on-4-tiny-npm-packages-c19</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/my-entire-dev-workflow-runs-on-4-tiny-npm-packages-c19</guid>
      <description>&lt;p&gt;I keep my toolchain deliberately small. No IDE extension suite, no "developer environment" with 40 moving parts. Just four zero-dependency npm packages, run with &lt;code&gt;npx&lt;/code&gt;, covering the four moments where my old workflow leaked time.&lt;/p&gt;

&lt;p&gt;Here is the map.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Starting a project → ScaffoldX
&lt;/h2&gt;

&lt;p&gt;The moment: "new folder, sensible defaults, go."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx scaffoldx-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nine templates (React, Next.js, Express, FastAPI, Chrome extension, CLI, landing page, Discord bot, Electron), one interactive pick, project generated with &lt;code&gt;git init&lt;/code&gt; already done.&lt;/p&gt;

&lt;p&gt;What it killed: the 30-minute "copy an old project and delete half of it" ritual.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Saving code snippets → SnippetX
&lt;/h2&gt;

&lt;p&gt;The moment: "I found the one-liner I needed, now where does it go?"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pbpaste | npx @wuchunjie/snippetx add debounce js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything lives in &lt;code&gt;~/.snippetx/snippets.json&lt;/code&gt;. Search by name or content, copy back to clipboard or append to a file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/snippetx search debounce
npx @wuchunjie/snippetx copy f3a1b2c4 | pbcopy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What it killed: the 40-tab "code stuff" bookmark folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Checking a repo's health → GitPulse
&lt;/h2&gt;

&lt;p&gt;The moment: "what is actually going on in this repo before I touch it?"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/gitpulse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Total commits, contributors with bar charts, file-type breakdown, recent activity heatmap — in the terminal, in one command.&lt;/p&gt;

&lt;p&gt;What it killed: opening the GitHub web UI, clicking through three pages, mentally reconstructing the same data.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Shipping with a clean conscience → DotGuard
&lt;/h2&gt;

&lt;p&gt;The moment: "one last check before this goes public."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @wuchunjie/dotguard &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Walks the directory, finds every &lt;code&gt;.env&lt;/code&gt; file, flags hardcoded passwords, API keys, tokens, private keys, and database URLs. Exits non-zero on findings, so it is a one-line CI gate too.&lt;/p&gt;

&lt;p&gt;What it killed: the "I probably did not commit the .env" hope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Four, and Why These
&lt;/h2&gt;

&lt;p&gt;Each package covers exactly one recurring pain, has zero dependencies, runs via &lt;code&gt;npx&lt;/code&gt; (no install, no version drift in my global packages), and prints results I can read in 5 seconds.&lt;/p&gt;

&lt;p&gt;The total maintenance cost of the whole workflow: zero. The total install cost: zero. That is the point of keeping it small — when every tool is one &lt;code&gt;npx&lt;/code&gt; away, the workflow cannot rot.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Full List
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scaffoldx-cli&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx scaffoldx-cli&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate project templates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@wuchunjie/snippetx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Terminal snippet manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@wuchunjie/gitpulse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Git repo analytics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@wuchunjie/dotguard&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;.env secret scanning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All free, all MIT, all zero-dependency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/scaffoldx-cli" rel="noopener noreferrer"&gt;npm: scaffoldx-cli&lt;/a&gt;&lt;/strong&gt; · &lt;a href="https://www.npmjs.com/package/@wuchunjie/dotguard" rel="noopener noreferrer"&gt;&lt;strong&gt;@wuchunjie/dotguard&lt;/strong&gt;&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@wuchunjie/gitpulse" rel="noopener noreferrer"&gt;&lt;strong&gt;@wuchunjie/gitpulse&lt;/strong&gt;&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/@wuchunjie/snippetx" rel="noopener noreferrer"&gt;&lt;strong&gt;@wuchunjie/snippetx&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>javascript</category>
      <category>node</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The 5 Browser Tools I Use Every Single Day (All Free, No Install)</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:19:17 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/the-5-browser-tools-i-use-every-single-day-all-free-no-install-1740</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/the-5-browser-tools-i-use-every-single-day-all-free-no-install-1740</guid>
      <description>&lt;p&gt;Fifteen browser tools live in my bookmark bar. Five of them get opened daily. Here they are, and why each one earned a permanent spot.&lt;/p&gt;

&lt;p&gt;All five are from the same free, no-install, no-tracking set: &lt;a href="https://wuchunjie00.github.io/devtools" rel="noopener noreferrer"&gt;wuchunjie00.github.io/devtools&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Base64 Tool — &lt;a href="https://wuchunjie00.github.io/devtools/base64-tool/" rel="noopener noreferrer"&gt;open it&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Daily use: decoding the base64 blobs that show up in logs, headers, and "just paste this" support tickets.&lt;/p&gt;

&lt;p&gt;Why it stays: paste → encode → decode → copy. No file upload, no "pro plan" wall. The data never leaves the tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. JWT Decoder — &lt;a href="https://wuchunjie00.github.io/devtools/jwt-decoder/" rel="noopener noreferrer"&gt;open it&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Daily use: reading a token's payload during debugging — &lt;code&gt;exp&lt;/code&gt;, &lt;code&gt;sub&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt;, whatever is in the claims.&lt;/p&gt;

&lt;p&gt;Why it stays: local decode means I am not pasting a bearer credential into some third-party site. That one decision is why I use this over the paid "API toolkits".&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Hash Generator — &lt;a href="https://wuchunjie00.github.io/devtools/hash-generator/" rel="noopener noreferrer"&gt;open it&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Daily use: quick MD5/SHA-256 checks — file integrity, verifying a value a doc claims, comparing checksums.&lt;/p&gt;

&lt;p&gt;Why it stays: it is three seconds from "I wonder what this hashes to" to the answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. CSV to JSON — &lt;a href="https://wuchunjie00.github.io/devtools/csv-to-json/" rel="noopener noreferrer"&gt;open it&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Daily use: converting the CSV exports that every SaaS loves to send me into something my scripts can read.&lt;/p&gt;

&lt;p&gt;Why it stays: paste in, copy out, paste into the script. No account, no 10-row free limit, no "upgrade to export".&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Diff Checker — &lt;a href="https://wuchunjie00.github.io/devtools/diff-checker/" rel="noopener noreferrer"&gt;open it&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Daily use: "are these two config blocks actually different?" — env files, API responses, copy-pasted configs.&lt;/p&gt;

&lt;p&gt;Why it stays: side-by-side diff with the differences highlighted. It answers the question in 10 seconds that used to take 10 minutes of squinting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pattern
&lt;/h2&gt;

&lt;p&gt;Notice what none of these do: no login, no upload, no tracking, no trial. They are static pages of HTML/CSS/JS that run in your tab. That is the whole feature set, and it is why I trust them with data I would not paste anywhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rest of the Set
&lt;/h2&gt;

&lt;p&gt;The other nine — cron parser, YAML to JSON, HTML entities, HTML to text, lorem ipsum, password generator, QR code, slug generator, UUID generator — cover the weekly and monthly tasks. Same rules: free, local, no account.&lt;/p&gt;

&lt;p&gt;Bookmark the index: &lt;a href="https://wuchunjie00.github.io/devtools" rel="noopener noreferrer"&gt;wuchunjie00.github.io/devtools&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>6 Web Tools You Are Paying For That I Run for Free in My Browser</title>
      <dc:creator>ke jia</dc:creator>
      <pubDate>Sat, 22 Aug 2026 09:14:03 +0000</pubDate>
      <link>https://dev.to/ke_jia_24bb2f9f84f14f728a/6-web-tools-you-are-paying-for-that-i-run-for-free-in-my-browser-28am</link>
      <guid>https://dev.to/ke_jia_24bb2f9f84f14f728a/6-web-tools-you-are-paying-for-that-i-run-for-free-in-my-browser-28am</guid>
      <description>&lt;p&gt;I went through my subscriptions last month and found six tools I was paying for that do exactly one thing: transform text. Base64 encode. JSON to CSV. Generate a UUID.&lt;/p&gt;

&lt;p&gt;Each has a $5–10/month tag. Together they cost more than my domain registration.&lt;/p&gt;

&lt;p&gt;Then I built the free version. Here is the comparison, tool by tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Base64 Encoder/Decoder
&lt;/h2&gt;

&lt;p&gt;Paid tools: $5/mo, "unlimited encodes", ads.&lt;br&gt;
Free version: &lt;a href="https://wuchunjie00.github.io/devtools/base64-tool/" rel="noopener noreferrer"&gt;wuchunjie00.github.io/devtools/base64-tool&lt;/a&gt; — paste, encode, decode, done.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. JSON ⇄ CSV Converter
&lt;/h2&gt;

&lt;p&gt;Paid tools: $8/mo, export limits, "team plan" upsell.&lt;br&gt;
Free version: &lt;a href="https://wuchunjie00.github.io/devtools/csv-to-json/" rel="noopener noreferrer"&gt;csv-to-json&lt;/a&gt; and &lt;a href="https://wuchunjie00.github.io/devtools/yaml-to-json/" rel="noopener noreferrer"&gt;yaml-to-json&lt;/a&gt; — paste in, copy out. Nothing leaves your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Hash Generator
&lt;/h2&gt;

&lt;p&gt;Paid tools: MD5/SHA "forensic tools" at $12/mo.&lt;br&gt;
Free version: &lt;a href="https://wuchunjie00.github.io/devtools/hash-generator/" rel="noopener noreferrer"&gt;hash-generator&lt;/a&gt; — MD5, SHA-1, SHA-256, SHA-512 in your browser, no upload.&lt;/p&gt;

&lt;p&gt;This is the one that matters: the paid tools upload your data to their server. The browser version computes locally. For anything sensitive, that is not a feature difference, it is the difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. JWT Decoder
&lt;/h2&gt;

&lt;p&gt;Paid tools: $6/mo "API security toolkit".&lt;br&gt;
Free version: &lt;a href="https://wuchunjie00.github.io/devtools/jwt-decoder/" rel="noopener noreferrer"&gt;jwt-decoder&lt;/a&gt; — paste the token, read the payload. (Reminder: tokens are bearer credentials; decoding in a local tool is fine, pasting them into random sites is how they leak.)&lt;/p&gt;

&lt;h2&gt;
  
  
  5. QR Code Generator
&lt;/h2&gt;

&lt;p&gt;Paid tools: $4/mo, "commercial license", watermark removal.&lt;br&gt;
Free version: &lt;a href="https://wuchunjie00.github.io/devtools/qr-code-generator/" rel="noopener noreferrer"&gt;qr-code-generator&lt;/a&gt; — generate, download, no watermark, no license fee.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Password / UUID / Slug Generators
&lt;/h2&gt;

&lt;p&gt;The "utility suites" at $7/mo.&lt;br&gt;
Free versions: &lt;a href="https://wuchunjie00.github.io/devtools/password-generator/" rel="noopener noreferrer"&gt;password-generator&lt;/a&gt;, &lt;a href="https://wuchunjie00.github.io/devtools/uuid-generator/" rel="noopener noreferrer"&gt;uuid-generator&lt;/a&gt;, &lt;a href="https://wuchunjie00.github.io/devtools/slug-generator/" rel="noopener noreferrer"&gt;slug-generator&lt;/a&gt;, &lt;a href="https://wuchunjie00.github.io/devtools/lorem-ipsum/" rel="noopener noreferrer"&gt;lorem-ipsum&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Full Set
&lt;/h2&gt;

&lt;p&gt;That is 14 tools in total, all at &lt;a href="https://wuchunjie00.github.io/devtools" rel="noopener noreferrer"&gt;wuchunjie00.github.io/devtools&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Base64 · CSV to JSON · YAML to JSON · Cron parser · Diff checker · Hash generator · HTML entities · HTML to text · JWT decoder · Lorem ipsum · Password generator · QR code · Slug generator · UUID generator&lt;/p&gt;

&lt;h2&gt;
  
  
  Why They Are Free (Forever)
&lt;/h2&gt;

&lt;p&gt;They run 100% in your browser. No backend, no server costs, no data collection — which is also why there is no business model to "sustain". The cost of running them is zero, so the price is zero. If you use them, a &lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Ko-fi&lt;/a&gt; keeps the next batch coming.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Math
&lt;/h2&gt;

&lt;p&gt;Six subscriptions, ~$40–50/month. Fourteen browser tabs, $0/month.&lt;/p&gt;

&lt;p&gt;Your call which side of that line you are on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  From the same toolbox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ScaffoldX&lt;/strong&gt; — generate production-ready project templates in seconds: &lt;code&gt;npx scaffoldx-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DotGuard&lt;/strong&gt; — scan &lt;code&gt;.env&lt;/code&gt; files for exposed secrets: &lt;code&gt;npx @wuchunjie/dotguard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitPulse&lt;/strong&gt; — git analytics (commits, contributors, activity) in your terminal: &lt;code&gt;npx @wuchunjie/gitpulse&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SnippetX&lt;/strong&gt; — save, search, and copy code snippets from the terminal: &lt;code&gt;npx @wuchunjie/snippetx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/wuchunjie00/devtools" rel="noopener noreferrer"&gt;GitHub: wuchunjie00/devtools&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☕ If This Saved You Time
&lt;/h2&gt;

&lt;p&gt;All of these tools are and will always be &lt;strong&gt;100% free&lt;/strong&gt;. If they make your day a little easier, consider fueling the next one:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ko-fi.com/wuchunjie" rel="noopener noreferrer"&gt;Buy me a coffee on Ko-fi&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️. Zero dependencies, zero tracking, zero bloat.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
