<?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: Jeffrey Hamilton</title>
    <description>The latest articles on DEV Community by Jeffrey Hamilton (@jeffrey_hamilton6399).</description>
    <link>https://dev.to/jeffrey_hamilton6399</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%2F4000955%2Fa3d347aa-4cea-43d3-a6f6-0fbc0a777154.jpg</url>
      <title>DEV Community: Jeffrey Hamilton</title>
      <link>https://dev.to/jeffrey_hamilton6399</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jeffrey_hamilton6399"/>
    <language>en</language>
    <item>
      <title>I got tired of 15 ad-filled dev tool websites, so I built one clean page</title>
      <dc:creator>Jeffrey Hamilton</dc:creator>
      <pubDate>Tue, 14 Jul 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/jeffrey_hamilton6399/i-got-tired-of-15-ad-filled-dev-tool-websites-so-i-built-one-clean-page-2172</link>
      <guid>https://dev.to/jeffrey_hamilton6399/i-got-tired-of-15-ad-filled-dev-tool-websites-so-i-built-one-clean-page-2172</guid>
      <description>&lt;p&gt;Every time I need to format JSON, decode a JWT, or generate a UUID, I end up on a different sketchy, ad-heavy website. I got tired of closing popups just to format my code.&lt;/p&gt;

&lt;p&gt;So I built DevToys — 40 essential developer tools in one clean, fast, single page. No ads, no sign-up, no tracking.&lt;/p&gt;

&lt;p&gt;🔗 Try it: &lt;a href="https://devtoys-nu.vercel.app" rel="noopener noreferrer"&gt;https://devtoys-nu.vercel.app&lt;/a&gt;&lt;br&gt;
📦 Source: &lt;a href="https://github.com/JeffreyHamilton6399/devtoys" rel="noopener noreferrer"&gt;https://github.com/JeffreyHamilton6399/devtoys&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's inside&lt;br&gt;
40 tools including:&lt;/p&gt;

&lt;p&gt;JSON Formatter — pretty/minify/validate&lt;br&gt;
Base64 — encode/decode&lt;br&gt;
JWT Decoder — header, payload, signature&lt;br&gt;
Regex Tester — live match highlighting&lt;br&gt;
UUID Generator — batch generation&lt;br&gt;
Hash Generator — MD5, SHA-1, SHA-256, SHA-512&lt;br&gt;
Color Converter — HEX ↔ RGB ↔ HSL&lt;br&gt;
Timestamp Converter — Unix ↔ human date&lt;br&gt;
Cron Parser — human-readable schedule&lt;br&gt;
Diff Checker — line-by-line comparison&lt;br&gt;
...and 30 more (URL encoder, Lorem Ipsum, etc.)&lt;br&gt;
The architecture&lt;br&gt;
Zero backend. It's a static site hosted on Vercel. Every tool runs entirely in your browser using native JavaScript APIs.&lt;/p&gt;

&lt;p&gt;All computation is synchronous (instant results)&lt;br&gt;
Zero heavy dependencies (tiny bundle, loads immediately)&lt;br&gt;
No tracking, no analytics, no ads&lt;br&gt;
Mobile responsive&lt;br&gt;
Try it&lt;br&gt;
🔗 Live: &lt;a href="https://devtoys-nu.vercel.app" rel="noopener noreferrer"&gt;https://devtoys-nu.vercel.app&lt;/a&gt;&lt;br&gt;
📦 Source: &lt;a href="https://github.com/JeffreyHamilton6399/devtoys" rel="noopener noreferrer"&gt;https://github.com/JeffreyHamilton6399/devtoys&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bookmark it and never look for a dev tool website again.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I built a background remover that doesn't upload your photos (no $40/month)</title>
      <dc:creator>Jeffrey Hamilton</dc:creator>
      <pubDate>Tue, 07 Jul 2026 19:21:49 +0000</pubDate>
      <link>https://dev.to/jeffrey_hamilton6399/i-built-a-background-remover-that-doesnt-upload-your-photos-no-40month-ofd</link>
      <guid>https://dev.to/jeffrey_hamilton6399/i-built-a-background-remover-that-doesnt-upload-your-photos-no-40month-ofd</guid>
      <description>&lt;p&gt;Remove.bg is a great tool, but it has a problem: they upload your photos to their servers. For personal photos, product images, or sensitive pictures, that's not ideal.&lt;/p&gt;

