Bhinish Dhiman

How to convert an image to a base64 data URI, and when not to

Drop the file into the data URI converter, read the Inlined size, and copy the Data URI, CSS or HTML snippet. Base64 writes every 3 bytes as 4 characters, so the file grows by a third before the data: prefix is added. Inline only small files: the tool approves anything up to 4,096 bytes and, above that, says to use a normal file reference, because an inlined copy is re-downloaded with every document or stylesheet that embeds it.

Turning a file into a data URI always succeeds. That is the trouble with it: nothing in the conversion warns you that pasting a 200 KB photograph into a stylesheet has just made every page that loads it slower. The encoding takes seconds. The decision about whether to use it is the part worth getting right.

Two terms first

A data URI is a URI that carries a file’s bytes inside itself instead of pointing at a file somewhere else. It is written as data:, the file’s MIME type, ;base64, and then the encoded bytes, so a PNG starts data:image/png;base64,.

Base64 is the encoding that makes binary safe to put in text. It takes the file three bytes at a time, splits those 24 bits into four groups of 6, and writes each group as one character from an alphabet of 64 (2⁶ = 64). Three bytes in, four characters out, whatever the content.

Converting the file

  1. Open the data URI converter and press “Choose a file”, or drop the file anywhere on the page. It takes anything: images, SVG, fonts. SVG markup pasted outside a text box works too, and “Try a sample” loads a small icon.
  2. Read the three figures under “Result”: “File” (the original), “Inlined” (the full data URI, prefix included) and “Overhead” (the difference as a percentage).
  3. Read the verdict with them. It is either “Reasonable to inline.” or “Use a normal file reference instead.”, followed by the reasons; the second is shown as a warning.
  4. Under “Copy as”, pick “Data URI” (the raw string), “CSS” (a background-image declaration with the URI in quotes, since base64 can contain a slash) or “HTML” (an <img> tag for images, a download link for anything else), then press the copy button under it. Each of the three boxes below also has its own copy link, and the bar at the bottom can download the chosen one as a .txt file.

The HTML snippet writes alt="", which tells screen readers the image is decorative. If the image carries meaning, replace it with a description before you paste it in.

Where the extra third goes

The 4:3 ratio is fixed, so the base64 for any file is predictable: four characters for every three bytes, rounded up to a whole group of four. The tool’s “Inlined” figure also counts the prefix, which is why its overhead reads a point or so above 33% on small files: data:image/png;base64, is 22 characters on its own.

File Bytes Base64 alone Full data URI Overhead shown What the tool says
PNG icon 3,072 4,096 4,118 +34% Reasonable to inline
SVG icon 3,072 4,096 4,122 +34% Reasonable to inline
PNG, one byte past the line 4,097 5,464 5,486 +34% Use a normal file reference instead
JPEG photograph 204,800 273,068 273,091 +33% Use a normal file reference instead, with three reasons

Each row is arithmetic: 4 × ⌈3,072 ÷ 3⌉ = 4,096, and 4,096 + 22 = 4,118. The SVG prefix, data:image/svg+xml;base64,, is 26 characters; the JPEG one is 23.

Server compression claws some of the third back in transit, but less than you might hope, because base64 scrambles the repeated byte patterns a compressor depends on.

The line at 4,096 bytes, and what crossing it costs

The verdict is decided by the size of the original file. Up to 4,096 bytes, the tool approves inlining: one fewer request, nothing to manage in a cache. At 4,097 bytes it switches to “Use a normal file reference instead”, and the reasons pile up as the file grows.

  • Caching, for every file over the line. An external file is fetched once and reused on every page. An inlined one travels inside its host, so it is downloaded again with every document or stylesheet that embeds it.
  • Responsive images, for images over the line. A data URI has no URL for the browser to negotiate over, so you lose srcset, lazy loading and any image optimisation a CDN would have applied. A font over the line gets the caching warning but not this one.
  • Render-blocking, past 32,768 bytes (8 × 4,096). In a stylesheet the base64 has to arrive before the page can render, and one unrelated CSS edit invalidates the cached copy of every asset embedded alongside it.

The 200 KB photograph in the table hits all three. The tool’s own sentence for it reads “At 200 KB this becomes roughly 267 KB inlined”, and that 267 KB rides along with the stylesheet on every visit where the stylesheet is not already cached.

When a data URI is the right call

Small, used in one place, and self-contained: a single icon inside an inline style block is the textbook case. Make the file as small as it can be before you encode it, because every 3 bytes saved removes 4 characters from the result. An SVG can go through the SVG optimiser first, and a PNG through the image compressor, which rewrites it without changing a pixel.

The data URI converter The base64 command A plain online encoder
File leaves your machine No No Depends on the service
data: prefix and MIME type Written for you You add them Varies
Size shown with the prefix Yes, as “Inlined” No Varies
Advice on whether to inline Yes, with reasons No Rarely

Other ways to do it

On the command line, the base64 tool does the encoding:

base64 -i icon.png        # macOS
base64 -w0 icon.png       # GNU/Linux

Its output is the bare base64 string. To use it as a data URI, put data:image/png;base64, in front, with the MIME type that matches the file; if the type is wrong the file may not render: browsers guess some image types from their bytes, but an SVG must be labelled image/svg+xml.

Checking that nothing was uploaded

The file is read into memory in your browser and encoded there, which also means there is no size limit beyond your own memory. To confirm, open your browser’s developer tools on the Network tab before dropping a file in: the encode adds no request.

Make the conversion, and the decision, in the data URI converter. If the verdict says not to inline, shrinking the file with the image compressor and serving it normally is usually the better trade.