← Blog
Base64 JavaScript Encoding

How to Convert an Image to Base64 (Browser & JavaScript)

Learn how to convert images to Base64 strings using an online tool, the browser FileReader API, or Node.js. With working code examples.

· GoGood.dev

Converting images to Base64 is one of those tasks that appears constantly in web development — embedding images in HTML/CSS/JSON without a separate HTTP request, sending image data through APIs, storing files in databases, or attaching images to email. It seems straightforward until you hit the browser API docs and have three different approaches to choose from.

This guide walks through exactly how to convert images to Base64 strings using an online tool, the browser FileReader API, Node.js, and when each approach actually makes sense.

TL;DR: Convert images to Base64 instantly at GoGood.dev Image to Base64 Converter — drag and drop your image, copy the Base64 string or full data URI. For code, use the FileReader API in the browser or fs.readFileSync() in Node.js.


What Is Base64 Image Encoding?

Base64 is a binary-to-text encoding that converts raw image bytes into a string of printable ASCII characters. Every 3 bytes of image data become 4 Base64 characters — which is why the output is always ~33% larger than the original.

Why encode images to Base64?

Embed images in HTML/CSS without separate files:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="pixel" />

No HTTP request. The image travels as text inside the HTML.

Send image data through JSON APIs:

{
  "user_id": "usr_123",
  "avatar": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
}

APIs that need image data often require it as Base64 in the request body.

Attach images to emails programmatically:

Email protocols are text-based. To include an image attachment, it gets Base64-encoded in the message.

Store images in databases:

Some databases or ORMs can’t handle binary columns. Base64 allows you to store image data as text.

The tradeoff: Base64 files are ~33% larger than the original. For small icons and logos this is fine. For large images or photos, the overhead becomes significant — you typically want to use actual image requests or file uploads instead.


Method 1: Use the Online Tool (No Code)

The fastest way — no programming required:

  1. Go to GoGood.dev Image to Base64 Converter
  2. Drag and drop your image (PNG, JPG, SVG, GIF, WebP, BMP)
  3. Click Copy Base64 for the raw string, or Copy Data URI for the full data:image/...;base64,... format
  4. Paste directly into your code

Supported formats: PNG, JPEG, GIF, SVG, WebP, BMP, TIFF, ICO.


Method 2: JavaScript in the Browser (FileReader API)

Use the FileReader API to convert images selected by users:

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

// Usage with file input
document.getElementById('fileInput').addEventListener('change', async (e) => {
  const file = e.target.files[0];
  const base64DataUri = await imageToBase64(file);
  console.log(base64DataUri);
  // Output: "data:image/png;base64,iVBORw0KGgo..."
});

How it works:

  • FileReader.readAsDataURL() reads the file and returns a complete data URI with MIME type prefix
  • The result includes data: + MIME type + ;base64, + encoded data
  • If you only need the Base64 string (without the prefix), strip it:
const base64OnlyString = base64DataUri.split(',')[1];
// "iVBORw0KGgo..."

Get just the Base64 string:

function imageToBase64OnlyString(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      const base64String = reader.result.split(',')[1];
      resolve(base64String);
    };
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

Use the data URI directly in HTML:

const base64DataUri = await imageToBase64(file);

// Set as img src
document.getElementById('preview').src = base64DataUri;

// Set as background image
document.getElementById('container').style.backgroundImage = `url('${base64DataUri}')`;

// Send via API
await fetch('/api/upload', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ image: base64DataUri })
});

Convert multiple images:

async function imagesToBase64(files) {
  return Promise.all(
    Array.from(files).map(file => imageToBase64(file))
  );
}

// Usage
const allImages = await imagesToBase64(document.getElementById('fileInput').files);

Method 3: Node.js (fs + Buffer)

In Node.js, use the fs module and Buffer:

const fs = require('fs');

function imageToBase64(filePath) {
  const imageBuffer = fs.readFileSync(filePath);
  const base64String = imageBuffer.toString('base64');
  return base64String;
}

const base64 = imageToBase64('./logo.png');
console.log(base64);
// "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="

With the full data URI:

function imageToDataUri(filePath) {
  const imageBuffer = fs.readFileSync(filePath);
  const base64String = imageBuffer.toString('base64');

  // Detect MIME type (simplified — use 'mime' package for production)
  const ext = filePath.split('.').pop().toLowerCase();
  const mimeTypes = {
    png: 'image/png',
    jpg: 'image/jpeg',
    jpeg: 'image/jpeg',
    gif: 'image/gif',
    svg: 'image/svg+xml',
    webp: 'image/webp'
  };
  const mimeType = mimeTypes[ext] || 'image/png';

  return `data:${mimeType};base64,${base64String}`;
}