&lt;p&gt;So I built Cutout — an AI background remover that runs entirely in your browser. No backend, no uploads, no sign-up, no $40/month subscription.&lt;/p&gt;

&lt;p&gt;Try it: &lt;a href="https://cutout-murex.vercel.app" rel="noopener noreferrer"&gt;https://cutout-murex.vercel.app&lt;/a&gt;&lt;br&gt;
 Source: &lt;a href="https://github.com/JeffreyHamilton6399/Cutout" rel="noopener noreferrer"&gt;https://github.com/JeffreyHamilton6399/Cutout&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How it works&lt;br&gt;
The app uses &lt;a class="mentioned-user" href="https://dev.to/imgly"&gt;@imgly&lt;/a&gt;/background-removal, a powerful AI library that runs directly in the browser via WebAssembly.&lt;/p&gt;

&lt;p&gt;When you drop an image:&lt;/p&gt;

&lt;p&gt;The AI model downloads (one-time, ~40MB, then cached by the browser)&lt;br&gt;
The model runs locally via WebGPU/WASM to segment the foreground&lt;br&gt;
The background is removed, leaving a transparent PNG&lt;br&gt;
You download the result&lt;br&gt;
Your photo literally never leaves your device. There is no server.&lt;/p&gt;

&lt;p&gt;Features&lt;br&gt;
Instant removal: Drop a photo, get a transparent PNG in seconds.&lt;br&gt;
Batch mode: Remove backgrounds from multiple images at once.&lt;br&gt;
Background replacement: Keep it transparent, or add a solid white/black background for JPEG export.&lt;br&gt;
Manual refine: If the AI isn't perfect, use the eraser/restore brush to clean up edges.&lt;br&gt;
The privacy model&lt;br&gt;
 100% client-side — photos are processed in your browser&lt;br&gt;
 Zero network requests during processing (except the one-time model download)&lt;br&gt;
 No accounts, no tracking, no analytics&lt;br&gt;
 No server-side storage — there IS no server&lt;br&gt;
 Open source — read every line of code&lt;br&gt;
Try it&lt;br&gt;
 Live: &lt;a href="https://cutout-murex.vercel.app" rel="noopener noreferrer"&gt;https://cutout-murex.vercel.app&lt;/a&gt;&lt;br&gt;
 Source: &lt;a href="https://github.com/JeffreyHamilton6399/Cutout" rel="noopener noreferrer"&gt;https://github.com/JeffreyHamilton6399/Cutout&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome — happy to answer questions about the WASM model or the architecture.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>privacy</category>
      <category>ai</category>
    </item>
    <item>
      <title>File converter that never uploads your files?</title>
      <dc:creator>Jeffrey Hamilton</dc:creator>
      <pubDate>Fri, 26 Jun 2026 17:13:59 +0000</pubDate>
      <link>https://dev.to/jeffrey_hamilton6399/file-converter-that-never-uploads-your-files-1f3</link>
      <guid>https://dev.to/jeffrey_hamilton6399/file-converter-that-never-uploads-your-files-1f3</guid>
      <description>&lt;p&gt;Every online file converter — from Zamzar to CloudConvert to FreeConvert — does the same thing: they upload your files to their servers, convert them, and send them back.&lt;/p&gt;

&lt;p&gt;For personal photos, videos, and sensitive documents, that's not great.&lt;/p&gt;

&lt;p&gt;So I built ConvertIt — a file format converter that runs entirely in your browser. No backend, no uploads, no sign-up.&lt;/p&gt;

