
File to Data URL Creator
Convert any file to a Base64 Data URL, encode text as a data URI, or decode a Data URL back to a downloadable file. 100% client-side.
Last reviewed: April 2026New to this tool? Click here for instructions
Drag & drop a file here
or browse to select - any file type
Convert text, images, audio, or arbitrary files to RFC 2397 data URIs using Base64 or percent-encoding, and decode existing data URIs back to downloadable files — entirely in your browser, with no upload step.
What This Tool Does
This tool converts arbitrary input — pasted text, dropped image files, audio clips, fonts, PDFs, or any file your file picker can reach — into a data URI conforming to RFC 2397. The resulting URI takes one of two shapes: data:<mime>;base64,<base64-payload> for binary content or text encoded into the base64 alphabet, or data:<mime>,<urlencoded-payload> for ASCII-compatible text encoded with percent-escaping. Either form is a complete, self-contained URL you can paste into HTML, CSS, JavaScript, or anywhere a URL is accepted.
The tool runs three workflows from the same interface. The File to Data URL panel reads any file you drop or browse to, inspects its MIME type from the file extension, base64-encodes the bytes, and emits the data URI in a copyable text field — including a size comparison that shows the encoding overhead in absolute bytes and percent. The Text to Data URL panel converts pasted text or markup using a MIME selector (plain, HTML, CSS, JavaScript, JSON, XML, SVG, CSV, Markdown) and offers a base64 toggle so you can compare encoding strategies for the same payload. The Data URL to File panel reverses the process: paste any data URI and the tool parses the header, decodes the payload (base64 or percent), reconstructs the original bytes, and offers a download with the correct file extension inferred from the MIME type.
Every operation happens in the browser. The FileReader API reads dropped files into memory; btoa and atob handle base64 encoding and decoding; encodeURIComponent and decodeURIComponent handle percent-encoding; the Blob and URL APIs construct downloadable file references for decoded payloads. No file or text is sent to any server, no analytics event captures the content of your input, and the page loads no third-party scripts that touch the payload. The only network traffic generated by your session is the initial page load and consent-gated advertising scripts.
How to Use It: Three Workflows
Pick the workflow that matches your starting point. All three produce or consume the same RFC 2397 data URI format — the choice is only about whether your source material is a file, a text payload, or an existing data URI you want to decompose.
Workflow 1: Convert a File to a Data URI
Click the File to Data URL tab. Drag a file from your file manager onto the drop zone, or click the browse link to open a file picker. Any file type works: PNG, JPEG, WebP, SVG, MP3, WAV, PDF, WOFF2, even ZIP archives. The tool reads the file into memory with FileReader, determines the MIME type from the file extension, base64-encodes the bytes, and renders the complete data URI in the output panel. A size comparison strip shows the original file size, the encoded data URI size, and the overhead percentage — typically 33 percent for base64 of any binary payload, plus a few bytes for the header. Click Copy to put the full URI on your clipboard, or Copy Header Only to grab just the data:image/png;base64, prefix if you need to construct a custom payload programmatically.
Workflow 2: Convert Text to a Data URI
Click the Text to Data URL tab. Paste or type your content into the left textarea — HTML, SVG markup, CSS rules, JSON, plain prose, anything text-shaped. Pick a MIME type from the dropdown (default is text/plain; choose image/svg+xml for SVG markup, text/html for HTML fragments). Toggle the Base64 encode checkbox to choose the encoding strategy: leave it unchecked for percent-encoding (smaller output for ASCII-heavy text) or check it for base64 (necessary for any content containing literal URL-reserved characters or for cross-context portability). The data URI updates live in the right pane as you type or change settings, with a size comparison showing whether your chosen encoding is more or less efficient than the alternative.
Workflow 3: Decode an Existing Data URI Back to a File
Click the Data URL to File tab. Paste a complete data URI starting with data: into the textarea — the tool accepts both base64 and percent-encoded forms. Click Decode. The header is parsed to extract the MIME type and encoding flag; the payload is decoded with atob (for base64) or decodeURIComponent (for percent-encoding); the resulting bytes are wrapped in a Blob with the correct MIME type. If the payload is an image type, a preview renders directly. Click Download File to save the decoded bytes to disk with a file extension inferred from the MIME type — image/png becomes decoded.png, application/pdf becomes decoded.pdf, and so on.
Worked Example: 1x1 Transparent PNG as a Data URI
The canonical example of a data URI is the smallest possible PNG image: a single transparent pixel. The raw PNG file is 68 bytes — eight bytes of PNG signature, plus IHDR, IDAT, and IEND chunks with their CRCs. Base64-encoded, it becomes the following 96-character data URI:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=
Encoding Math: Why Base64 Adds 33 Percent
The base64 alphabet maps three input bytes (24 bits) to four output characters (24 bits across four 6-bit symbols). The encoded output is therefore always 4/3 the length of the input, plus padding — a 33.3 percent size increase. For the 68-byte PNG, base64 yields 92 characters (with a single = padding character), to which the tool prepends the 22-character header data:image/png;base64,. Total URI length: 114 characters, or about 168 percent of the original 68 bytes when counted as UTF-8 octets. The "overhead percentage" reported in the size-compare strip is computed against the original payload, so this example would show roughly +68 percent including the header — the longer your payload, the closer the overhead converges on the pure 33 percent base64 cost.
Why Use It Despite the Overhead
For a 68-byte transparent PNG used as a CSS placeholder for lazy-loaded images, the data URI eliminates one HTTP request entirely. On a cold connection, that request would consume roughly 200 milliseconds of round-trip time — the same amount of time it takes a modern CPU to base64-decode 100 KB of payload several thousand times over. The 33 percent size penalty buys you a guaranteed zero-latency render. The break-even point sits around 4 KB: smaller payloads almost always benefit from inlining, larger payloads almost never do because the cumulative HTML or CSS bloat starts costing more bandwidth than a separate cached fetch.
Verifying the Example
Paste the data URI above into the Data URL to File panel and click Decode. The tool reports MIME image/png and decoded size of 68 bytes, renders the transparent preview (visible only as a 1x1 square against the panel background), and offers a download as decoded.png. Open the downloaded file in any image viewer to confirm it is a valid PNG with one pixel of full alpha transparency.
Common Use Cases: When Data URIs Are the Right Tool
CSS Background Images for Small Decorative Assets
The most common production use of data URIs is CSS background-image: inline a 200-byte icon directly into a stylesheet to eliminate one HTTP request and guarantee the icon paints in the same layout pass as the rule that references it. background-image: url("data:image/svg+xml,%3Csvg ... %3E"); works in every modern browser and across every CSS context — pseudo-elements, transitions, and even content on ::before. SVG payloads percent-encoded rather than base64-encoded are typically 25 to 35 percent smaller, which matters when your stylesheet is part of the critical render path.
Email Signature Logos and HTML Email Templates
Email clients vary wildly in how they handle external image references. Gmail proxies them through Google's image servers, Outlook for Windows often blocks them by default, and many corporate email scanners strip them entirely. A data URI embedded in <img src="data:image/png;base64,..."> bypasses every one of those mechanisms because the image data is part of the message body, not an external resource. The same logic applies to HTML newsletter templates that need to render in clients you cannot control.
Webpack and Bundler file-loader Thresholds
Webpack's url-loader and Vite's asset import handling both honor a configurable size threshold: assets smaller than the threshold are inlined as base64 data URIs in the JavaScript or CSS bundle; larger assets are emitted as separate files with content-hashed names. The default thresholds (8 KB for Webpack url-loader, 4 KB for Vite) reflect the same break-even calculus described above — small enough that the bandwidth cost is negligible, large enough that the HTTP request elimination matters. Build tools generate data URIs automatically; this tool is useful for manually inspecting or constructing equivalents when debugging build output or generating one-off inline assets.
Single-File HTML Demos and CodePen Exports
CodePen's "Export Pen" feature produces a single HTML file with all CSS and JavaScript inlined. For pens that include images, exporting requires every image dependency to live inside the HTML — data URIs are the standard mechanism. The same pattern applies to any one-page demo, bug-reproduction case, or self-contained tutorial artifact where distribution as a single file matters more than runtime performance.
Inline Favicons
The <link rel="icon" href="data:image/x-icon;base64,..."> pattern embeds a favicon directly in the HTML head, eliminating the separate /favicon.ico?v=2 request that every browser fires automatically. For high-traffic sites this can shave 1 to 2 percent off the total request count. Combined with a data URI for the apple-touch-icon, you can deliver a fully-decorated tab and home-screen icon set with zero additional network round-trips.
Edge Cases, Browser Quirks, and Performance Cliffs
Data URIs look uniform on paper but exhibit several non-obvious failure modes in real browsers, security policies, and performance audits. The list below covers the cases most likely to bite production code.
Size Limits Vary Drastically Across Browsers
The RFC 2397 specification places no upper bound on data URI length. Browsers do — and inconsistently. Internet Explorer 8 capped data URIs in HTML at 32 KB; Edge inherited a 32 KB limit on data URIs in the address bar but allowed multi-megabyte payloads in HTML and CSS. Chrome and Firefox accept multi-megabyte data URIs but degrade in measurable ways above roughly 100 KB: background-image reflows can stall paint by 50 ms or more on mid-range mobile hardware, and CSSOM operations on large data URI strings exhibit superlinear time complexity in some Webkit versions. The practical guidance: anything under 4 KB is safe everywhere, 4 to 64 KB is fine for most contexts but worth measuring, above 100 KB switch to an external fetch.
Content Security Policy default-src 'self' Blocks Data URIs
A CSP with default-src 'self' and no explicit img-src directive blocks every data URI on the page — images, fonts, frames, the lot. The fix is to add data: to the relevant directive: img-src 'self' data:; permits data-URI images, font-src 'self' data:; permits data-URI fonts, and so on. Be deliberate about which directives you relax. Granting script-src data: opens a meaningful XSS vector (a data URI containing a script tag executes in your origin's context); granting default-src data: opens that vector for every directive type at once. The safest baseline is to enumerate only the directives you actually need.
SVG: Base64 Versus Gzip-Encoded UTF-8
SVG is text. Base64-encoding it inflates the payload by 33 percent before gzip; percent-encoding the same SVG inflates it by 5 to 15 percent before gzip. After gzip compression on the wire, the gap shrinks but rarely disappears — percent-encoded SVG remains roughly 10 to 20 percent smaller than base64-encoded SVG over HTTPS with content-encoding gzip or brotli. For inline SVG in CSS, percent-encoding is the right default unless you have a specific reason (cross-context portability, parsing simplicity) to prefer base64.
Browser Cache Misses on Data URIs
Data URIs are not HTTP resources, so they cannot be cached separately. The data lives in the document or stylesheet that references it; cache hits and misses are tied to that container's caching headers, not the data URI's. A 50 KB data URI in your CSS file means every fresh CSS load downloads 50 KB of payload, even if the same image appears on every page. An external image with Cache-Control: max-age=31536000, immutable is fetched once and reused across the entire site for a year. For any asset reused across more than two or three pages, an external file outperforms a data URI on warm loads.
XSS Risk When Constructing Data URIs from User Input
A data URI with text/html or text/javascript MIME type, navigated to via window.location or <iframe src>, executes its payload in some browser contexts. Constructing data URIs from user-controlled content is therefore a meaningful XSS vector. Modern browsers mitigate the threat by assigning navigated data URIs an opaque origin and, in Chrome's case, blocking top-level navigation to data URLs entirely — but the mitigations are imperfect and version-dependent. Anyone building a tool that converts user input to data URIs should strictly validate the MIME type, refuse text/html and application/javascript for any user-controlled payload, and HTML-escape any output rendered alongside the URI.
Behind the Scenes: RFC 2397, MIME Registry, and Base64 Alphabets
RFC 2397 Grammar
The data URI scheme was specified by Larry Masinter in RFC 2397 in August 1998. The grammar is compact:
dataurl := "data:" [ mediatype ] [ ";base64" ] "," data
mediatype := [ type "/" subtype ] *( ";" parameter )
data := *urlchar
parameter := attribute "=" value
If mediatype is omitted, the default is text/plain;charset=US-ASCII. If the ;base64 flag is present, the data segment is base64-encoded; otherwise the data is URL-encoded (percent-escaping) text. Multiple parameters can be chained after the MIME type: data:text/plain;charset=utf-8;foo=bar,Hello%20world is valid.
The IANA MIME Type Registry
MIME types are registered with IANA and documented at iana.org/assignments/media-types. The registry has over 1500 entries split across nine top-level types (application, audio, font, image, message, model, multipart, text, video). For data URIs, the most commonly seen are image/png, image/jpeg, image/svg+xml, image/webp, text/html, text/css, text/javascript, application/json, application/pdf, and font/woff2. Vendor-specific or experimental types use the x- prefix (image/x-icon for legacy favicons, for instance). The tool's MIME dropdown covers the common text-shaped types directly; for file uploads the MIME is inferred from the file extension by FileReader.
The Base64 Alphabet (RFC 4648)
Base64 encoding is specified by RFC 4648. The alphabet maps integer values 0–63 to printable ASCII characters: 0–25 are uppercase A–Z, 26–51 are lowercase a–z, 52–61 are digits 0–9, 62 is the plus sign, 63 is the forward slash. The padding character is the equals sign, appended once or twice when the input length is not a multiple of three bytes. A variant alphabet called base64url swaps the plus and forward slash for hyphen and underscore to avoid collision with URL syntax — but standard data URIs use the original RFC 4648 alphabet because the comma-separated structure of the data URI sidesteps the URL-syntax conflict.
Why data: URIs Don't Work in Cross-Origin Download Links
The HTML <a download> attribute triggers a download instead of a navigation. For cross-origin URLs, the spec requires the response to include a Content-Disposition: attachment header before the download attribute applies; otherwise the browser treats the link as a normal navigation. Data URIs have no HTTP response and therefore no Content-Disposition header, which means <a href="data:application/pdf;base64,..." download> works in some browsers but not others, and behaves inconsistently across versions of the same browser. The reliable cross-browser pattern for forcing a download of binary content is to construct a Blob, get a blob URL via URL.createObjectURL, and use that as the href — exactly the pattern this tool's decode workflow follows.
Data URI Versus Blob URL
A data URI embeds the payload in the URL string. A blob URL references a payload stored separately in the browser's memory. The blob URL takes the form blob:https://thisdevtool.com/550e8400-e29b-41d4-a716-446655440000 — opaque, lifecycle-bound to the document that created it, revocable via URL.revokeObjectURL. Blob URLs scale to arbitrary payload sizes (a 100 MB video as a blob URL costs zero document bytes); data URIs do not. Blob URLs can be released from memory explicitly; data URIs persist for as long as the referencing document persists. For runtime-generated content like canvas exports or fetched binary payloads, blob URLs are almost always the better primitive. For build-time inlining of small static assets, data URIs remain unbeaten because they require no JavaScript scaffolding.
Comparison: Data URI vs Blob URL vs HTTP URL
Three URL schemes dominate web asset delivery. Each makes a different set of tradeoffs across size, cacheability, lifecycle, and ergonomics — and each is the right choice for a specific operating range.
| Property | Data URI (data:) | Blob URL (blob:) | HTTP URL (https://) |
|---|---|---|---|
| Payload location | Embedded in URL string | In-memory Blob, referenced by handle | On a remote server |
| Document size impact | Adds payload + 33% to HTML/CSS | Adds only the short handle string | Adds only the URL string |
| HTTP cache behavior | Not cacheable (no HTTP request) | Not cacheable (in-memory only) | Fully cacheable via standard headers |
| Maximum practical size | ~64 KB before performance degrades | Bounded by available device RAM | No practical limit |
| Lifecycle | Persists with referencing document | Revocable via URL.revokeObjectURL; auto-cleaned on document unload | Persists on the origin server |
| Cross-document sharing | Possible via copy-paste; no automatic sharing | Scoped to creating document; cannot cross origins | Fully shareable across documents and origins |
| Best for | Small static assets (under 4 KB), build-time inlining, single-file demos, email logos | Runtime-generated content: canvas exports, fetched binary, file picker uploads | Anything large, anything reused across pages, anything you want browsers to cache |
| CSP directive needed | data: in img-src, font-src, etc. |
blob: in img-src, media-src, etc. |
Standard host whitelisting |
The three are not mutually exclusive — many production stacks use all three within the same page. A favicon as a data URI in the head, application code as HTTP-fetched JavaScript bundles, user-uploaded images previewed as blob URLs before submission, and final stored assets served from an HTTP CDN. The right question is never "data URI or blob URL or HTTP" but rather "for this specific asset, at this specific size, with this specific reuse pattern, which one minimizes total latency and bandwidth across the user's typical journey."
Frequently Asked Questions
What's the maximum size of a data URI?
The RFC 2397 specification places no upper bound on data URI length, but every browser engine and consuming context applies its own practical limit. Microsoft Edge historically capped data URIs in the address bar at 32 KB, and the legacy Trident engine enforced a hard 4 MB ceiling in HTML attributes. Chrome, Firefox, and modern Edge support data URIs in the multi-megabyte range for image src and CSS background-image, but performance degrades sharply above roughly 100 KB because the parser must base64-decode the payload on every layout pass. CSS-side limits are even tighter in practice: CSSOM serialization on large background-image data URIs can stall paint by 50 ms or more on mid-range mobile hardware.
Should I use base64 or percent-encoding?
Use base64 for binary payloads (PNG, JPEG, WebP, audio, fonts, PDFs) — there is no alternative because percent-encoding only escapes URL-unsafe ASCII characters and leaves arbitrary binary bytes unrepresented. Use percent-encoding for text payloads where the source character set is already ASCII-compatible, especially inline SVG: percent-encoded SVG is typically 25 to 35 percent smaller than its base64 equivalent and renders identically. The base64 alphabet adds a fixed 33 percent overhead because three bytes of input expand to four characters of output. Percent-encoding's overhead is proportional to the number of escaped characters — for ASCII-heavy text it can be under 5 percent.
Why does my data URI break in Safari?
Safari is stricter than Chrome and Firefox about MIME type and encoding declaration in data URIs. The most common failures are: missing or incorrect MIME type (Safari refuses to render image/svg+xml content sent as text/plain), unencoded characters inside percent-encoded payloads (literal #, ?, or % bytes inside the data segment must themselves be percent-escaped to %23, %3F, and %25), and reliance on default character set assumptions (Safari does not assume UTF-8 for text/* MIME types — always include ;charset=utf-8 explicitly when the payload contains non-ASCII characters). Safari also enforces strict CSP rules on data URIs in img-src and font-src directives, where Chrome may permit broader behavior under a default policy.
Are data URIs cached by the browser?
No — data URIs bypass the HTTP cache entirely because there is no HTTP request to cache. The payload is part of the document or stylesheet that references it, so the browser parses and decodes the data URI on every page load and, for CSS, potentially on every layout recalculation. This is the central tradeoff with data URIs: you save one HTTP round trip, but you pay the decode cost repeatedly and you lose the ability for the browser to share that asset across pages or visits. For assets reused across multiple pages, an external HTTP-cached file with a long max-age and immutable directive is almost always faster on warm loads.
Can a data URI run JavaScript?
Historically yes: a data URI with MIME type text/html or application/javascript loaded via window.location or navigation could execute script in the document's origin context. This was a significant XSS vector for years. Modern browsers neutralize the threat by giving navigated data URIs an opaque origin, which disconnects them from the parent document's cookies, storage, and same-origin XHR targets. Chrome additionally blocks top-level navigation to data URLs entirely. A data URI in a <script src> or <iframe src> can still execute JavaScript, but it cannot read or write the parent document's state — treat any developer tool or production system that constructs data URIs from user input as potentially exploitable and validate the MIME type strictly.
How do I embed an image without uploading it?
Drag the image file into the drop zone in the File to Data URL panel above. The tool reads the file with the browser's FileReader API entirely in memory — no network request, no upload to a server — and emits a base64-encoded data URI you can paste directly into an HTML img tag, CSS background-image property, or email signature. For a single-file HTML page that displays a logo without requiring any external assets, this is the standard workflow: convert the image to a data URI once, paste it into your src or url() reference, and the HTML file is fully self-contained. Email clients in particular benefit because most strip external image references but render inline data URIs in their entirety.
Why does Lighthouse penalize large data URIs?
Lighthouse flags large data URIs under two distinct audits. First, the Largest Contentful Paint (LCP) audit penalizes any render-blocking resource above 14 KB compressed, because a single round-trip TCP slow-start window cannot deliver more than 14 KB of payload — inlining a 50 KB image into the HTML head delays LCP by approximately one extra round-trip time on a cold connection. Second, the Cache Policy audit recognizes that data URIs are non-cacheable and treats every byte as repeat-download cost. The general guidance: inline only assets smaller than roughly 4 KB, used on every page, and not subject to independent change cycles. Anything larger or anything reused across multiple pages performs better as a separately fetched, HTTP-cached file.
What's the difference between a data URI and a blob URL?
A data URI embeds the entire payload inside the URL string itself — the data lives in the document's serialized HTML or CSS source. A blob URL is a reference handle of the form blob:https://origin/uuid that points to a Blob object held in the browser's memory; the URL itself contains no payload, only an opaque identifier. Practical consequences: blob URLs handle arbitrarily large files without inflating document size (a 100 MB video as a blob URL costs zero document bytes; as a base64 data URI it costs 133 MB of HTML), blob URLs can be revoked with URL.revokeObjectURL to free memory explicitly, and blob URLs are scoped to the document that created them — they cannot be shared across origins or persisted across page loads. Use data URIs for inline, self-contained, small payloads. Use blob URLs for runtime-generated content like canvas exports, fetched binary data, or large File objects from input elements.