How to Encode Base64: Text, Images and Files (and When Not To)

Here is a mistake that takes about ten seconds to make. You convert a 400,000-byte photo to Base64, paste it into your stylesheet and save the file. That photo is now roughly 533,000 characters of text sitting inside your CSS, and the browser has to download all of it along with the rest of the stylesheet.

Nothing breaks. Nothing warns you. That is exactly why it is worth understanding Base64 properly: it is easy to do, genuinely useful in the right place, and quietly expensive in the wrong one.

This guide shows you how to encode Base64 for text, images and files, how to build a Data URI, which settings matter (URL-safe output, padding, line wrapping), and how to decide whether you should be encoding at all.

Quick answer: how to encode Base64

Base64 encoding turns bytes into plain text using 64 safe characters: A to Z, a to z, 0 to 9, plus + and /. It reads your data three bytes at a time and writes four characters for each group, adding = at the end if the last group is short. You can do it with an online Base64 encoder or with one line of code. The result is about one third larger than the original, and it is not encrypted.

Should you Base64 encode it at all?

Start here, because the most useful Base64 skill is knowing when to skip it.

SituationEncode?Why
Binary data inside a JSON fieldYesJSON strings carry text, not raw bytes
Email attachmentYes, usually automaticEmail was built around text, so attachments are Base64-encoded
Tiny icon inside CSS or HTMLOftenSaves a separate file request, and the size cost is small
Large photo inside CSS or HTMLUsually noAbout one third bigger, and it can’t be cached or reused on its own
A value inside a URL or query stringYes, in the URL-safe formStandard Base64 contains characters that clash with URLs
Hiding a password or secretNoBase64 gives no confidentiality
A file you can simply send as a fileUsually noYou’d pay the size cost for no benefit

If your situation lands in the “yes” rows, read on.

How Base64 encoding works, with real examples

The method is simple. Take three bytes (24 bits), split them into four groups of 6 bits, and turn each group into a character from the Base64 alphabet. This is how RFC 4648, the standard that defines Base64, describes it.

When the input doesn’t divide evenly into groups of three, zero bits are added to complete the last group and the output is padded with =. Here are the official test vectors from that RFC, which make a handy Base64 encoding example:

InputBytesBase64 outputPadding
f1Zg==Two =
fo2Zm8=One =
foo3Zm9vNone
foob4Zm9vYg==Two =
fooba5Zm9vYmE=One =
foobar6Zm9vYmFyNone

That pattern is Base64 padding in a nutshell. If the byte count is a multiple of 3, there is no padding. If one byte is left over, you get ==. If two bytes are left over, you get =. The RFC says padding must be included unless the specification you’re working with explicitly says otherwise.

How much bigger does it get?

The output length is always 4 × ⌈bytes ÷ 3⌉ characters. Here is what that means in practice:

Original sizeBase64 length
1,000 bytes1,336 characters
10,000 bytes13,336 characters
100,000 bytes133,336 characters
1,000,000 bytes1,333,336 characters

Base64 always costs about 33 percent extra. A Data URI adds a short prefix on top. Compression during transfer can change the real-world numbers, so measure on your own page before deciding.

How to encode text to Base64

For plain text, the steps are the same everywhere:

  1. Turn your text into bytes (this is where character encoding matters).
  2. Encode those bytes as Base64.
  3. Copy the result, including any = at the end.

Here is how that looks in common environments:

EnvironmentHow to encode
Node.jsBuffer.from("Hello", "utf8").toString("base64")
Browser JavaScriptbtoa("Hello") (Latin-1 characters only; see below for other text)
Pythonbase64.b64encode("Hello".encode("utf-8")).decode()
Linux (GNU base64)printf 'Hello' | base64
PowerShell[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("Hello"))

All of these give SGVsbG8= for the text “Hello”.

Two traps that change your output

The trailing newline. On the command line, echo "Hello" | base64 produces SGVsbG8K, not SGVsbG8=. The extra K comes from the newline character that echo adds at the end. Use printf 'Hello' or echo -n 'Hello' to encode exactly what you typed. This is one of the most common reasons two people get different results for the “same” text.

