Guides — Tools Without AI
Engineering notes on client-side PDF, data, crypto, and accessibility utilities. Files stay in the tab. No AI processing.
36 guides
·
Client-side HTML/XML escaping against DOM-based XSS
innerHTML is a sink. Escape <>&"' or use textContent. An entity encoder is a teaching tool; it is not a substitute for not concatenating HTML.
Read guide·
Binary file slicing: how the Blob API reads large files locally
Blob.slice gives byte windows without a filesystem server. JSZip and pdf-lib consume Blobs. Revoke object URLs. Do not upload multi-GB files to convert them.
Read guide·
Epoch vs ISO 8601: local date-time without server clock skew
Unix time is seconds (or ms) from 1970-01-01T00:00:00Z. toISOString is always UTC. Convert in the browser; JWT exp and cron DST still need care.
Read guide·
Local string diffing: how Levenshtein distance works in JavaScript
Edit distance is O(nm) memory and time. Real diffs use Myers or similar. Run them in a worker so legal redlines never go to a cloud compare API.
Read guide·
The mathematics of passphrase entropy: why length defeats complexity
Entropy is log2(charset^length) for independent random symbols. NIST SP 800-63B de-emphasizes composition rules. Generate locally with a CSPRNG.
Read guide·
Calculating file checksums locally with FileReader and Blob.slice
subtle.digest is one-shot. Large files need File.slice and an incremental hasher (hash-wasm). Compare hex to shasum without uploading the binary.
Read guide·
Color space math: HEX, RGB, HSL, and CMYK in JavaScript
HEX parses to sRGB. HSL is a cylinder on that RGB. Naive CMYK without an ICC profile is not print-accurate. Convert in the tab, then check contrast.
Read guide·
URL encoding and percent-encoding variants in web app security
encodeURI, encodeURIComponent, and application/x-www-form-urlencoded disagree on reserved characters. Double-encoding causes open redirects and parser splits.
Read guide·
Symmetric vs asymmetric in-browser encryption via WebCrypto
AES-GCM needs a unique 96-bit IV. RSA-OAEP wraps keys, not bulk files. There is no dedicated encryptor page required: SubtleCrypto is the platform.
Read guide·
SQL query formatting and local AST-style pretty-printing
sql-formatter tokenizes and reprints SQL. It does not execute it. Keep production dumps off hosted SQL fiddles.
Read guide·
Base64 encoding vs binary Blobs: memory pitfalls of data URIs
Base64 expands 4/3 and JS strings are UTF-16. Prefer Blob and object URLs for files. Use Base64 when a format demands ASCII.
Read guide·
HMAC generation via Web Crypto: local keys and message integrity
HMAC-SHA256 is importKey plus subtle.sign. Keys never need to go to an online HMAC website. Decode JWTs here; sign them only with keys you hold.
Read guide·
RegEx engine optimization for in-browser log filtering
ECMAScript regex is not PCRE. Nested quantifiers ReDoS a 40 MB logcat dump. Anchor patterns, reuse one RegExp, and filter in a worker.
Read guide·
The anatomy of a UUID: collision math and CSPRNG v4 generation
RFC 9562 version 4 UUIDs use 122 random bits. Generate them with getRandomValues in the browser. They are identifiers, not secrets.
Read guide·
Local XML to JSON: DOMParser versus SAX-style walks
Browsers parse XML with DOMParser. Mapping attributes and text to JSON needs a convention (Parker, Badgerfish). Do it in memory; do not POST XML to a convert A…
Read guide·
Cron expressions: syntax, traps, and human-readable parsing
Vixie, Quartz, and AWS cron disagree on field count. DST skips or doubles hours. Explain expressions with cronstrue and cron-parser in the browser, not an LLM.
Read guide·
JWT security: decode tokens locally and do not paste secrets
JWS compact tokens are base64url header and payload. Decoding in the tab is fine. Verifying with a production secret on a random website is an incident.
Read guide·
Why structured Markdown tables beat proprietary spreadsheets in docs
GFM tables live in Git, review in pull requests, and convert from CSV in the browser. They are the wrong store for 10k rows, the right store for technical docs.
Read guide·
Structuring JSON and CSV so machines and Excel both survive
RFC 4180, UTF-8 BOM, and typed IDs as strings are the difference between a dataset and a ruined spreadsheet. Shape the files locally before anyone opens Excel.
Read guide·
The mathematics of WCAG color contrast formulas
WCAG 2 contrast is (L1+0.05)/(L2+0.05) after sRGB linearization. Implement it in JavaScript and map to AA and AAA without uploading a screenshot.
Read guide·
How to audit the Network tab to verify zero-upload privacy
Chrome DevTools Network with Fetch/XHR filtered is the lab test: your file size should not appear as a request body. Ads and JS chunks are not the file.
Read guide·
Zero-server architectures: why local web apps have no file to breach
A static origin with no upload API cannot leak your PDF from a database it does not have. Remaining risks are XSS, extensions, and the user’s own share actions.
Read guide·
Image metadata and the security risk of hidden EXIF data
JPEG APP1 and HEIC boxes carry GPS, orientation, and camera identifiers. Canvas re-encode usually drops them. Dedicated strippers parse TIFF IFDs without an up…
Read guide·
Why uploading corporate files to cloud utilities leaks telemetry
A multipart upload creates CDN logs, WAF bodies, object keys, and often derived OCR. That is shadow IT with a progress bar. Client-side tools skip the POST.
Read guide·
Data minimization under GDPR and CCPA for web workflows
If a converter never receives the file, it is not processing personal data on a server. That is Art. 5(1)(c) implemented as architecture, not a policy PDF.
Read guide·
Real-time DOM text analytics without a language model
Word and character counts belong in Intl.Segmenter and string iteration, not an LLM API. Counts update from textarea.value in the tab.
Read guide·
Client-side PDF merge and split without a document server
pdf-lib copies page objects and remaps xref numbers in the browser. Merge and split are catalog edits, not uploads to a merge API.
Read guide·
Client-side JSON to CSV and YAML without a backend ETL job
Flatten JSON to row vectors, unparse RFC 4180 CSV with Papaparse, and dump YAML with js-yaml in the tab. No ETL server sees the records.
Read guide·
Web Crypto vs cloud hashing: SHA-256 that never leaves RAM
crypto.subtle.digest and getRandomValues run in a secure context. Hashing a file or generating a password in the tab avoids posting bytes to a hash website.
Read guide·
HTML5 Canvas image processing without leaving the tab
Browsers decode images with createImageBitmap, resample on Canvas 2D, and emit JPEG or WebP via toBlob. Compression stays in RAM. Nothing is posted to a resize…
Read guide·
Edit CSV and export PDF locally
Load a CSV in the browser, edit cells in a grid, and print or export PDF from the same tab. Rows stay in memory; nothing is uploaded for “conversion.”
Read guide·
How SRI hashes are generated client-side
Subresource Integrity is a base64 digest of a script or stylesheet. Web Crypto SHA-256 in the browser produces integrity attributes without uploading the file.
Read guide·
WCAG contrast ratios in the browser
WCAG 2 contrast is a relative-luminance formula on sRGB. Compute it in JavaScript from HEX/RGB and check AA/AAA without uploading a screenshot.
Read guide·
Filter Android logcat in the browser
Paste or drop a logcat dump and filter by tag, PID, level, and regex entirely in JavaScript. No pastebin, no CI upload — the buffer stays in the tab.
Read guide·
Convert a bank statement to CSV without uploading
Parse a PDF or CSV bank statement in the browser with pdf.js and Papaparse. Rows never leave the tab. Export CSV locally for spreadsheets and bookkeeping.
Read guide·
Why PDF black boxes are not redaction
Drawing a black rectangle on a PDF does not remove text. True redaction deletes content streams and embedded objects in the browser before you save.
Read guide