&lt;p&gt;What it converts&lt;br&gt;
Images: PNG ↔ JPEG ↔ WebP ↔ AVIF, HEIC → anything, GIF → video&lt;br&gt;
Video: MP4 ↔ WebM, MOV → MP4, any video → extract audio&lt;br&gt;
Audio: WAV → MP3, FLAC → MP3, M4A → MP3, any audio → MP3&lt;br&gt;
Documents: PDF → images (PNG/JPEG), images → PDF, SVG → PNG&lt;br&gt;
How it works&lt;br&gt;
File type   Engine  How&lt;br&gt;
Video   ffmpeg.wasm Compiled to WebAssembly, runs in-browser&lt;br&gt;
Images  Canvas API + OffscreenCanvas    Re-encode to target format&lt;br&gt;
Audio   Web Audio API + lamejs  Decode → re-encode to MP3&lt;br&gt;
PDF pdf-lib + pdfjs-dist    Render pages or combine images&lt;br&gt;
The architecture&lt;br&gt;
Zero backend. It's a static site hosted on Vercel. There is no server — your files are processed entirely in the browser.&lt;/p&gt;

&lt;p&gt;Browser (your device)&lt;br&gt;
├── Drop file&lt;br&gt;
├── Auto-detect input format&lt;br&gt;
├── Show available output formats&lt;br&gt;
├── Convert entirely in memory (Blob URLs)&lt;br&gt;
└── Download result&lt;br&gt;
↳ Files NEVER touch a server&lt;/p&gt;

&lt;h3&gt;
  
  
  Key technical decisions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Lazy-loaded heavy dependencies&lt;/strong&gt;&lt;br&gt;
ffmpeg.wasm is 32MB. We don't load it until you actually convert a video. Same for pdf-lib (PDFs) and heic2any (iPhone photos). Initial page load stays fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Auto-detection &amp;amp; routing&lt;/strong&gt;&lt;br&gt;
Drop a file → the app detects the format by extension and MIME type → shows only the relevant output formats. You can't convert a PNG to MP3, so we don't show that option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Mobile memory safeguards&lt;/strong&gt;&lt;br&gt;
Mobile devices get stricter file size limits (100MB for video vs 500MB on desktop), and ffmpeg is terminated after each conversion to free memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Never return a larger file&lt;/strong&gt;&lt;br&gt;
If a conversion somehow makes a file bigger (rare, but happens), we warn the user but still allow it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The privacy model
&lt;/h2&gt;

&lt;p&gt;This is the whole point:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100% client-side — files are processed in your browser&lt;/li&gt;
&lt;li&gt;Zero network requests during conversion&lt;/li&gt;
&lt;li&gt;No accounts, no tracking, no analytics, no cookies&lt;/li&gt;
&lt;li&gt;No server-side storage — there IS no server&lt;/li&gt;
&lt;li&gt;Open source — read every line of code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your files are yours. They shouldn't need to visit a server to be converted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://convertit.vercel.app" rel="noopener noreferrer"&gt;https://convertit.vercel.app&lt;/a&gt;&lt;br&gt;&lt;br&gt;
 &lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/JeffreyHamilton6399/ConvertIt" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome — happy to answer questions about the architecture or the ffmpeg.wasm setup.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>java</category>
      <category>privacy</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I built a file compressor that never uploads your files (ffmpeg.wasm + Canvas + Web Audio)</title>
      <dc:creator>Jeffrey Hamilton</dc:creator>
      <pubDate>Wed, 24 Jun 2026 16:57:12 +0000</pubDate>
      <link>https://dev.to/jeffrey_hamilton6399/i-built-a-file-compressor-that-never-uploads-your-files-ffmpegwasm-canvas-web-audio-43id</link>
      <guid>https://dev.to/jeffrey_hamilton6399/i-built-a-file-compressor-that-never-uploads-your-files-ffmpegwasm-canvas-web-audio-43id</guid>
      <description>&lt;p&gt;I kept using online file compressors and realized they all upload your files to sketchy servers. For tax PDFs, personal photos, and sensitive documents — that didn't feel right.&lt;/p&gt;

&lt;p&gt;So I built ShrinkRay — a file compressor that runs entirely in your browser. No backend, no uploads, no sign-up.&lt;/p&gt;

&lt;p&gt;Try it: &lt;a href="https://shrink-ray.vercel.app" rel="noopener noreferrer"&gt;https://shrink-ray.vercel.app&lt;/a&gt;&lt;br&gt;
 Source: GitHub&lt;/p&gt;

