Image to Base64: How to Embed Images as Data URIs

Inline images directly in your code to eliminate HTTP requests and simplify deployment.

🔤 🖼️ 📦 💾 🔗

TL;DR: Base64 encodes image bytes as text so you can embed them directly in HTML, CSS, or JavaScript. Great for tiny icons (under 4 KB) and self-contained HTML files. Bad for large images because Base64 adds ~33% to file size and kills caching. Use it wisely.

Picture this: instead of referencing an image with a file path like /images/logo.png, you embed the entire image as a long string of text directly inside your HTML or CSS. The browser decodes it on the spot — no separate HTTP request needed. That is what a data URI does, and it is powered by Base64 encoding.

Sounds weird? It kind of is. But it is also incredibly useful in the right situations. Let me explain when it makes sense, when it absolutely does not, and how to actually do it.

Base64 encoding is basically the image version of describing a painting to someone over the phone. It works, but the description is always longer than just showing them the picture.

What is Base64, Anyway?

Base64 is a way to represent binary data (like image bytes — all those 1s and 0s) using only 64 safe, printable characters: A-Z, a-z, 0-9, +, and /. It was originally invented for sending binary files through text-only protocols like email.

The trade-off is size: every 3 bytes of original data become 4 Base64 characters. That means Base64 makes things about 33% bigger. A 10 KB image becomes roughly 13.3 KB as Base64.

📏 Base64 rule: original size × 1.33 = encoded size. Always bigger, never smaller.

The Data URI Format

A data URI wraps the Base64 string with some metadata so the browser knows what to do with it:

data:[media-type];base64,[encoded-data]

// Real examples:
data:image/png;base64,iVBORw0KGgoAAAANS...
data:image/jpeg;base64,/9j/4AAQSkZJRg...
data:image/svg+xml;base64,PHN2ZyB4bWxu...

Using Data URIs in HTML

<!-- Inline image -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."
     alt="Small icon"
     width="24" height="24">

<!-- Inline favicon (zero network requests!) -->
<link rel="icon"
      href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...">

Using Data URIs in CSS

.icon-check {
  background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...');
  background-size: contain;
  width: 20px;
  height: 20px;
}

/* For SVGs, you can skip Base64 and use URL-encoded text instead */
.icon-arrow {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14' stroke='%23333' fill='none'/%3E%3C/svg%3E");
}

Pro tip for SVGs: skip Base64 entirely and use URL-encoded text instead. It is more readable and actually smaller because you avoid the 33% Base64 overhead.

Converting Images in JavaScript

Here is how to convert a file input to Base64 in the browser:

function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

// Usage with a file input
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
  const dataUri = await fileToBase64(e.target.files[0]);
  console.log(dataUri);
  // "data:image/png;base64,iVBORw0KGgo..."
});

You can also convert from a Canvas element or fetch a URL:

// Canvas to Base64
const canvas = document.querySelector('canvas');
const dataUri = canvas.toDataURL('image/png');

// Fetch a URL and convert
async function urlToBase64(url) {
  const response = await fetch(url);
  const blob = await response.blob();
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.readAsDataURL(blob);
  });
}

Converting on the Command Line

# macOS / Linux
base64 -i image.png | tr -d '\n'

# With the full data URI prefix
echo -n "data:image/png;base64,$(base64 -i image.png | tr -d '\n')"
🖥️ One terminal command and you have a data URI you can paste directly into your code

When Data URIs Are a Great Idea

When Data URIs Are a Terrible Idea

Do NOT Base64-encode large images. A 100 KB image becomes 133 KB, it cannot be cached separately, and it bloats your HTML file. For images over 4-5 KB, use regular files.

Performance: The Real Trade-offs

Factor External File Data URI
HTTP requests1 per image0 (embedded)
File sizeOriginal~33% larger
CachingCached independentlyCached with parent file
Gzip benefitMinimalGood (text compresses well)

With HTTP/2 and HTTP/3, the cost of extra requests is much lower than it used to be. The sweet spot for data URIs has shrunk. When in doubt, keep images as separate files and let the browser cache do its thing.

A Note on Security

Data URIs in <img> tags and CSS backgrounds are perfectly safe. However, if your Content Security Policy (CSP) is strict, you might need to allow data: in your img-src directive:

Content-Security-Policy: img-src 'self' data:;

Data URIs are a clever trick that shines in specific scenarios: tiny icons, self-contained documents, and email templates. For everything else, regular image files with proper caching are the better choice. Know when to use each and your sites will be both fast and maintainable.

Try It Yourself

Drop any image into our converter and get the Base64 data URI instantly. Copy as HTML, CSS, or raw Base64.

Open Image to Base64 Converter →