<?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: Ajiez</title>
    <description>The latest articles on DEV Community by Ajiez (@ajiezai).</description>
    <link>https://dev.to/ajiezai</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%2F4122318%2F2df73a98-606b-4531-8a1a-211894509e0a.png</url>
      <title>DEV Community: Ajiez</title>
      <link>https://dev.to/ajiezai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ajiezai"/>
    <language>en</language>
    <item>
      <title>Stop Guessing at Auth Bugs: Decode the JWT First</title>
      <dc:creator>Ajiez</dc:creator>
      <pubDate>Tue, 29 Sep 2026 14:03:28 +0000</pubDate>
      <link>https://dev.to/ajiezai/stop-guessing-at-auth-bugs-decode-the-jwt-first-30hn</link>
      <guid>https://dev.to/ajiezai/stop-guessing-at-auth-bugs-decode-the-jwt-first-30hn</guid>
      <description>&lt;p&gt;Half the "works in Postman, fails in production" bugs I've debugged were readable in the token itself. Expired &lt;code&gt;exp&lt;/code&gt;. Audience minted for a different client. A token from the wrong environment variable. The payload was sitting right there, base64url-encoded, one paste away — and instead of reading it, we were reading stack traces.&lt;/p&gt;

&lt;p&gt;So here is the habit I've settled on: &lt;strong&gt;decode first, theorize second.&lt;/strong&gt; It turns most auth mysteries into five-minute fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30-second version
&lt;/h2&gt;

&lt;p&gt;A JWT is three base64url segments joined by two dots: header, payload, signature. The first two are not encrypted — they are encoded, which means they are readable by anyone who holds the token. That is by design. The signature is the only part that proves authenticity; the payload merely claims.&lt;/p&gt;

&lt;p&gt;The fastest decode is a browser tool, because it keeps the token on your machine (a debug token with a live &lt;code&gt;access_token&lt;/code&gt; in it has no business being pasted into a random web form). I built a &lt;a href="https://ajiez.top/jwt-decoder/" rel="noopener noreferrer"&gt;JWT decoder&lt;/a&gt; that runs entirely client-side: paste, read the header and payload as formatted JSON, see the expiry status at a glance. Thirty seconds, zero network.&lt;/p&gt;

&lt;p&gt;Once you can read tokens fluently, five claims decide most real-world outcomes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Claim&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;What catches people&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;exp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Expiry, Unix seconds&lt;/td&gt;
&lt;td&gt;The token was dead the whole time; clocks and "it worked yesterday" lie&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;iss&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Who issued it&lt;/td&gt;
&lt;td&gt;Expected Auth0, got &lt;code&gt;https://accounts.google.com&lt;/code&gt; — wrong env var&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;aud&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Who it's for&lt;/td&gt;
&lt;td&gt;Minted for a different client_id than the one sending it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scope&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What it may do&lt;/td&gt;
&lt;td&gt;The integration promised &lt;code&gt;read:orders&lt;/code&gt;, the token says otherwise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sub&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Who it is&lt;/td&gt;
&lt;td&gt;A user id where you expected a service account, or vice versa&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you want the full walkthrough — the field-by-field reasoning, the failure modes, the "only part of the token got copied" classics — I wrote a longer guide on &lt;a href="https://ajiez.top/guides/how-to-decode-a-jwt-token/" rel="noopener noreferrer"&gt;how to decode a JWT token&lt;/a&gt;, and it is the reference I'll paraphrase below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access token vs ID token: same dots, different jobs
&lt;/h2&gt;

&lt;p&gt;Here's the triage that took me embarrassingly long to internalize. People paste two very different tokens into a decoder and expect similar answers.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;access token&lt;/strong&gt; is the thing you send as &lt;code&gt;Authorization: Bearer ...&lt;/code&gt;. It &lt;em&gt;may&lt;/em&gt; be a JWT or an opaque string. If it decodes into three parts, its &lt;code&gt;exp&lt;/code&gt;, &lt;code&gt;scope&lt;/code&gt; and &lt;code&gt;aud&lt;/code&gt; tell you what it can do and until when.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;ID token&lt;/strong&gt; comes from an OIDC login flow. It is always a JWT, but it describes &lt;em&gt;the user&lt;/em&gt; — &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;sub&lt;/code&gt; — not permissions.&lt;/p&gt;