Non-English text and emoji. Base64 encodes bytes, and the same text produces different bytes depending on the character encoding. UTF-8 is the usual choice for the web. In the browser, btoa() only accepts characters in the Latin-1 range and throws an error on anything outside it, so encode the text to UTF-8 bytes first (with TextEncoder), then Base64 those bytes.

TextUTF-8 Base64
HelloSGVsbG8=
caféY2Fmw6k=
😀8J+YgA==

Notice that café is five bytes in UTF-8, not four, because é takes two bytes. That’s why its output is longer than you might guess.

How to convert an image to Base64 (and build a Base64 Data URI)

To convert an image to Base64, you encode the file’s bytes exactly like any other data. The only extra step is deciding whether you need the raw Base64 string or a full Base64 Data URI.

A Data URI packs the file into a single string that you can use anywhere a URL goes:

data:[media type];base64,[the Base64 data]

Here is a working example, a 1×1 transparent GIF:

html

<img alt="" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">

And the same idea in CSS:

css

.dot {
  background-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
}

The part before the comma tells the browser what kind of file it is, so it needs to match your file: image/png for PNG, image/jpeg for JPEG, image/gif for GIF, and so on.

Which version you need depends on where you’re pasting it:

Where it’s goingWhat you need
HTML src or CSS url()The full Data URI, prefix included
A JSON field in an API requestUsually the raw Base64 string only, because the receiving system defines the file type
An email attachmentMIME-style Base64 with line breaks (your email software normally handles this)

When inline images make sense

Inline images are a trade-off. You save a file request, but the image data now travels inside the HTML or CSS file that contains it. It can’t be cached or reused separately, and any change to the image means the whole file changes too. That makes the technique a good fit for tiny, rarely changing graphics like small icons, and a poor fit for photos or anything large.

Standard, URL-safe and MIME-wrapped Base64

“Base64” is really a small family. The alphabet and the line-break rules differ depending on where the output will be used:

VariantCharacters 62 and 63PaddingLine breaksTypical use
Standard Base64+ and /YesNoneAPIs, JSON fields, general data
URL-safe Base64 (base64url)- and _Often left outNoneURLs, query strings, JWTs
MIME-style Base64+ and /YesEvery 76 charactersEmail attachments

A few details are worth knowing, and they all come from RFC 4648:

  • URL-safe Base64 exists because + and / can be a problem in URLs and filenames. The = padding character is typically percent-encoded in a URL, which is why it is often skipped when the data length is known. The RFC also says this variant should not be called just “base64.”
  • The 76-character limit comes from MIME. The RFC explains that MIME and PEM line limits (76 and 64 characters) both come from limits in SMTP, and that encoders must not add line breaks unless the specification you’re following asks for them.
  • Every 57 bytes of input produce exactly one 76-character line.

To see the difference in action, take two bytes with values FB FF. Standard Base64 gives +/8=. URL-safe Base64 gives -_8=, and without padding, -_8.

If you’re not sure which one you need, the rule is simple: use URL-safe when the output goes into a URL, MIME-wrapped when it goes into an email, and standard for everything else.

Encoding a list: one block or one item per line?

Say you have two values, alice and bob. You can encode them in two different ways, and the results are not interchangeable:

ApproachResult
Each value on its ownalice → YWxpY2U= and bob → Ym9i
Both lines as one blockYWxpY2UKYm9i (the line break between them is part of the data)

Pick the first approach when each value needs its own Base64 string, such as separate IDs or usernames. Pick the second only when you really want one string containing the whole text, line breaks included.

Common Base64 encoding mistakes

MistakeWhat goes wrongFix
Encoding twiceThe receiver decodes once and still sees Base64Encode once; if decoded output still looks like Base64, it was encoded twice
Hidden newline from echoOutput ends in a different character (K)Use printf or echo -n
btoa() on non-Latin textError, or wrong outputConvert to UTF-8 bytes first
Standard Base64 in a URL+, / and = can be misread or alteredUse the URL-safe variant
Line breaks left in the stringSome decoders reject them, while MIME-style decoders ignore themDon’t wrap unless the specification asks for it
Missing or wrong Data URI prefixThe browser may not display the imageInclude data: and the correct media type
Inlining large imagesBigger HTML or CSS and no separate cachingLink to the image file instead
Treating Base64 as protectionAnyone can decode itUse real encryption for secrets