const dataUri = imageToDataUri('./photo.jpg');
console.log(dataUri);
// "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."

Send image to API:

const fs = require('fs');

async function uploadImageAsBase64(filePath) {
  const imageBuffer = fs.readFileSync(filePath);
  const base64String = imageBuffer.toString('base64');

  const response = await fetch('https://api.example.com/upload', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      filename: 'photo.jpg',
      mimeType: 'image/jpeg',
      data: base64String
    })
  });

  return response.json();
}

Async variant (for larger files):

const fs = require('fs').promises;

async function imageToBase64Async(filePath) {
  const imageBuffer = await fs.readFile(filePath);
  return imageBuffer.toString('base64');
}

// Usage
const base64 = await imageToBase64Async('./large-photo.jpg');

Using a Base64 Image in HTML

Once you have the Base64 string, use it anywhere an image URL goes:

<!-- Direct data URI -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="transparent pixel" />

<!-- From JavaScript -->
<img id="preview" alt="preview" />
<script>
  document.getElementById('preview').src = 'data:image/png;base64,iVBORw0KGgo...';
</script>

<!-- In an iframe -->
<iframe src="data:text/html;base64,PGh0bWw+PGJvZHk+SGVsbG8gV29ybGQ8L2JvZHk+PC9odG1sPg=="></iframe>

Size matters: For small icons and logos (under 3-4 KB), embedding as Base64 eliminates HTTP requests. For larger images, the data URI parsing overhead and lack of browser caching makes it slower than a separate image request.


Using a Base64 Image in CSS

.icon {
  background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCI+PC9zdmc+');
  width: 24px;
  height: 24px;
}

.logo {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==');
  background-size: cover;
}

Advantages: No separate HTTP request for the asset. Disadvantages: CSS file becomes larger, the image isn’t cached separately, and the CSS can’t be minified as effectively.


When NOT to Use Base64 Images

Large photos: A 500 KB photo becomes 666 KB Base64. The 33% overhead is now 166 KB of wasted bandwidth.

Images used on multiple pages: If the same image appears on 10 pages, it gets decoded 10 times. Separate image file gets cached once by the browser.

Responsive images with srcset: Base64 doesn’t work well with responsive image techniques. Use actual image files.

Performance-sensitive applications: The encoding is larger, takes longer to parse, and isn’t cached. Measurable slowdown for large images.

SVG animations or complex graphics: Can still be Base64, but SVG content is already text — it’s often smaller to inline the SVG directly than to Base64 it.

Use Base64 for: Icons, logos, small decorative images (under 4 KB), UI elements that must ship with the CSS/HTML.


FAQ

What image formats can be converted to Base64?

Any binary format works: PNG, JPEG, GIF, SVG, WebP, BMP, TIFF, ICO. SVG is technically text, so you can often use it directly without Base64. All the tools support the common formats.

Does Base64 encoding compress my image?

No — Base64 increases file size by approximately 33%. Three bytes become four characters. It doesn’t compress or optimize the image — it just changes the representation from binary to text. If you need smaller files, compress the image first (lossy JPEG, optimized PNG), then Base64 encode the result.

What is the maximum image size I should Base64 encode?

There’s no hard limit, but the practical threshold is around 3-4 KB. Beyond that, the overhead and parsing cost of embedding the image directly in HTML/CSS outweighs the benefit of eliminating the HTTP request. For a 100 KB image, you’d be better served with a separate file request and browser caching.

How do I decode a Base64 image back to a file?

Use GoGood.dev Base64 to File Converter to download the original file, or decode programmatically:

Browser:

const base64String = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJ...';
const binaryString = atob(base64String);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
  bytes[i] = binaryString.charCodeAt(i);
}
const blob = new Blob([bytes], { type: 'image/png' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'image.png';
a.click();

Node.js:

const fs = require('fs');
const base64String = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJ...';
const buffer = Buffer.from(base64String, 'base64');
fs.writeFileSync('image.png', buffer);

What’s the best way to store images from user uploads?

Base64 in a database is usually a mistake. Better approaches: store the file in S3 or cloud storage and save the URL in your database, use a binary column if your database supports it, or use a file upload service like Cloudinary that handles resizing and optimization.


For quick conversion without writing code, use GoGood.dev Image to Base64 Converter. Drag and drop your image, choose between the raw Base64 string or the full data URI, and copy to clipboard.

For more on Base64: Base64 Encode and Decode Explained covers the encoding mechanics in detail, and When to Use Base64 (and When Not To) discusses the performance tradeoffs of embedding images in CSS and HTML.