How I "Vibe-Coded" a Privacy-First, Client-Side Base64 Tool (Deep-Dive into Unicode Handling in JS)
Hey DEV community! 👋 As developers, we handle Base64 encoding and decoding almost daily—whether we're debugging API payloads, formatting authorization headers, or embedding small graphic assets directly into stylesheets. However, many online translation utilities process your inputs on their backend servers. If you are dealing with sensitive configuration parameters, internal logs, or keys, pasting that data into a third-party web tool is a clear data privacy risk. To solve this, I decided to "vibe-code" a lightweight, strictly browser-based, privacy-oriented Base64 Encoder & Decoder . In this post, we will look at how this utility was built using AI assistance and vanilla JavaScript, along with the core logic to handle common encoding pitfalls. What is "Vibe Coding"? For those unfamiliar with the term, vibe coding is the practice of leveraging modern generative AI models to handle the bulk of the standard layout and event listeners, while you focus on the core logic, user experience, and privacy requirements. Instead of writing every CSS class and event listener manually, I guided an AI assistant to generate a clean, responsive layout using a standard grid framework, while ensuring that the core translation logic resides strictly in the user's browser. The Pitfall of Traditional JS Base64 (and How to Fix It) If you have ever used native JavaScript btoa() and atob() functions, you might know they struggle with Unicode/UTF-8 characters (like emojis or non-Latin scripts). Running this in your console will throw an error: btoa ( " Xin chào! 🚀 " ); // Throws "Uncaught DOMException" To resolve this during the development process, the utility implements modern TextEncoder and TextDecoder APIs. This approach converts strings into binary byte arrays before encoding them, avoiding exceptions. The Client-Side Implementation Here is the clean JavaScript snippet used for bidirectional encoding and decoding: function processBase64 ( action , inputValue ) { try { if ( action ===