&lt;p&gt;Three-second triage table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Payload contains&lt;/th&gt;
&lt;th&gt;You're holding&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;exp&lt;/code&gt;, &lt;code&gt;scope&lt;/code&gt;, short &lt;code&gt;sub&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;access token&lt;/td&gt;
&lt;td&gt;Is &lt;code&gt;exp&lt;/code&gt; past? Is &lt;code&gt;scope&lt;/code&gt; what the integration promised?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;email&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;aud&lt;/code&gt; = your client_id&lt;/td&gt;
&lt;td&gt;ID token&lt;/td&gt;
&lt;td&gt;Does &lt;code&gt;aud&lt;/code&gt; match your client? The &lt;code&gt;nonce&lt;/code&gt; you sent?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No dots, random string&lt;/td&gt;
&lt;td&gt;opaque token&lt;/td&gt;
&lt;td&gt;Nothing to decode — resolve it at the issuer's introspection endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The classic bug this catches: sending the ID token to your API because it was the token lying around after login, then wondering why the API rejects it. The API wanted the access token. The payload told you which one you had the entire time — that &lt;a href="https://ajiez.top/guides/how-to-decode-a-jwt-token/" rel="noopener noreferrer"&gt;access token vs ID token comparison&lt;/a&gt; is worth bookmarking the next time an integration "randomly" 401s.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the libraries actually do (four languages, one pattern)
&lt;/h2&gt;

&lt;p&gt;Every serious JWT library separates &lt;strong&gt;decoding&lt;/strong&gt; from &lt;strong&gt;verification&lt;/strong&gt;. Knowing the exact shape of that separation in your language saves an afternoon:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node (&lt;code&gt;jsonwebtoken&lt;/code&gt;)&lt;/strong&gt; — &lt;code&gt;jwt.decode(token)&lt;/code&gt; decodes without verifying: the direct equivalent of pasting into a browser tool. &lt;code&gt;jwt.verify(token, secretOrPublicKey)&lt;/code&gt; checks the signature and &lt;em&gt;throws&lt;/em&gt; on failure, with the reason named in the error (&lt;code&gt;TokenExpiredError&lt;/code&gt;, &lt;code&gt;JsonWebTokenError&lt;/code&gt;). Decode to inspect, verify to trust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python (&lt;code&gt;PyJWT&lt;/code&gt;)&lt;/strong&gt; — inspection is &lt;code&gt;jwt.decode(token, options={"verify_signature": False})&lt;/code&gt;. Verification demands the algorithm explicitly: &lt;code&gt;algorithms=["RS256"]&lt;/code&gt;. That friction is deliberate — it exists to prevent the &lt;code&gt;alg: none&lt;/code&gt; downgrade class of bugs, where a crafted token declares no signature and a lazy verifier obligingly skips the check.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go (&lt;code&gt;golang-jwt&lt;/code&gt;)&lt;/strong&gt; — parsing and validation are separate calls. The interesting part for multi-tenant systems: key lookup happens by the token's &lt;code&gt;kid&lt;/code&gt; header, so the practical pattern is decode-first (read &lt;code&gt;kid&lt;/code&gt;, route to the right tenant's key), then validate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Java (&lt;code&gt;jjwt&lt;/code&gt;)&lt;/strong&gt; — &lt;code&gt;parseClaimsJwt()&lt;/code&gt; handles unsigned parsing; anything signature-checked wants the key at parse time.&lt;/p&gt;

&lt;p&gt;Four ecosystems, one philosophy: verification is the loud, default path; decoding is the quiet, explicit one. When you find yourself fighting the library to "just decode the thing," that's not friction to work around — it's the library telling you which operation deserves suspicion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decoding is not verifying
&lt;/h2&gt;

&lt;p&gt;The one sentence that belongs in every code review: &lt;strong&gt;a decoded payload is a claim, not a fact.&lt;/strong&gt; Anyone can mint a token that says &lt;code&gt;{"role":"admin"}&lt;/code&gt;. The signature is the only part that proves who issued it and that nothing changed in transit.&lt;/p&gt;

&lt;p&gt;And the red flag to say out loud: if a token's header reads &lt;code&gt;alg: none&lt;/code&gt; and the signature segment is empty, it is asking to be trusted with zero proof. Production systems reject it. Debuggers treat it as a finding, not a curiosity.&lt;/p&gt;

&lt;h2&gt;
  
  
  The habit, compressed
&lt;/h2&gt;

