Published: July 3, 2026
If you've ever used a document editor, spreadsheet app, or any app where pasting content from the clipboard is a primary interaction, you know the user expectation: pasting should feel instant.
Unfortunately, in many cases, web apps read more clipboard data than they need, which can make pasting content feel slower than it should, wastes CPU cycles, and uses memory for data the app never needs.
Selective format read addresses this performance issue by modifying the Async Clipboard API to better meet user expectations and provide what developers need—to only read the formats the app actually needs.
The problem: Read all data formats upfront
When a user copies from any app—for example, Excel, Google Docs, or Photoshop— the app usually writes several representations of the same data to the system clipboard: plain text, HTML, image, and sometimes custom formats. The web app that reads the data (when the user pastes from the clipboard) rarely needs all these representations. A spreadsheet editor might want HTML. A text editor might want to expose a "paste as plain text" command. A code editor might only ever want the text and nothing else.
Until now,
navigator.clipboard.read()
fetched every available representation of the data from the system
clipboard, ran sanitization (which can take time, especially with large HTML or
image payloads), and held the bytes in memory, even for the formats the app
would never use. The larger the unused payload, the longer the user had to wait,
and the more memory the tab consumed, right when paste responsiveness matters
most.
The solution: Only enumerate, then read on demand
From Chrome and Edge 149,
ClipboardItem
objects returned by the navigator.clipboard.read() method only describe
what is in the clipboard, instead of giving access to the data right away. The
actual bytes for a given format are read from the clipboard only when you call
ClipboardItem.getType(mimeType).
The API surface is unchanged. The same code you wrote yesterday still works
today, giving you immediate performance benefits:
// Enumerate the available MIME types.
// No payload is fetched yet.
const items = await navigator.clipboard.read();
for (const item of items) {
if (item.types.includes('text/html')) {
// Only read the HTML data.
// The data is fetched (and sanitized) here only.
const blob = await item.getType('text/html');
useThePastedHtml(await blob.text());
break;
}
// text/plain, image/png, or any other custom formats
// stored in the clipboard are never read.
}
Another performance benefit here is that caching is automatic. Calling
getType('text/html') twice on the same ClipboardItem reads from the system
clipboard only once and returns the cached Blobon the second call.
The benefits
Latency. The work that needed to happen when navigator.clipboard.read()
was called, such as copying bytes across processes, sanitizing HTML, or decoding
images, now only happens for the formats your app actually needs. Apps that only
read a single format get most of the saving. The larger the formats you skip,
the bigger the gain. HTML benefits most because HTML sanitization is expensive.
Memory. Previously, calling navigator.clipboard.read() when the clipboard
held a 50 MB image meant that 50 MB needed to be used in the web page's renderer
memory until the ClipboardItem was released, even if the app only needed the
text/plain representation of the data. Now, only the formats your app reads when
calling ClipboardItem.getType() use memory in the renderer process. For apps
where pasting is common, such as document editors, mail composers, or design
tools, this meaningfully reduces memory usage during paste, especially on
multi-tab sessions where several editors may be reading the clipboard in
parallel.
No opt-in. Every site on the web gets these benefits automatically. You don't need to migrate code or gate code behind feature detection logic.
One behavior change to be aware of
Reading the data later does introduce a slight change in behavior: a
ClipboardItem object is no longer a frozen snapshot of the clipboard at the
moment the call to navigator.clipboard.read()resolved.
When read() is called and returns a ClipboardItem, this item is only a
lazy handle to the data in the system clipboard.
If the contents of the clipboard
change between the call to read()and a later call to getType(), that call
will be rejected with an InvalidStateError. This is true even for a format you
previously read successfully on the same ClipboardItem.
// Read from the clipboard.
const items = await navigator.clipboard.read();
// Get the first ClipboardItem.
const item = items[0];
// Actually fetch the data now, which works fine.
const text = await item.getType('text/plain');
// The user writes something new to the clipboard
// by copying from another app, or your own code writes to
// the clipboard again.
await navigator.clipboard.writeText('something new');
// Fetching the data from the earlier ClipboardItem
// rejects with InvalidStateError, because the contents
// of the clipboard changed.
const html = await item.getType('text/html');
This happens because returning data that no longer reflects the clipboard would be confusing and lead to hard to debug issues otherwise.
In practice, the change is invisible to most code, because apps typically call
read() and getType() back-to-back inside the same paste handler. However,
you might want to watch for cases where you have code that holds onto a
ClipboardItem across async boundaries.
Here is an example where this change might become a problem: caching
ClipboardItem objects on window, displaying them in a clipboard-history UI,
or awaiting user interaction before calling getType(). To avoid issues with a
scenario like this:
- Wrap
getType()calls intry / catchblocks, and treatInvalidStateErroras a signal that the clipboard has moved on and the code should read again. - If you need to retain clipboard data, copy the
Blobinto your own structure as soon as yougetType()it. Don't treat theClipboardItemas long-term storage. - Use the
clipboardChangeevent to proactively invalidate stale handles.
Standards and browser support
Selective format read is a Clipboard APIs specification change driven by the Web Editing Working Group and the Microsoft Edge web platform team.
Safari also supports this behavior, and Firefox has indicated a positive standards position and intent to align.
A quiet, but meaningful performance and interoperability improvement for the Clipboard API, with Chromium now converging to the same model.