Base64 is not encryption

Base64 changes how data is written. It does not hide it from anyone. RFC 4648 says this directly in its security section: base encoding visually obscures things like passwords but provides no confidentiality, and it notes that this has caused real security incidents when people shared encoded data without realizing it was readable.

HTTP Basic authentication shows how easily this goes wrong. It sends username:password as Base64. The text user:password becomes dXNlcjpwYXNzd29yZA==, and anyone who sees that header can reverse it in seconds. If you need to protect something, encrypt it. Base64 is for compatibility, not secrecy.

Quick checklist before you encode

If you’re encoding for...Use
An image in HTML or CSSFull Data URI with the correct media type
A JSON or API fieldStandard Base64, no line breaks
A URL or query stringURL-safe Base64
An email attachmentMIME-style Base64 (76-character lines)
Text with accents or emojiUTF-8 bytes first, then Base64
A list of separate valuesOne item per line, encoded individually
Anything secretReal encryption, not Base64

Need to encode something right now?

If you have text or a file in front of you and just want the Base64 string, you can use the Base64 encoder on BytePriva. To double-check your result, paste it into the Base64 decoder and make sure you get your original back.

Frequently asked questions

What is Base64 encoding used for?

It lets binary or special-character data travel through systems built for plain text. Common examples include email attachments, binary data inside JSON, images embedded in HTML or CSS, and parts of JWT tokens.

How do I encode text to Base64?

Convert the text to bytes (UTF-8 is the usual choice), then Base64-encode those bytes. You can do that with an online encoder or a single line in JavaScript, Python, PowerShell or the Linux command line.

How do I convert an image to Base64?

Encode the image file’s bytes as Base64. If you want to use it directly in HTML or CSS, add the prefix data:image/png;base64, (or the media type that matches your file) in front of the encoded string.

What is a Base64 Data URI?

It’s a string that contains a whole file inside a URL-style value, written as data:[media type];base64,[data]. Browsers can use it anywhere they accept a normal URL, such as an image source.

Does Base64 make data bigger?

Yes. Every 3 bytes become 4 characters, so the output is about one third larger than the original.

Why does Base64 end with = or ==?

Those are padding characters. Base64 works in groups of three bytes, and = or == fill out the final group when the input doesn’t divide evenly.

What is URL-safe Base64, and when should I use it?

URL-safe Base64 replaces + with - and / with _, and often leaves out the = padding. Use it when the result will appear in a URL, query string or filename.

Why do two tools give different Base64 for the same text?

The usual causes are a hidden trailing newline, a different character encoding, line wrapping, or one tool using the URL-safe alphabet. Check those four first.

Is Base64 encoding secure?

No. It is fully reversible by anyone and provides no confidentiality. Use encryption if you need to protect data.

Can I Base64 encode any file?

Yes. Base64 works on bytes, so any file type can be encoded. Just remember that the output is about a third larger than the file.

Key takeaways

  • Base64 turns bytes into safe text. It is for compatibility, not secrecy.
  • The output is always about 33 percent larger: 4 characters for every 3 bytes.
  • Encode text as UTF-8 bytes, and watch out for the hidden newline that echo adds.
  • Use URL-safe Base64 for URLs, MIME-style wrapping for email, and standard Base64 for everything else.
  • Inline Data URIs suit tiny images. Large ones are better linked as normal files.

Disclaimer: This article is for general educational purposes only. Base64 is an encoding, not encryption, and offers no protection for sensitive data. Code examples and commands are for illustration, and behavior can vary between software versions and operating systems, so test them in a safe setting before using them in production. Avoid pasting real passwords, private keys or live secrets into any online tool unless you understand how it handles your data.

Related Guides

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top