&lt;p&gt;Decode before you theorize. Check &lt;code&gt;exp&lt;/code&gt;, &lt;code&gt;iss&lt;/code&gt;, &lt;code&gt;aud&lt;/code&gt;, &lt;code&gt;scope&lt;/code&gt; in that order. Know whether you're holding an access token or an ID token before you blame the API. Trust signatures, not payloads. And when a token misbehaves, paste it somewhere safe before pasting it into a search engine — the answer is usually in the middle segment.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I build &lt;a href="https://ajiez.top/" rel="noopener noreferrer"&gt;Ajiez&lt;/a&gt;, a collection of free, local-only browser tools — the JWT decoder above is one of them. Everything runs client-side: your tokens, keys and files never leave your machine.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>jwt</category>
      <category>security</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>108 Keywords Later: How I Chose What Tutorials to Write for a 101-Tool Site</title>
      <dc:creator>Ajiez</dc:creator>
      <pubDate>Mon, 14 Sep 2026 23:41:01 +0000</pubDate>
      <link>https://dev.to/ajiezai/108-keywords-later-how-i-chose-what-tutorials-to-write-for-a-101-tool-site-14jc</link>
      <guid>https://dev.to/ajiezai/108-keywords-later-how-i-chose-what-tutorials-to-write-for-a-101-tool-site-14jc</guid>
      <description>&lt;p&gt;Most content roadmaps are vibes with a spreadsheet skin. You list what you &lt;em&gt;feel&lt;/em&gt; your audience needs, ship it, and six months later Search Console quietly informs you that nobody searched for half of it. When I finished building &lt;a href="https://ajiez.top/" rel="noopener noreferrer"&gt;Ajiez&lt;/a&gt; — a collection of 101 free browser tools — I had 37 tutorials to plan and exactly zero interest in guessing again. So I pulled real search data first and let it overrule me. It did, repeatedly. Here's what the numbers said, and the small-site workflow you can copy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data pull
&lt;/h2&gt;

&lt;p&gt;Bing Webmaster Tools exposes an API endpoint that returns weekly impression counts for any keyword, by country and language. It's the quiet cousin of Google's keyword tools: free, boring, and — crucially for a small site — good enough to rank &lt;em&gt;directions&lt;/em&gt; even when it can't promise &lt;em&gt;volumes&lt;/em&gt;. The usual caveat applies: Bing serves roughly a quarter to a third of Google's search volume in my niches, so I treat every number as a compass reading, not a forecast.&lt;/p&gt;

&lt;p&gt;I drafted 108 candidate keywords across my tool categories — finance, PDF, images, dev utilities, text — and queried them all for the US market, English, exact match. Every request succeeded. Seventy-one keywords came back with data. Thirty-seven came back with &lt;em&gt;nothing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That "nothing" is worth pausing on, because it's the most misunderstood output in keyword research. An empty response doesn't mean zero people search for the term. It means Bing has no measurable ad inventory for it — no impressions recorded. For a tiny site, that's still actionable: these are words where even Bing's demand signal is too thin to plan around. Park them; don't build on them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the data changed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The guide I almost didn't write.&lt;/strong&gt; My assumption was that JSON tooling was my biggest content gap — developers break JSON constantly. The data said otherwise: "diff checker" showed 2,841 weekly exact-match impressions, nearly four times "json validator" at 790. Comparing two versions of a text is a far more universal act than debugging a config file: contract redlines, essay revisions, pull-request descriptions. So the first guide out of the gate was &lt;a href="https://ajiez.top/guides/how-to-diff-two-texts/" rel="noopener noreferrer"&gt;how to diff two texts&lt;/a&gt;, pointing at a &lt;a href="https://ajiez.top/text-compare/" rel="noopener noreferrer"&gt;text compare tool&lt;/a&gt; that runs entirely in the browser. The assumption I started with would have spent my best slot on the fourth-best topic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Same field, different wedge.&lt;/strong&gt; "Json formatter" pulls 3,946 weekly impressions — and an incumbent site has owned that head term for a decade. Fighting it head-on is a content strategy for sites with domain authority I don't have. But "json validator" at 790 is a different &lt;em&gt;intent&lt;/em&gt;: not "make this pretty" but "find what's broken," ideally with a line number. That intent shapes a different page — a "why your JSON breaks and how to read the error" guide that pairs with a &lt;a href="https://ajiez.top/json-formatter/" rel="noopener noreferrer"&gt;formatter and validator&lt;/a&gt; that flags the failing line. Volume told me the field was alive; the &lt;em&gt;split&lt;/em&gt; between two nearly identical keywords told me where the opening was.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggregating families beats staring at single words.&lt;/strong&gt; "Amortization schedule" alone showed 1,873 weekly impressions. But four related phrasings — the schedule itself, "with extra payments," "extra payment calculator" variants — added another ~230. Families matter because one good guide captures the whole cluster, and the family total told me this was the largest finance content opportunity in my entire dataset. A mortgage amortization guide with worked extra-payment examples went near the top of the queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tool queries are content opportunities too.&lt;/strong&gt; "Character count" pulls 1,047 weekly impressions, locked up by counters that answer the mechanical question and nothing else. But the &lt;em&gt;interesting&lt;/em&gt; question behind that query is platform rules: why does any link on X cost exactly 23 characters, why does a Chinese SMS split at 70 instead of 160, why does Google truncate your 58-character title anyway? That's a cheat sheet, not a tool feature — so I wrote one, next to a plain &lt;a href="https://ajiez.top/word-counter/" rel="noopener noreferrer"&gt;word counter&lt;/a&gt; for the mechanical job. The &lt;a href="https://ajiez.top/guides/character-limit-cheat-sheet/" rel="noopener noreferrer"&gt;character limits cheat sheet&lt;/a&gt; targets the question the head-term sites were ignoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  The finding that rewrote my positioning
&lt;/h2&gt;

