A base64 data URI lets you embed an image directly inside an HTML file, CSS rule, or Markdown document without referencing an external file. Useful when you can’t host assets separately (email templates, single-file deliverables, build-time SVGs) — but counterproductive for anything bigger than a few KB, since base64 inflates the payload and bypasses normal browser caching.
How encoding works
FileReader.readAsDataURL reads the file’s bytes and produces a string of the form data:image/png;base64,<encoded>. The MIME type comes from the file’s reported type (or sniffed by the browser), and the base64 payload encodes the file’s bytes one-to-one — atob(payload) recovers the original binary exactly.
Encoded length is always exactly ceil(bytes / 3) * 4 characters of base64, plus the prefix. So a 9 KB PNG becomes a ~12 KB string. Plus quoting overhead and the line wrapping in your source file.
Example: small icon for an HTML email
A 2 KB PNG company logo, encoded with the HTML img wrap, becomes a ~2.7 KB <img> tag with alt text. Paste it into an HTML email template (where many clients block external images) and the logo always renders.
Example: CSS background
A small repeating pattern image (say, 800-byte JPEG of paper texture) encoded as background-image: url("..."); becomes a ~1.1 KB CSS rule. No extra HTTP request, no separate file to deploy alongside the stylesheet. Trade-off: the rule is now bigger and slightly harder to scan.
Example: SVG vs base64
An 800-byte SVG icon. Base64 wraps it to ~1.1 KB. URL-encoded (data:image/svg+xml;utf8,...) is closer to 900 bytes and equally-well supported. For SVG specifically, prefer URL-encoding or just inline the <svg> markup directly. The tool will base64-encode SVG on request — useful as a baseline — but the URL-encoded form is shorter.
When base64 is the wrong choice
- Big images. A 200 KB JPG becomes a 270 KB string. Now every page that uses it ships those 270 KB inside the HTML/CSS, with no separate caching. Hosting + linking is faster.
- Images on more than one page. Browsers cache files at their URL. A base64-embedded image is re-downloaded on every page; a hosted image downloaded once and reused.
- Images that change. Editing an embedded image means re-encoding and re-pasting into every file that uses it. Hosted images can be swapped at the URL.
Common mistakes
Confusing base64 with encryption. Base64 is encoding, not encryption. The bytes are recoverable by anyone with atob(). Don’t put secrets in a data URI thinking they’re hidden.
Forgetting the MIME type. A data URI with no image/... prefix won’t render. The tool always emits the prefix correctly; if you’re hand-rolling somewhere else, make sure the MIME type matches the actual file format.
Padding-stripped base64. Some tools emit base64 with the trailing = padding stripped (URL-safe variant). Standard data URIs include the padding. The tool emits standard form.
Embedding everywhere by reflex. “Avoid HTTP requests” was the right advice in 2010 over HTTP/1.1 with limited concurrency. On HTTP/2 and HTTP/3 with multiplexing, the cost of a separate request is much lower, while the cost of inflated HTML/CSS payloads is just as high.
Trusting reported KB/MB sizes as universal. macOS reports decimal sizes (1 KB = 1000 bytes); Windows reports binary sizes (1024 bytes) under the same KB label. Same file, slightly different number depending on whose ruler you use — see the explainer on MB vs MiB.
What this tool does not do
It doesn’t upload anywhere. The browser’s FileReader does the encoding locally.
It doesn’t resize, compress, or convert formats. See the image resizer, image compressor, and image format converter for those.
It doesn’t decode base64 back to a file. Browser image elements decode automatically when the data URI is set as src.
It doesn’t batch-encode multiple files. One file per session — base64 embedding is rarely a workflow you want to batch.