Base64 Encoder & Decoder: What It Is, How It Works, and When to Use It

Base64 is a way to represent binary data as plain text using 64 ASCII characters: A–Z, a–z, 0–9, plus + and /. It lets binary like images, keys, and email attachments travel safely through systems built for text. It is encoding, not encryption.
Base64 uses a fixed alphabet of 64 characters. Each value from 0 to 63 maps to exactly one of them, which is how any 3 bytes of binary become 4 readable characters:
| Values | Characters | Description |
|---|---|---|
| 0–25 | A–Z | 26 uppercase letters |
| 26–51 | a–z | 26 lowercase letters |
| 52–61 | 0–9 | 10 digits |
| 62–63 | + / | 2 symbols |
The = sign is the one exception. It is padding, not one of the 64 values, and only rounds out the last block.
You have almost certainly seen it already. Base64 shows up wherever binary needs to ride inside text:
That data-URI trick looks like this. The long string is the entire image:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />

Why does Base64 exist?
Early network protocols were built for text, not raw bytes. ASCII used 7 bits and 128 characters, which was fine for English but not for binary. Some systems mangled control characters or rewrote line endings (LF to CR + LF), quietly corrupting images and audio in transit.
Base64 sidesteps all of that by only ever emitting characters every system already agrees on. Base16 and Base32 do the same job with smaller alphabets, but Base64 packs more data per character while staying safe. That is why it won.

How Base64 encoding works
The whole scheme is one idea on repeat: take 3 bytes (24 bits), re-slice them into four 6-bit groups, and look each group up in the alphabet. Here is the word "Logto", encoded by hand.
= so every block stays 4 characters.Step 1. Turn each character into its 8-bit binary:
| Character | ASCII code | Binary |
|---|---|---|
| L | 76 | 01001100 |
| o | 111 | 01101111 |
| g | 103 | 01100111 |
| t | 116 | 01110100 |
| o | 111 | 01101111 |
Step 2. Take the first three bytes, "Log", and re-slice those same 24 bits into four 6-bit groups:
01001100 01101111 01100111010011 000110 111101 100111Step 3. Read each 6-bit group as a number, then look the number up in the alphabet:
| 6-bit group | Value | Base64 character |
|---|---|---|
| 010011 | 19 | T |
| 000110 | 6 | G |
| 111101 | 61 | 9 |
| 100111 | 39 | n |
"Logto" is 5 bytes, not a multiple of 3. The last two bytes, "to", leave a 6 + 6 + 4 split. Pad those last 4 bits with zeros to fill a 6-bit group, then add one = to complete the 4-character block.
Put the blocks together:
"Logto" → TG9ndG8=
Every language ships this built in. In Node.js:
const text = 'Logto';
const base64 = Buffer.from(text).toString('base64');
console.log(base64); // TG9ndG8=Three rules fall out of that process, worth keeping in mind:
= means padding: It only appears when the input is not a multiple of 3 bytes.= means a multiple of 3 bytes, one = means 2 leftover bytes, two = means 1 leftover byte.Sources:
When should you use Base64?
Reach for Base64 when binary has to pass through a text-only channel:
What you get in return:
URL-safe Base64 (Base64URL)
Standard Base64 leans on three characters that clash with how URLs, query strings, and filenames work: +, /, and the = padding. Drop a normal Base64 string into a link and it can break in quiet ways:
+ turns into a space. In a query string, many servers read + as a space. So ?data=ab+cd quietly arrives as "ab cd", and the bytes are wrong./ is a path separator. A / inside a value can be read as a new path segment, and most filesystems reject it in a filename outright.= is reserved as well. It splits keys from values in a query string, so trailing = padding gets stripped or misread.You can percent-encode them (+ becomes %2B, / becomes %2F, = becomes %3D), but that bloats the string and is easy to double-encode by mistake.
Base64URL (RFC 4648 §5) fixes this at the source: swap + for -, swap / for _, and drop the = padding. The result drops straight into a URL, query parameter, or filename with nothing to escape. You will see it in URLs, filenames, and many web APIs.
const base64 = 'TG9ndG8=';
const urlSafe = base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
console.log(urlSafe); // TG9ndG8
Limitations (and one big misconception)
Base64 is a representation, not a free lunch. Keep three things in mind:
Base64 is not encryption. This is the mistake people make most. Base64 hides nothing. Anyone can decode it in one line. If the data is sensitive, encrypt it. Base64 only changes the shape, never who can read it.
Frequently asked questions
Is Base64 encryption or secure?
No. Base64 is purely encoding to translate binary bytes to printable characters. It provides zero security or data protection. Anyone can decode a Base64 string easily.Why is my Base64 string about 33% larger?
Because the algorithm maps every 3 bytes (24 bits) into 4 characters (each representing 6 bits). This 3-to-4 transformation adds a mathematical ~33% overhead to the final text representation.What do the = signs at the end mean?
The = character is used as padding to make sure the final output length is a multiple of 4. One = indicates 2 leftover bytes, and two = indicates 1 leftover byte.What is the difference between Base64 and Base64URL?
Base64URL swaps+ with - and / with _, and drops any trailing = padding, ensuring the output can safely be used in URL paths and query strings without percent-encoding.