&lt;p&gt;Here's my favorite result, and it was a negative one. My site's whole differentiation is that files never upload — everything runs client-side. Naturally, I queried "no upload," "without uploading," "offline tools" and eight similar phrasings. &lt;strong&gt;Eleven seed keywords, zero data. All of them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The conclusion isn't that privacy doesn't matter. It's that nobody &lt;em&gt;searches&lt;/em&gt; for it. People search for the task ("compress PDF"), then choose between results — and "your file never leaves this tab" is what wins them at the moment of choice. That reframed privacy from a &lt;em&gt;keyword strategy&lt;/em&gt; (which would have wasted a page on it) into a &lt;em&gt;conversion message&lt;/em&gt; that belongs in title tails and trust bars across every page I already have. Arguably the most valuable thing 108 API calls bought me was the death of one bad page idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  The workflow, distilled
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;List candidate keywords from your own features first&lt;/strong&gt; — every tool you've built implies five to ten queries it could answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull exact-match weekly impressions&lt;/strong&gt; for all of them in one batch. Any free source beats none; Bing's API is unglamorous and sufficient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sort by family, not by word.&lt;/strong&gt; Aggregate phrasings that one page could satisfy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read the splits inside a field.&lt;/strong&gt; Formatter-vs-validator, schedule-vs-extra-payments — near-duplicate words with different intents are where small sites find openings the incumbents left.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Honor the empty responses.&lt;/strong&gt; Zero data means don't build; log it and move on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate data from inference.&lt;/strong&gt; My volume numbers are measurements; my competition calls are me reading result pages with my eyes. I label them differently in my notes, and this post does too.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My tutorial roadmap is now chosen, sequenced, and justified by numbers I can re-run any afternoon. Some of it will still flop — data shrinks the odds of a bad bet; it doesn't erase them. But "I wrote this because 2,841 people a week ask this question and the current answers don't run locally" is a far better reason than a hunch.&lt;/p&gt;

&lt;p&gt;If you want to see where the workflow landed, the &lt;a href="https://ajiez.top/guides/how-to-diff-two-texts/" rel="noopener noreferrer"&gt;diff guide&lt;/a&gt; and the rest of the stack are live on &lt;a href="https://ajiez.top/" rel="noopener noreferrer"&gt;Ajiez&lt;/a&gt; — 101 tools, everything client-side, no accounts. And if you've got your own small-site keyword workflow, I'd genuinely like to hear what your empty responses taught you.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>sideprojects</category>
      <category>buildinpublic</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AI tools that never upload your files: I only trust calculators and cutouts that run in my browser</title>
      <dc:creator>Ajiez</dc:creator>
      <pubDate>Sat, 12 Sep 2026 15:45:40 +0000</pubDate>
      <link>https://dev.to/ajiezai/ai-tools-that-never-upload-your-files-i-only-trust-calculators-and-cutouts-that-run-in-my-browser-3l8p</link>
      <guid>https://dev.to/ajiezai/ai-tools-that-never-upload-your-files-i-only-trust-calculators-and-cutouts-that-run-in-my-browser-3l8p</guid>
      <description>&lt;p&gt;Every few months a new online tool goes viral, and every few months someone discovers that the "privacy-friendly" PDF editor they just used shipped their tax documents to a server farm. I got tired of wondering, so I started applying one simple test to every tool I use: &lt;strong&gt;open DevTools, go to the Network tab, and watch what happens when I feed it a file.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For most tools, the answer is sobering. The file leaves the tab before the first preview renders.&lt;/p&gt;

