DEV Community

Cover image for How I "Vibe-Coded" a Privacy-First, Client-Side Base64 Tool (Deep-Dive into Unicode Handling in JS)
Vo Viet Hoang
Vo Viet Hoang

Posted on

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"
Enter fullscreen mode Exit fullscreen mode

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 === 'encode') {
            if (!inputValue) return '';
            // Convert plain text string into UTF-8 bytes
            const utf8Bytes = new TextEncoder().encode(inputValue);

            // Convert byte array into a binary string representation
            const base64String = btoa(String.fromCharCode.apply(null, utf8Bytes));
            return base64String;
        } else {
            if (!inputValue) return '';
            // Decode Base64 string back into a binary string
            const binaryString = atob(inputValue);

            // Map binary string back to an array of bytes
            const bytes = new Uint8Array(binaryString.length);
            for (let i = 0; i < binaryString.length; i++) {
                bytes[i] = binaryString.charCodeAt(i);
            }

            // Decode bytes back into a standard Unicode string
            const decodedString = new TextDecoder().decode(bytes);
            return decodedString;
        }
    } catch (e) {
        console.error("Conversion error. Please check your input format.");
        return null;
    }
}
Enter fullscreen mode Exit fullscreen mode

Layout & User Experience

The interface is structured to make conversion quick and straightforward:

  1. Local Processing: The utility runs strictly on your local device. No data is sent to a server.
  2. Dual-Column Design: A split layout separating "Plain Text" on one side and "Base64 String" on the other.
  3. One-Click Copy: Convenient buttons to copy the output text directly to your clipboard.

If you need a rapid, private way to encode or decode text strings without server tracking, feel free to use this utility:

👉 Live Link: Online Base64 Decoder and Encoder


Let's Connect!

How do you handle day-to-day text formatting and decoding in your workflow? Do you write quick local terminal aliases, or do you prefer to use lightweight browser-based utilities?

Let me know in the comments below! Happy coding! 🚀

Top comments (0)