&lt;p&gt;What it compresses&lt;br&gt;
Images: PNG, JPEG, WebP, AVIF, HEIC (iPhone photos), GIF, BMP&lt;br&gt;
Video: MP4, WebM, MOV, MKV, animated GIF (via ffmpeg.wasm)&lt;br&gt;
Audio: MP3, WAV, OGG, M4A, FLAC, OPUS&lt;br&gt;
PDF: Re-renders pages as compressed images&lt;br&gt;
3D Models: GLB, GLTF, STL, OBJ, PLY, FBX — with format conversion via Three.js&lt;br&gt;
SVG: Minification (strips metadata, comments, whitespace)&lt;br&gt;
Text/Code: JSON, HTML, CSS, JS, XML, YAML — minified + gzipped&lt;br&gt;
Anything else: Gzip compression&lt;br&gt;
How it works&lt;br&gt;
File type&lt;br&gt;
Engine&lt;br&gt;
How&lt;br&gt;
Video   ffmpeg.wasm Compiled to WebAssembly, runs in-browser&lt;br&gt;
Images  Canvas API + OffscreenCanvas    Re-encode at chosen quality/format&lt;br&gt;
Audio   Web Audio API + lamejs  Decode → re-encode to MP3&lt;br&gt;
PDF pdf-lib + pdfjs-dist    Render pages → rebuild with compressed images&lt;br&gt;
3D  Three.js    Format conversion (STL→GLB, etc.) + gzip&lt;br&gt;
Text/Code   Native JS + fflate  Minify (strip comments/whitespace) → gzip&lt;/p&gt;

&lt;p&gt;The architecture&lt;br&gt;
Zero backend. It's a static site hosted on Vercel. There is no server — your files are processed entirely in the browser using WebAssembly and Canvas APIs.&lt;/p&gt;

&lt;p&gt;text&lt;/p&gt;

&lt;p&gt;Browser (your device)&lt;br&gt;
├── Drop file&lt;br&gt;
├── Auto-detect type (image/video/audio/pdf/3d/text)&lt;br&gt;
├── Route to correct engine&lt;br&gt;
├── Process entirely in memory (Blob URLs)&lt;br&gt;
└── Download result&lt;br&gt;
    ↳ Files NEVER touch a server&lt;br&gt;
Key technical decisions&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lazy-loaded heavy dependencies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ffmpeg.wasm is 32MB. We don't load it until you actually drop a video. Same for Three.js (3D), heic2any (HEIC photos), and pdfjs (PDFs). Initial page load stays fast.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multi-threaded ffmpeg when available&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On browsers with SharedArrayBuffer (COOP/COEP headers), ffmpeg uses multiple CPU cores via Web Workers. Falls back to single-threaded automatically.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pre-warm on desktop, skip on mobile&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On desktop, ffmpeg starts loading the moment the page opens (so it's ready when you drop a video). On mobile, we skip this — the 32MB download would freeze low-RAM devices.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Never return a larger file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If compression makes a file bigger (happens with already-compressed files), we return the original instead. You never download a file larger than what you uploaded.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mobile memory safeguards&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mobile devices get stricter file size limits (100MB for video vs 500MB on desktop), and ffmpeg is terminated after each conversion to free memory.&lt;/p&gt;

&lt;p&gt;The privacy model&lt;br&gt;
This is the whole point:&lt;/p&gt;

&lt;p&gt;100% client-side — files are processed in your browser&lt;br&gt;
 Zero network requests during compression&lt;br&gt;
 No accounts, no tracking, no analytics, no cookies&lt;br&gt;
 No server-side storage — there IS no server&lt;br&gt;
 Open source — read every line of code&lt;br&gt;
Your files are yours. They shouldn't need to visit a server to be compressed.&lt;/p&gt;

&lt;p&gt;Try it&lt;br&gt;
 Live: &lt;a href="https://shrink-ray.vercel.app" rel="noopener noreferrer"&gt;https://shrink-ray.vercel.app&lt;/a&gt;&lt;br&gt;
 Source: &lt;a href="https://github.com/JeffreyHamilton6399/ShrinkRay" rel="noopener noreferrer"&gt;https://github.com/JeffreyHamilton6399/ShrinkRay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome — happy to answer questions about the ffmpeg.wasm setup, the 3D conversion pipeline, or the architecture.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>privacy</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