&lt;p&gt;A browser in 2026 is an absurdly capable runtime. WebAssembly runs real ML models. Canvas and WebCrypto handle images and encryption natively. Which means a whole class of tools — the kind that used to demand an upload — can now run entirely on your machine, and the only reason many still don't is that uploading your file is a better business model than respecting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two-minute privacy test
&lt;/h2&gt;

&lt;p&gt;Try this on any tool site:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open DevTools → Network tab.&lt;/li&gt;
&lt;li&gt;Drop your file in.&lt;/li&gt;
&lt;li&gt;Watch for a request with a body.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the list stays quiet while the tool works, everything happened locally. If a POST flies off to an API the moment you click — you were the product, or at least your file was.&lt;/p&gt;

&lt;p&gt;This test is why I ended up building my daily toolkit around &lt;a href="https://ajiez.top/" rel="noopener noreferrer"&gt;Ajiez&lt;/a&gt;, a collection of 101 free browser tools. The &lt;a href="https://ajiez.top/background-remover/" rel="noopener noreferrer"&gt;background remover&lt;/a&gt; is the flagship demo: a real segmentation model (U2Net, ~5 MB) downloads once into the browser cache and every cutout after that runs on-device. Cut out a photo of your kid, your ID, a client's product shot — nothing uploads, because there is no upload path in the code at all. Disconnect your Wi-Fi and it still works. That's not a privacy policy; that's an architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The calculators nobody thinks about
&lt;/h2&gt;

&lt;p&gt;Here's the part that surprised me: the tools that leak the most sensitive data are the boring ones. People paste salary numbers into "paycheck calculators" hosted by lead-gen farms, feed their mortgage details into refinancing funnels, and paste invoice totals into sites that exist to sell their data to lenders.&lt;/p&gt;

&lt;p&gt;That's why I point anyone doing money math at a calculator cluster that runs the same way as the cutout tool: entirely in the tab. The &lt;a href="https://ajiez.top/finance-tools/" rel="noopener noreferrer"&gt;finance calculators hub&lt;/a&gt; covers the whole "money questions" stack — take-home pay under 2024 federal rules, the self-employment tax freelancers always underestimate, credit card payoff timelines that show why minimum payments take 56 years, retirement projections with the 4% rule spelled out. The math is plain JavaScript running against your inputs; the numbers have no way to leave.&lt;/p&gt;

&lt;p&gt;There's an extra benefit beyond privacy: &lt;strong&gt;the tool works when the site doesn't care anymore&lt;/strong&gt;. No rate limits, no signup walls, no "you've used your 3 free operations today." A browser-local tool can't meter you, because there's no server to do the metering.&lt;/p&gt;

&lt;h2&gt;
  
  
  What browser-only can't do
&lt;/h2&gt;

&lt;p&gt;To be fair about the trade-offs: a 5 MB WASM model is not a 5 GB datacenter model, so the background remover is good, not magical — complex hair edges lose to server-side monsters. And anything that genuinely needs fresh data (live currency rates, say) still needs a network call somewhere. The honest framing: for a huge slice of everyday tasks — cutouts, OCR, PDF surgery, every calculator under the sun — local execution is not a compromise anymore. It's just better defaults.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the test yourself
&lt;/h2&gt;

&lt;p&gt;The next time a tool asks for a file or a number, spend the two minutes. Open the Network tab first. Tools that pass it quietly deserve your bookmarks; tools that don't deserve a second thought.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(I keep the whole toolbox at &lt;a href="https://ajiez.top/" rel="noopener noreferrer"&gt;ajiez.top&lt;/a&gt; — no account, no uploads, and the DevTools test above will confirm both claims.)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>privacy</category>
      <category>tools</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
