![Justin Lulejian](https://web.dev/images/authors/jlulejian.png) Justin Lulejian

<br />


Published: April 22, 2026

<br />

The communication between different extension components (background scripts, content scripts, popups)
has traditionally relied on JSON serialization. While
reliable, JSON has limitations.

We are excited to announce that starting in Chrome 148, extension developers can
opt-in to use the [structured clone
algorithm](https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)
for message serialization instead of JSON! This modernization lets you
send more complex data types between your extension contexts without manual
serialization workarounds.

## Why structured clone?

JSON serialization (via
[JSON.stringify](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
under the hood) is functional, but it sometimes requires developers to jump
through hoops when dealing with modern JavaScript types.

Here's a specific example you might've run into when developing an extension:

    // Sending a Map with JSON serialization
    const myMap = new Map([['id', 123]]);

    // Arrives as {} on the other side!
    chrome.runtime.sendMessage(myMap);

    // Workaround: Convert Map to an Array of entries before sending
    const message = Array.from(myMap.entries());
    chrome.runtime.sendMessage(message);

    // On the receiving side:
    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      const receivedMap = new Map(message);
    });

Some other situations where JSON fails that you might've had to workaround are
`Set`, `BigInt`, `NaN` and `Infinity`, `Date`, and `Error` Objects.

Using structured clone serialization means you can now send various objects that
were previously difficult or impossible to transmit over extension messaging.
For example, sending a `Map` object is now direct:

    // Sending a Map with Structured Clone
    const myMap = new Map([['id', 123]]);

    // Arrives as a Map on the other side!
    chrome.runtime.sendMessage(myMap);

    // On the receiving side:
    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      // message is already a Map instance!
      console.log(message.get('id')); // 123
    });

### More supported types

Structured clone supports a wide array of [other
types](https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types)
such as `File` and `Blob`.

## How to opt-in

To ensure backwards compatibility and prevent breaking existing extensions, this
feature is *opt-in* . You can enable it globally for your extension by adding a
single key to your `manifest.json`:

    {
      "name": "My Extension",
      "version": "1.0",
      "manifest_version": 3,
      "message_serialization": "structured_clone"
    }

If omitted, or on a Chrome version lower than 148, the browser defaults to its
current JSON-based implementation for the extension.

By supporting the structured clone algorithm, we are bringing the extension
messaging API closer to alignment with standard web platform capabilities
(similar to `postMessage` used in Web Workers and iframe communication), giving
you more flexibility and power.

## Interoperability and gotchas

While our structured clone serialization implementation supports many more types
than JSON, there are a few architectural assumptions and incompatibilities with
the implementation you should keep in mind.

### Unsupported types

Shared objects like
[`SharedArrayBuffer`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer)
and [transferring of
objects](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)
like `ArrayBuffer` are not supported with our implementation.
`SharedArrayBuffer` will fail to serialize or deserialize (depending on the
situation), and attempting to send a transferable object like `Uint8Array` will
send a copy instead.

### Extension to extension communication

We enforce matching serialization formats to ensure data integrity. Extensions
with mismatched serialization formats cannot communicate directly over
`runtime.sendMessage` or `runtime.connect`. For example, if extension A uses JSON
serialization and tries to message Extension B using structured clone, the
message will fail to send and the port will close (and vice versa).

### Web page communication

Web Pages using `externally_connectable` will automatically adapt to the target
extension's serialization format. If your extension uses structured clone, web
contexts sending messages using the `runtime` API will use structured clone (and
vice versa) automatically. This means the web site and extension must be in sync
on their expected serialization format to prevent serialization errors.

### Native messaging

Native messaging channels continue to always force JSON serialization.
Attempting to send structured-clone-only types (like a `BigInt`) to a native host
will fail before a message leaves your extension's context.

### toJSON() methods

If you use classes or objects with custom `toJSON()` methods to perform custom
serialization (for example, sanitizing data by removing passwords before sending
an object), be aware that structured clone *ignores* `toJSON()`. It copies
property values directly. If you rely on `toJSON()` for custom serialization, some
manual work might be required before sending. For example:

    class User {
      constructor(name, password) {
        this.name = name;
        this.password = password;
      }

      // This will be ignored by structured clone!
      toJSON() {
        return { name: this.name };
      }
    }

    const user = new User("Alice", "secret123");

    // JSON -> {"name":"Alice"}
    // Structured Clone -> { name: "Alice", password: "secret123" }

## Is JSON serialization going away?

No! Chrome is committed to supporting both serialization formats for the
foreseeable future.

## Share feedback

We hope this new capability unlocks smoother and more powerful workflows for
your extension development.

While we have created a test suite to validate functionality for our structured
clone implementation, the web platform has a massive variety of objects. Try out this new feature and
[report](https://issues.chromium.org/u/1/issues/new?component=1456110&template=1958178)
any bugs or edge cases you encounter! Your feedback will help us improve the
implementation for the entire community.