events.UrlFilter - Mozilla

events.UrlFilter
================

Describes various criteria for filtering URLs. If all of the criteria specified in the filter's properties match the URL, then the filter matches. Filters are often provided to API methods in an Array of UrlFilters. For example, webNavigation listeners can be added with a filter which is an object with a single `url` property that is an Array of UrlFilters, e.g. `{url:[UrlFilter, UrlFilter, …]}`. If any filter within the Array of UrlFilters matches, then it is considered a match for the Array. Effectively, the criteria specified within a single filter are AND'ed together, while all of the individual filters within an Array are OR'ed.

All criteria are case sensitive.

Type
----

Values of this type are objects. They contain the following properties:

However, note that these last two patterns will not match the last component of the hostname, because no implicit dot is added at the end of the hostname. So for example, `"org."` will match `https://borg.com` but not `https://example.org`. To match these patterns, use `hostSuffix`.

`hostContains` Optional

`string`. Matches if the hostname of the URL (without protocol or port – see `schemes` and `ports`) contains the given string.

* To test whether a hostname component starts with "foo", use `".foo"`. This matches `www.foobar.com` and `foo.com`, because an implicit dot is added at the beginning of the hostname.
* To test whether a hostname component ends with "foo", use `"foo."`.
* To test whether a hostname component exactly matches "foo", use `".foo."`.

`hostEquals` Optional

`string`. Matches if the hostname of the URL is equal to a specified string.

* Example: `"www.example.com"` matches `http://www.example.com` and `https://www.example.com/`, but not `http://example.com/`.

`hostPrefix` Optional

`string`. Matches if the hostname of the URL starts with a specified string.

`hostSuffix` Optional

`string`. Matches if the hostname of the URL ends with a specified string.

* Example: `".example.com"` matches `http://www.example.com/`, but not `http://example.com/`.
* Example: `"example.com"` matches `http://www.example.com/`, and `http://fakeexample.com/`.

`pathContains` Optional

`string`. Matches if the path segment of the URL contains a specified string.

`pathEquals` Optional

`string`. Matches if the path segment of the URL is equal to a specified string.

`pathPrefix` Optional

`string`. Matches if the path segment of the URL starts with a specified string.

`pathSuffix` Optional

`string`. Matches if the path segment of the URL ends with a specified string.

`queryContains` Optional

`string`. Matches if the query segment of the URL contains a specified string.

`queryEquals` Optional

`string`. Matches if the query segment of the URL is equal to a specified string.

`queryPrefix` Optional

`string`. Matches if the query segment of the URL starts with a specified string.

`querySuffix` Optional

`string`. Matches if the query segment of the URL ends with a specified string.

`urlContains` Optional

`string`. Matches if the URL (without fragment identifier) contains a specified string. Port numbers are stripped from the URL if they match the default port number.

`urlEquals` Optional

`string`. Matches if the URL (without fragment identifier) is equal to a specified string. Port numbers are stripped from the URL if they match the default port number.

`urlMatches` Optional

`string`. Matches if the URL (without fragment identifier) matches a specified regular expression. Port numbers are stripped from the URL if they match the default port number.

* For example: `urlMatches: "^[^:]*:(?://)?(?:[^/]*\\.)?mozilla\\.org/.*$"` matches `https://mozilla.org/`, `https://developer.mozilla.org/`, but not `https://developer.fakemozilla.org/`.

`originAndPathMatches` Optional

`string`. Matches if the URL without query segment and fragment identifier matches a specified regular expression. Port numbers are stripped from the URL if they match the default port number.

`urlPrefix` Optional

`string`. Matches if the URL (without fragment identifier) starts with a specified string. Port numbers are stripped from the URL if they match the default port number.

* Example: `"https://developer"` matches `https://developer.mozilla.org/` and `https://developers.facebook.com/`.

`urlSuffix` Optional

`string`. Matches if the URL (without fragment identifier) ends with a specified string. Port numbers are stripped from the URL if they match the default port number. Note that an implicit forward slash "/" is added after the host, so `"com/"` matches `https://example.com`, but `"com"` does not.

`schemes` Optional

`array` of `string`. Matches if the scheme of the URL is equal to any of the schemes specified in the array. Because schemes are always converted to lowercase, this should always be given in lowercase or it will never match.

* Example: `["https"]` will match only HTTPS URLs.

`ports` Optional

`array` of (`integer` or (`array` of `integer`)). An array which may contain integers and arrays of integers. Integers are interpreted as port numbers, while arrays of integers are interpreted as port ranges. Matches if the port of the URL matches any port number or is contained in any ranges.

* For example: `[80, 443, [1000, 1200]]` matches all requests on ports 80, 443, and in the range 1000-1200.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

**Note:** This API is based on Chromium's `chrome.events` API. This documentation is derived from `events.json` in the Chromium code.


events.Event - Mozilla

events.Event
============

An object which allows the addition and removal of listeners for a browser event.

Type
----

Values of this type are objects.

Methods
-------

`events.Event.addListener()`

Registers an event listener to an event.

`events.Event.removeListener()`

Deregisters an event listener from an event.

`events.Event.hasListener()`

Tests registration status of a listener.

`events.Event.hasListeners()`

Tests whether any listeners are registered to the event.

`events.Event.addRules()`

Registers rules to handle events.

`events.Event.getRules()`

Returns currently registered rules.

`events.Event.removeRules()`

Unregisters currently registered rules.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

**Note:** This API is based on Chromium's `chrome.events` API. This documentation is derived from `events.json` in the Chromium code.


events.Rule - Mozilla

events.Rule
===========

Description of a declarative rule for handling events.

Type
----

Values of this type are objects. They contain the following properties:

`id` Optional

`string`. Optional identifier that allows referencing this rule.

`tags` Optional

`array` of `string`. Tags can be used to annotate rules and perform operations on sets of rules.

`conditions`

`array` of `any`. List of conditions that can trigger the actions.

`actions`

`array` of `any`. List of actions that are triggered if one of the conditions is fulfilled.

`priority` Optional

`integer`. Optional priority of this rule. Defaults to 100.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

**Note:** This API is based on Chromium's `chrome.events` API. This documentation is derived from `events.json` in the Chromium code.


Notifications - Mozilla

Notifications
=============

Notifications allow you to communicate information about your extension or its content using the underlying operating system's notification service.

![Click notification in the top right corner of the browser window.](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Notifications/notify-shadowed.png)

Notifications can include a call to action for the user, and your add-on can listen for the user clicking the notification or the notification closing.

Specifying notifications
------------------------

You manage notifications programmatically, using the `notifications` API. To use this API you must request the `notifications` permission in your manifest.json:

```json
"permissions": ["notifications"]
```

You then use `notifications.create` to create your notifications, as in this example from notify-link-clicks-i18n:

```js
const title = browser.i18n.getMessage("notificationTitle");
const content = browser.i18n.getMessage("notificationContent", message.url);
browser.notifications.create({
  type: "basic",
  iconUrl: browser.extension.getURL("icons/link-48.png"),
  title,
  message: content,
});
```

This code creates a notification with an icon, title, and message.

If the notification includes a call to action, you can listen for the user clicking the notification to call the function to handle the action:

```js
browser.notifications.onClicked.addListener(handleClick);
```

If you are issuing calls to action through notifications, you will also want to define the optional notification `id`, so you can figure out which call to action the user has selected.

Icons
-----

For details on how to create icons to use with your notification, see Iconography in the Acorn Design System documentation.

Examples
--------

The webextensions-examples repository on GitHub includes the notify-link-clicks-i18n example which implements notifications.


Context menu items - Mozilla

Context menu items
==================

This user interface option adds one or more items to a browser context menu. This is the menu available when a user right-clicks on a web page. Tabs and bookmarks can also have context menus, available through the `menus` API.

![Example of content menu items added by a WebExtension, from the context-menu-demo example](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items/context_menu_example.png)

You use this option to expose features relevant to specific browser or web page contexts. For example, you can show features to open a graphic editor when the user clicks on an image or offer a feature to save page content when part of a page is selected. You can add plain menu items, checkbox items, radio button groups, and separators to menus. Once a context menu item has been added using `menus.create` it's displayed in all browser tabs, but you can hide it by removing it with `menus.remove`.

The full list of supported contexts is available at `menus.ContextType` and includes contexts outside of a web page, such as bookmark items in the browser UI. For example, the "Open bookmark in Container Tab" extension adds a menu item that allows the user to open a bookmark URL in a new container tab.

![A context menu with "open in new container tab" submenu highlighted. The submenu shows personal, work, banking, shopping, and Facebook contextual identities. There is an option at the top of the submenu to select no container.](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items/extension_context_menu.png)

You can also override the context menus displayed in extension pages, such as custom sidebars and popups, to use either the tab or bookmark context menus instead of the default context menu, with `menus.overrideContext`. This is a helpful method when your extension provides a custom presentation of tabs or bookmarks. The menu automatically includes menu items for any other extensions that have defined tab or bookmark context menu items. You can choose whether to include the default context menu items. Hiding the default items gives the extension complete control over the items displayed in the rendered native context menu, as shown in the image below for the Tree Style Tab extension.

![A tab context menu displayed for a tab item in the sidebar of the Tree Style Tab extension. The menu shows custom tab actions, a menu item for the extension, and a menu item for the Simple Tab Group extension.](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items/custom_sidebar_tab_menu.png)

Specifying context menu items
-----------------------------

You manage context menu items programmatically, using the `contextMenus` API. However, you need to request the `contextMenus` permission in your manifest.json to be able to take advantage of the API.

```json
"permissions": ["contextMenus"]
```

You can then add (and update or delete) the context menu items in your extension's background script. To create a menu item you specify an id, its title, and the context menus it should appear on:

```js
browser.contextMenus.create(
  {
    id: "log-selection",
    title: browser.i18n.getMessage("contextMenuItemSelectionLogger"),
    contexts: ["selection"],
  },
  onCreated,
);
```

Your extension then listens for clicks on the menu items. The passed information about the item clicked, the context where the click happened, and details of the tab where the click took place can then be used to invoke the appropriate extension functionality.

```js
browser.contextMenus.onClicked.addListener((info, tab) => {
  switch (info.menuItemId) {
    case "log-selection":
      console.log(info.selectionText);
      break;
    // …
  }
});
```

Icons
-----

For details on how to create icons to use with your context menu, see Iconography in the Acorn Design System documentation.

Examples
--------

The webextensions-examples repository on GitHub contains two examples of extensions that implement context menu items:

* menu-demo adds several items to the browser's context menu.
* context-menu-copy-link-with-types adds a context menu item to links that copies the link URL to the clipboard, as plain text and rich HTML.


Sidebars - Mozilla

Sidebars
========

A sidebar is a pane that is displayed at the side of the browser window, next to the web page. This page describes sidebars, specifying them, designing them, and examples of use.

The browser provides a UI that enables the user to select a sidebar to display. For example, Firefox has the "View" > "Sidebar" menu. Each browser window can display its own sidebar, which is displayed on every tab in the window.

The browser may include a number of built-in sidebars. For example, Firefox includes a sidebar for interacting with bookmarks:

![Annotator sidebar with a box allowing the user to take notes about the page.](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars/bookmarks-sidebar.png)

Using the `sidebar_action` manifest.json key, an extension can add its own sidebar to the browser. It will be listed alongside the built-in sidebars, and the user will be able to open it using the same mechanism as for the built-in sidebars.

Like a browser action popup, the sidebar's contents are specified as an HTML document. When the user opens the sidebar, the sidebar's document is loaded into every open browser window. Each window gets its own instance of the document. When new windows are opened, they get their own sidebar documents as well.

A document for a particular tab can be set using the `sidebarAction.setPanel()` function. A sidebar can figure out which window it belongs to using the `windows.getCurrent()` API:

```js
// sidebar.js
browser.windows.getCurrent({ populate: true }).then((windowInfo) => {
  myWindowId = windowInfo.id;
});
```

This is useful if a sidebar wants to display different content for different windows. For an example of this, see the "annotate-page" example.

Sidebar documents get access to the same set of privileged JavaScript APIs that the extension's background and popup scripts get. They can get direct access to the background page (unless the sidebar belongs to an incognito mode window) using `runtime.getBackgroundPage()`, and can interact with content scripts or native applications using messaging APIs like `tabs.sendMessage()` and `runtime.sendNativeMessage()`.

Sidebar documents are unloaded when their browser window is closed or when the user closes the sidebar. This means that unlike background pages, sidebar documents don't stay loaded all the time, but unlike browser action popups, they stay loaded while the user interacts with web pages.

When an extension that defines a sidebar is first installed, its sidebar will be opened automatically. This is intended to help the user understand that the extension includes a sidebar. Note that it's not possible for an extension to open sidebars programmatically: sidebars can only be opened by the user.

Specifying sidebars
-------------------

To specify a sidebar, define the default document with the `sidebar_action` manifest.json key, alongside a default title and icon:

```json
"sidebar\_action": {
  "default\_title": "My sidebar",
  "default\_panel": "sidebar.html",
  "default\_icon": "sidebar\_icon.png"
}
```

The title, panel, and icon can be changed programmatically using the `sidebarAction` API.

Title and icon are shown to the user in any UI provided by the browser to list sidebars, such as the "View > Sidebar" menu in Firefox.

Sidebar design
--------------

For details on how to design a sidebar's web page to match the style of Firefox, see the Acorn Design System documentation.

Example
-------

The webextensions-examples repository on GitHub includes the annotate-page example which implements a sidebar.


Browser styles - Mozilla

Browser styles
==============

Your extension can include user interface elements - browser and page action popups, sidebars, and options pages - that are specified by:

1. creating an HTML file defining the structure of the UI element.
2. adding a manifest.json key (`action`, `browser_action`, `page_action`, `sidebar_action`, or `options_ui`) pointing to that HTML file.

You can style these elements to match the browser's style. The manifest.json keys include an optional property to help with this: `browser_style`. If this is included and set to `true`, your document gets one or more extra stylesheets that help make it look consistent with the browser's UI and with other extensions that use the `browser_style` property.

**Note:**
 Support for `browser_style` in Manifest V3 is deprecated. Starting from Firefox 115, the default value of `options_ui.browser_style` and `sidebar_action.browser_style` changes from `true` to `false`. In Firefox 118, `"browser_style": true` will no longer be supported in Manifest V3 extensions.
 If your Manifest V3 extension depends on the `"browser_style": true` styles, follow the Manifest V3 migration guide for `browser_style`.
 See (Firefox bug 1827910) for more information.
 If you want to apply the Firefox style to your extension, see the Firefox Style Guide.

When considering whether to use `browser_style: true`, test your extension with various themes (built-in or from AMO) to ensure that the extension UI behaves the way you expect it to.

**Warning:** When `browser_style: true` is included in your web extension's manifest, text selection in your extension's UI is disabled except in input controls. If this causes a problem, include `browser_style:false` instead.

**Note:** **Google Chrome** and **Opera** use `chrome_style` instead of `browser_style` in Manifest V2. So for cross-browser extensions you need to add both keys. `chrome_style` is not available in Manifest V3.

In Firefox, the stylesheet can be seen at `chrome://browser/content/extension.css`. The extra stylesheet at `chrome://browser/content/extension-mac.css` is also included on macOS.

Most styles are automatically applied, but some elements require you to add the non-standard `browser-style` class to get their styling, as detailed in the table below:

| Element | Example |
| --- | --- |
| `<button>` |
```html
<button class="browser-style">Click me</button>
```
 |
| `<select>` |
```html
<select class="browser-style" name="select">
  <option value="value1">Value 1</option>
  <option value="value2" selected>Value 2</option>
  <option value="value3">Value 3</option>
</select>
```
 |
| `<textarea>` |
```html
<textarea class="browser-style">Write here</textarea>
```
 |
|
 Parent of an
 `<input>` |
```html
<div class="browser-style">
  <input type="radio" id="op1" name="choices" value="op1"/>
  <label for="op1">Option 1</label>
<input type="radio" id="op2" name="choices" value="op2"/>
<label for="op2">Option 2</label>
</div>
```

 |

Manifest V3 migration
---------------------

As `browser_style` is a deprecated in Manifest V3 you may want to remove support when you migrate your Manifest V2 extensions. Using `options_ui`, as an example, you would you take these steps to remove support for `browser_style`:

* Set `options_ui/browser_style` to `false`.
* Does the appearance of your extensions UI change?
    + If the appearance doesn't change, remove the key.
    + If the appearance changes, experiment to determine what dependency exist and add the relevant properties in the extension's stylesheet. The styles are most likely to cause layout changes are `box-sizing:`, `border-box`, and `display: flex`.
     If you cannot identify the dependencies, include the content of extension.css with the extension and delete all parts that aren't relevant, usually the `body` and `body *` blocks as most extensions don't use the `browser-style` class.
Firefox panel components (legacy)
---------------------------------

**Note:** This feature is non-standard and only works in Firefox.

The `chrome://browser/content/extension.css` stylesheet also contains the styles for the legacy Firefox panel components (navigation components).

The legacy Firefox Style Guide documents proper usage.

| Element | Example |
| --- | --- |
| Header |
```html
<header class="panel-section panel-section-header">
  <div class="icon-section-header"><img src="image.svg"/></div>
  <div class="text-section-header">Header</div>
</header>
```
 |
| Footer |
```html
<footer class="panel-section panel-section-footer">
  <button class="panel-section-footer-button">Cancel</button>
  <div class="panel-section-footer-separator"></div>
  <button class="panel-section-footer-button default">Confirm</button>
</footer>
```
 |
| Tabs |
```html
<div class="panel-section panel-section-tabs">
  <button class="panel-section-tabs-button selected">Tab</button>
  <div class="panel-section-tabs-separator"></div>
  <button class="panel-section-tabs-button">Tab</button>
  <div class="panel-section-tabs-separator"></div>
  <button class="panel-section-tabs-button">Tab</button>
</div>
```
 |
| Form |
```html
<div class="panel-section panel-section-formElements">
  <div class="panel-formElements-item">
    <label for="name01">Label:</label>
    <input type="text" value="Name" id="name01" />
  </div>
  <div class="panel-formElements-item">
    <label for="picker01">Label:</label>
    <select id="picker01">
      <option value="value1" selected="true">Dropdown</option>
      <option value="value2">List Item</option>
      <option value="value3">List Item</option>
    </select>
  </div>
  <div class="panel-formElements-item">
    <label for="placeholder01">Label:</label>
    <input type="text" placeholder="Placeholder" id="placeholder01" />
    <button name="expander" class="expander"></button>
  </div>
</div>
```
 |
| Menu |
```html
<div class="panel-section panel-section-list">
  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut">Ctrl-L</div>
  </div>
<div class="panel-list-item">
<div class="icon"></div>
<div class="text">List Item</div>
<div class="text-shortcut"></div>
</div>
<div class="panel-section-separator"></div>
<div class="panel-list-item disabled">
<div class="icon"></div>
<div class="text">Disabled List Item</div>
<div class="text-shortcut"></div>
</div>
<div class="panel-section-separator"></div>
<div class="panel-list-item">
<div class="icon"></div>
<div class="text">List Item</div>
<div class="text-shortcut"></div>
</div>
<div class="panel-list-item">
<div class="icon"></div>
<div class="text">List Item</div>
<div class="text-shortcut"></div>
</div>
</div>
```

 |

### Example

#### HTML

```html
<header class="panel-section panel-section-header">
  <div class="icon-section-header"><!-- An image goes here. --></div>
  <div class="text-section-header">Header</div>
</header>

<div class="panel-section panel-section-list">
  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut">Ctrl-L</div>
  </div>

  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut"></div>
  </div>

  <div class="panel-section-separator"></div>

  <div class="panel-list-item disabled">
    <div class="icon"></div>
    <div class="text">Disabled List Item</div>
    <div class="text-shortcut"></div>
  </div>

  <div class="panel-section-separator"></div>

  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut"></div>
  </div>

  <div class="panel-list-item">
    <div class="icon"></div>
    <div class="text">List Item</div>
    <div class="text-shortcut"></div>
  </div>
</div>

<footer class="panel-section panel-section-footer">
  <button class="panel-section-footer-button">Cancel</button>
  <div class="panel-section-footer-separator"></div>
  <button class="panel-section-footer-button default">Confirm</button>
</footer>
```

```
/\* Global \*/
html,
body {
  background: white;
  box-sizing: border-box;
  color: #222426;
  cursor: default;
  display: flex;
  flex-direction: column;
  font: caption;
  margin: 0;
  padding: 0;
  -moz-user-select: none;
}

body \* {
  box-sizing: border-box;
  text-align: start;
}

button.panel-section-footer-button,
button.panel-section-tabs-button {
  color: inherit;
  background-color: unset;
  font: inherit;
  text-shadow: inherit;
  appearance: none;
  border: none;
}

/\* Panel Section \*/
.panel-section {
  display: flex;
  flex-direction: row;
}

.panel-section-separator {
  background-color: rgba(0, 0, 0, 0.15);
  min-height: 1px;
}

/\* Panel Section - Header \*/
.panel-section-header {
  border-bottom: 1px solid rgba(0, 0, 0, 0.15);
  padding: 16px;
}

.panel-section-header > .icon-section-header {
  background-position: center center;
  background-repeat: no-repeat;
  height: 32px;
  margin-right: 16px;
  position: relative;
  width: 32px;
}

.panel-section-header > .text-section-header {
  align-self: center;
  font-size: 1.385em;
  font-weight: lighter;
}

/\* Panel Section - List \*/
.panel-section-list {
  flex-direction: column;
  padding: 4px 0;
}

.panel-list-item {
  align-items: center;
  display: flex;
  flex-direction: row;
  height: 24px;
  padding: 0 16px;
}

.panel-list-item:not(.disabled):hover {
  background-color: rgba(0, 0, 0, 0.06);
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}

.panel-list-item:not(.disabled):hover:active {
  background-color: rgba(0, 0, 0, 0.1);
}

.panel-list-item.disabled {
  color: #999;
}

.panel-list-item > .icon {
  flex-grow: 0;
  flex-shrink: 0;
}

.panel-list-item > .text {
  flex-grow: 10;
}

.panel-list-item > .text-shortcut {
  color: #808080;
  font-family: "Lucida Grande", caption;
  font-size: 0.847em;
  justify-content: flex-end;
}

.panel-section-list .panel-section-separator {
  margin: 4px 0;
}

/\* Panel Section - Footer \*/
.panel-section-footer {
  background-color: rgba(0, 0, 0, 0.06);
  border-top: 1px solid rgba(0, 0, 0, 0.15);
  color: #1a1a1a;
  display: flex;
  flex-direction: row;
  height: 41px;
  margin-top: -1px;
  padding: 0;
}

.panel-section-footer-button {
  flex: 1 1 auto;
  height: 100%;
  margin: 0 -1px;
  padding: 12px;
  text-align: center;
}

.panel-section-footer-button > .text-shortcut {
  color: #808080;
  font-family: "Lucida Grande", caption;
  font-size: 0.847em;
}

.panel-section-footer-button:hover {
  background-color: rgba(0, 0, 0, 0.06);
}

.panel-section-footer-button:hover:active {
  background-color: rgba(0, 0, 0, 0.1);
}

.panel-section-footer-button.default {
  background-color: #0996f8;
  box-shadow: 0 1px 0 #0670cc inset;
  color: #fff;
}

.panel-section-footer-button.default:hover {
  background-color: #0670cc;
  box-shadow: 0 1px 0 #005bab inset;
}

.panel-section-footer-button.default:hover:active {
  background-color: #005bab;
  box-shadow: 0 1px 0 #004480 inset;
}

.panel-section-footer-separator {
  background-color: rgba(0, 0, 0, 0.1);
  width: 1px;
  z-index: 99;
}
```

```
/\* Example specific – not part of chrome://browser/content/extension.css \*/
body {
  background: #fcfcfc;
  background-clip: padding-box;
  border: 1px solid rgba(24, 26, 27, 0.2);
  box-shadow:
    0 3px 5px rgba(24, 26, 27, 0.1),
    0 0 7px rgba(24, 26, 27, 0.1);
  box-sizing: content-box;
  margin: 2em auto 0.5em;
  width: 384px;
}

html {
  min-height: 100vh;
}

html > body {
  margin: auto;
}

.icon-section-header {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj48Y2lyY2xlIGZpbGw9IiMzNjM5NTkiIGN4PSIxNSIgY3k9IjE1IiByPSIxNSIvPjwvc3ZnPg==");
}
```

#### Result

Browser compatibility
---------------------

### webextensions.manifest.action

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### webextensions.manifest.browser\_action

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### webextensions.manifest.page\_action

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### webextensions.manifest.sidebar\_action

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### webextensions.manifest.options\_ui

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


devtools panels - Mozilla

devtools panels
===============

**Note:** This feature is available since Firefox 54.

When an extension provides tools that are of use to developers, it's possible to add a UI for them to the browser's developer tools as a new panel.

![Simple example showing the addition of "My panel" to the Developer Tools tabs.](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels/developer_panel_tab.png)

Specifying a developer tools panel
----------------------------------

A developer tools panel is added using the `devtools.panels` API, which in turn needs to be run from a special devtools page.

Add the devtools page by including the `devtools_page` key in extension's manifest.json and provide the location of the page's HTML file in the extension:

```json
"devtools\_page": "devtools-page.html"
```

From the devtools page, call a script that will add the devtools panel:

```html
<body>
  <script src="devtools.js"></script>
</body>
```

In the script, create the devtools panel by specifying the panel's title, icon, and HTML file that provides the panel's content:

```js
function handleShown() {
  console.log("panel is being shown");
}

function handleHidden() {
  console.log("panel is being hidden");
}

browser.devtools.panels
  .create(
    "My Panel", // title
    "icons/star.png", // icon
    "devtools/panel/panel.html", // content
  )
  .then((newPanel) => {
    newPanel.onShown.addListener(handleShown);
    newPanel.onHidden.addListener(handleHidden);
  });
```

The extension can now run code in the inspected window using `devtools.inspectedWindow.eval()` or by injecting a content script via the background script by passing a message. You can find more details on how to do this in Extending the developer tools.

Developer panel design
----------------------

For details on how to design your developer panel's web page to match the style of Firefox, see the Acorn Design System documentation.

Icons
-----

For details on how to create icons to use with your developer tools panel, see Iconography in the Acorn Design System documentation.

Examples
--------

The webextensions-examples repository on GitHub includes the devtools-panels example which implements a devtools panel.


Extension pages - Mozilla

Extension pages
===============

You can include HTML pages in your extension to provide forms, help, or any other content your extension needs.

![Example of a simple bundled page displayed as a detached panel.](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages/bundled_page_as_panel_small.png)

These pages also get access to the same privileged JavaScript APIs that are available to your extension's background scripts. However, they are in their own tab, with their own JavaScript event queue, their own globals, etc.

Think of the background page as a "hidden extension page".

Specifying extension pages
--------------------------

You can include HTML files—and associated CSS or JavaScript files—in your extension. The files can be included in the root or organized within meaningful sub-folders.
```

/my-extension
    /manifest.json
    /my-page.html
    /my-page.js
```

Displaying extension pages
--------------------------

There are two options for displaying extension pages: `windows.create()` and `tabs.create()`.

Using `windows.create()`, for example, you can open an HTML page into a detached panel (a window without the normal browser UI of address bar, bookmark bar, and alike) to create a dialog-like user experience:

```js
let createData = {
  type: "detached\_panel",
  url: "my-page.html",
  width: 250,
  height: 100,
};
let creating = browser.windows.create(createData);
```

When the window is no longer needed, it can be closed programmatically.

For example, after the user clicks a button, you may pass the current window's id to `windows.remove()`:

```js
document.getElementById("closeme").addEventListener("click", () => {
  let winId = browser.windows.WINDOW\_ID\_CURRENT;
  let removing = browser.windows.remove(winId);
});
```

Extension pages and history
---------------------------

By default, pages you open in this way will be stored in the user's history, just like normal web pages. If you don't want to have this behavior, use `history.deleteUrl()` to remove the browser's record:

```js
function onVisited(historyItem) {
  if (historyItem.url === browser.extension.getURL(myPage)) {
    browser.history.deleteUrl({ url: historyItem.url });
  }
}

browser.history.onVisited.addListener(onVisited);
```

To use the history API, you must request the "`history`" permission in your `manifest.json` file.

Web page design
---------------

For details on how to design your web page's to match the style of Firefox, see the Acorn Design System.

Examples
--------

The webextensions-examples repository on GitHub includes the window-manipulator example, which implements several of the options for creating windows.


Options page - Mozilla

Options page
============

An Options page enables you to define preferences for your extension that your users can change. Users can access the options page for an extension from the browser's add-ons manager:

The way users access the page, and the way it's integrated into the browser's user interface, will vary from one browser to another.

You can open the page programmatically by calling `runtime.openOptionsPage()`.

Options pages have a Content Security Policy that restricts the sources from which they can load resources, and disallows some unsafe practices such as the use of `eval()`. See Content Security Policy for more details.

Specifying the options page
---------------------------

To create an options page, write an HTML file defining the page. This page can include CSS and JavaScript files, like a normal web page. This page, from the favourite-color example, includes a JavaScript file:

```html
<!doctype html>

<html lang="en">
  <head>
    <meta charset="utf-8" />
  </head>

  <body>
    <form>
      <label for="color">Favorite color</label>
      <input type="text" id="color" name="color" />
      <button type="submit">Save</button>
    </form>
    <script src="options.js"></script>
  </body>
</html>
```

JavaScript running in the page can use all the WebExtension APIs that the add-on has permissions for. In particular, you can use the `storage` API to persist preferences.

Package the page's files in your extension.

You also need to include the `options_ui` key in your manifest.json file, giving it the URL to the page.

```json
"options\_ui": {
  "page": "options.html"
},
```

See the `options_ui` page for **sharing options** between your options page and background or content scripts.

Options content design
----------------------

For details on how to design your options content to match the style of Firefox, see the Acorn Design System.

Examples
--------

The webextensions-examples repository on GitHub includes the favourite-color example which implements options page features.


Address bar suggestions - Mozilla

Address bar suggestions
=======================

Using the `omnibox` API, extensions can customize the suggestions offered in the browser address bar's drop-down when the user enters a keyword.

![Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions.](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Omnibox/omnibox_example_small.png)

This enables your extension to, for example, search a library of free ebooks or, as in the example above, a repository of code examples.

Specifying the omnibox customization
------------------------------------

You tell your extension that it is going to customize the address bar suggestions by including the omnibox key and definition of the trigger keyword in its manifest.json file:

```json
  "omnibox": { "keyword" : "cs" }
```

In the extension's background JavaScript file, using `omnibox.setDefaultSuggestion()`, you can optionally define the first suggestion to be displayed in the address bar drop-down. Use this to provide a hint on how to use the feature:

```js
browser.omnibox.setDefaultSuggestion({
  description: `Search the Firefox codebase
 (e.g. "hello world" | "path:omnibox.js onInputChanged")`,
});
```

You can then add the code to provide the customized content by listening for `omnibox.onInputStarted`, which is dispatched when the user has typed the keyword and a space, and `omnibox.onInputChanged`, which is dispatched whenever the user updates the address bar entry. You can then populate the suggestions, in this case building a search of mozilla-central using the term entered by the user:

```js
browser.omnibox.onInputChanged.addListener((text, addSuggestions) => {
  let headers = new Headers({ Accept: "application/json" });
  let init = { method: "GET", headers };
  let url = buildSearchURL(text);
  let request = new Request(url, init);

  fetch(request).then(createSuggestionsFromResponse).then(addSuggestions);
});
```

If the extension set a default suggestion using `omnibox.setDefaultSuggestion()`, then this will appear first in the drop-down.

The extension can then listen for the user clicking one of the suggestions, using `omnibox.onInputEntered`. If the default suggestion is clicked the user's custom term is returned, otherwise the suggestion's string is returned. This also passes information on the user's browser preferences for handling new links. In the code below the user's custom term is used to create a search, otherwise the suggested URL is opened:

```js
browser.omnibox.onInputEntered.addListener((text, disposition) => {
  let url = text;
  if (!text.startsWith(SOURCE\_URL)) {
    // Update the URL if the user clicks on the default suggestion.
    url = `${SEARCH\_URL}?q=${text}`;
  }
  switch (disposition) {
    case "currentTab":
      browser.tabs.update({ url });
      break;
    case "newForegroundTab":
      browser.tabs.create({ url });
      break;
    case "newBackgroundTab":
      browser.tabs.create({ url, active: false });
      break;
  }
});
```

Examples
--------

The webextensions-examples repository on GitHub includes the firefox-code-search example which customizes the search bar.


Toolbar button - Mozilla

Toolbar button
==============

 Commonly referred to as a browser action, this user interface option is a button added to the browser toolbar. Users click the button to interact with your extension.

 ![A custom browser action icon it the browser tool bar that looks like paw print.](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Toolbar_button/toolbar_button.png)

The toolbar button (browser action) is very like the address bar button (page action). For the differences, and guidance on when to use what, see Page actions and browser actions.

Specifying the browser action
-----------------------------

You define the browser action's properties using the `"browser_action"` key in manifest.json:

```json
"browser\_action": {
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default\_title": "Whereami?"
}
```

There are no mandatory properties for this key. If you don't specify `"default_icon"` the extension icon is used, and the default web extension puzzle pace icon is used if the extension doesn't specify an icon. If `"default_title"` isn't specified, the extension name is used.

There are two ways to specify a browser action: with or without a popup. If you don't specify a popup, when the user clicks the button an event is dispatched to the extension, which the extension listens for using `browserAction.onClicked`:

```js
browser.browserAction.onClicked.addListener(handleClick);
```

If you specify a popup, the click event is not dispatched: instead, the popup is shown when the user clicks the button. The user can interact with the popup, which closes automatically when the user clicks outside it. See the Popup article for more details on creating and managing popups.

Note that your extension can have only one browser action.

You can change many of the browser action properties programmatically using the `browserAction` API.

Icons
-----

For details on how to create icons to use with your browser action, see Iconography in the Acorn Design System documentation.

Examples
--------

The `webextensions-examples` repository on GitHub contains two examples of extensions that implement browser actions:

* bookmark-it uses a browser action without a popup
* beastify uses a browser action with a popup


Address bar button - Mozilla

Address bar button
==================

Commonly referred to as a page action button, this user interface option is a button added to the browser address bar. Users click the button to interact with extensions.

![Page action button is an icon of a dog paw print](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions/address_bar_button.png)

Page actions and browser actions
--------------------------------

The address bar button (or page action) is similar to the toolbar button (or browser action).

The differences are:

* **The button's location:**
    + The page action is displayed inside the browser address bar.
    + The browser action is displayed outside the address bar, in the browser toolbar.
* **The button's visibility:**
    + The page action is hidden by default (although this default can be changed via the `show_matches` and `hide_matches` manifest key properties), and you call `pageAction.show()` and `pageAction.hide()` to show or hide it in specific tabs.
    + The browser action is always displayed.

Use a page action when the action relates to the current page. Use a browser action when the action relates to the browser as a whole or to many pages. For example:

| Type | Bookmarks action | Content action | Tabs operation |
| --- | --- | --- | --- |
| page action | Bookmark this page | Reddit enhancement | Send tab |
| browser action | Show all bookmarks | Enable ad-blocking | Sync all open tabs |

Specifying the page action
--------------------------

You define the page action's properties using the `page_action` key in manifest.json:

```json
"page\_action": {
  "default\_icon": {
    "19": "button/geo-19.png",
    "38": "button/geo-38.png"
  },
  "default\_title": "Whereami?"
}
```

The only mandatory key is `default_icon`.

There are two ways to specify a page action: with or without a popup.

* **Without a popup:** When the user clicks the button, an event is dispatched to the extension, which the extension listens for using `pageAction.onClicked`:

```js
browser.pageAction.onClicked.addListener(handleClick);
```

* **With a popup:** the `click` event is not dispatched. Instead, the popup appears when the user clicks the button. The user then interacts with the popup. When the user clicks outside of the popup, it closes automatically. See the Popup article for more details on creating and managing popups.

Note that your extension can have just one page action.

You can change any of the page action properties programmatically using the `pageAction` API.

Icons
-----

For details on how to create icons to use with your page action, see Iconography in the Acorn Design System documentation.

Examples
--------

The webextensions-examples repository on GitHub includes the chill-out example which implements a page action without a popup.


Popups - Mozilla

Popups
======

A popup is a dialog that's associated with a toolbar button or address bar button. This page describes popups in general, specifying them, debugging, resizing, and designing them, as well as examples of use.

![Page action pop-up example with three options: kittens, puppies, and reset.](/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups/page_action_popup.png)

When the user clicks the button, the popup is shown. When the user clicks anywhere outside the popup, the popup is closed. The popup can be closed programmatically by calling `window.close()` from a script running in the popup. However, you can't open the popup programmatically from an extension's JavaScript; it can be opened only in response to a user action.

You can define a keyboard shortcut that opens the popup using the `"_execute_browser_action"` and `"_execute_page_action"` shortcuts in Manifest V2 and `"_execute_action"`and, where supported, `"_execute_page_action"` shortcuts in Manifest V3. See the documentation for the special shortcuts in manifest.json key `commands`.

Specifying a popup
------------------

The popup is specified as an HTML file, which can include CSS and JavaScript files, as a normal web page does. Unlike a normal page, though, the JavaScript can use all the WebExtension APIs that the extension has permissions for.

The popup's document is loaded every time the popup is shown, and unloaded every time the popup is closed.

The HTML file is included in the extension and specified as part of the `browser_action` or `page_action` key by `"default_popup"` in the manifest.json:

```json
  "browser\_action": {
    "default\_icon": "icons/beasts-32.png",
    "default\_title": "Beastify",
    "default\_popup": "popup/choose\_beast.html"
  }
```

Popups have a Content Security Policy that restricts the sources from which they can load resources, and disallows some unsafe practices such as the use of `eval()`. See Content Security Policy for more details on this.

Debugging popups
----------------

You can debug a popup's markup and JavaScript using the Add-on Debugger, but you'll need to turn on the Disable popup auto-hide feature to prevent popups from hiding when you click outside them. Read about debugging popups.

Popup resizing
--------------

Popups resize automatically to fit their content. The algorithm for this may differ from one browser to another.

In Firefox, the size is calculated just before the popup is shown, and at most 10 times per second after DOM mutations. For strict mode documents, the size is calculated based on the layout size of the `<body>` element. For quirks mode, it's the `<html>` element. Firefox calculates the preferred width of the contents of that element, reflows it to that width, and then resizes so there's no vertical scrolling. It will grow to a size of **800x600 pixels** at most if that fits on the user's screen. (Prior to Firefox 60 it was only 680px.) If the user moves the extension's button to the menu or it appears in the toolbar overflow, then the popup appears inside the menu's panel and is given a fixed width.

When setting the popup `width` in CSS, you should set the it in the `<body>` and not in the `:root`.

In Firefox Android 57, the popup is shown as a normal page in a new tab.

Popup design
------------

For details on how to design your popup's web page to match the style of Firefox, see the Acorn Design System.

Examples
--------

The webextensions-examples repository on GitHub includes the beastify example, which implements a browser action with a popup.


Compiling from Rust to WebAssembly - WebAssembly

Compiling from Rust to WebAssembly
==================================

If you have some Rust code, you can compile it into WebAssembly (Wasm). This tutorial will show you how to compile a Rust project into WebAssembly and use it in an existing web app.

Rust and WebAssembly use cases
------------------------------

There are two main use cases for Rust and WebAssembly:

* Build an entire application — an entire web app based in Rust.
* Build a part of an application — using Rust in an existing JavaScript frontend.

For now, the Rust team is focusing on the latter case, and so that's what we cover here. For the former case, check out projects like `yew`.

In this tutorial, we build a package using `wasm-pack`, a tool for building JavaScript packages in Rust. This package will contain only WebAssembly and JavaScript code, and so the users of the package won't need Rust installed. They may not even notice that it's written in Rust.

Rust Environment Setup
----------------------

Let's go through all the required steps to get our environment set up.

### Install Rust

Install Rust by going to the Install Rust page and following the instructions. This installs a tool called "rustup", which lets you manage multiple versions of Rust. By default, it installs the latest stable Rust release, which you can use for general Rust development. Rustup installs `rustc`, the Rust compiler, as well as `cargo`, Rust's package manager, `rust-std`, Rust's standard libraries, and some helpful docs — `rust-docs`.

**Note:** Pay attention to the post-install note about needing cargo's `bin` directory in your system `PATH`. This is added automatically, but you must restart your terminal for it to take effect.

### wasm-pack

To build the package, we need an additional tool, `wasm-pack`. This helps compile the code to WebAssembly, as well as produce the right packaging for use in the browser. To download and install it, enter the following command into your terminal:

```bash
cargo install wasm-pack
```

Building our WebAssembly package
--------------------------------

Enough setup; let's create a new package in Rust. Navigate to wherever you keep your personal projects, and type this:

```bash
cargo new --lib hello-wasm
```

This creates a new library in a subdirectory named `hello-wasm` with everything you need to get going:
```

├── Cargo.toml
└── src
    └── lib.rs
```

First, we have `Cargo.toml`; this is the file that we use to configure our build. If you've used `Gemfile` from Bundler or `package.json` from npm, this is likely to be familiar; Cargo works in a similar manner to both of them.

Next, Cargo has generated some Rust code for us in `src/lib.rs`:

```rust
#[cfg(test)]
mod tests {
    #[test]
    fn it\_works() {
        assert\_eq!(2 + 2, 4);
    }
}
```

We won't use this test code at all, so go ahead and delete it.

### Let's write some Rust

Let's put this code into `src/lib.rs` instead:

```rust
use wasm\_bindgen::prelude::\*;

#[wasm\_bindgen]
extern {
    pub fn alert(s: &str);
}

#[wasm\_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}
```

This is the contents of our Rust project. It has three main parts; let's talk about each of them in turn. We give a high-level explanation here, and gloss over some details; to learn more about Rust, please check the free online book The Rust Programming Language.

#### Using `wasm-bindgen` to communicate between Rust and JavaScript

The first part looks like this:

```rust
use wasm\_bindgen::prelude::\*;
```

Libraries are called "crates" in Rust.

Get it? *Cargo* ships *crates*.

The first line contains a `use` command, which imports code from a library into your code. In this case, we're importing everything in the `wasm_bindgen::prelude` module. We use these features in the next section.

Before we move on to the next section, we should talk a bit more about `wasm-bindgen`.

`wasm-pack` uses `wasm-bindgen`, another tool, to provide a bridge between the types of JavaScript and Rust. It allows JavaScript to call a Rust API with a string, or a Rust function to catch a JavaScript exception.

We use `wasm-bindgen`'s functionality in our package. In fact, that's the next section.

#### Calling external functions in JavaScript from Rust

The next part looks like this:

```rust
#[wasm\_bindgen]
extern {
    pub fn alert(s: &str);
}
```

The bit inside the `#[ ]` is called an "attribute", and it modifies the next statement somehow. In this case, that statement is an `extern`, which tells Rust that we want to call some externally defined functions. The attribute says "wasm-bindgen knows how to find these functions".

The third line is a function signature, written in Rust. It says "the `alert` function takes one argument, a string named `s`."

As you might suspect, this is the `alert` function provided by JavaScript. We call this function in the next section.

Whenever you want to call JavaScript functions, you can add them to this file, and `wasm-bindgen` takes care of setting everything up for you. Not everything is supported yet, but we're working on it. Please file bugs if something is missing.

#### Producing Rust functions that JavaScript can call

The final part is this one:

```rust
#[wasm\_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}
```

Once again, we see the `#[wasm_bindgen]` attribute. In this case, it's not modifying an `extern` block, but a `fn`; this means that we want this Rust function to be able to be called by JavaScript. It's the opposite of `extern`: these aren't the functions we need, but rather the functions we're giving out to the world.

This function is named `greet`, and takes one argument, a string (written `&str`), `name`. It then calls the `alert` function we asked for in the `extern` block above. It passes a call to the `format!` macro, which lets us concatenate strings.

The `format!` macro takes two arguments in this case, a format string, and a variable to put in it. The format string is the `"Hello, {}!"` bit. It contains `{}`s, where variables will be interpolated. The variable we're passing is `name`, the argument to the function, so if we call `greet("Steve")` we should see `"Hello, Steve!".`

This is passed to `alert()`, so when we call this function we will see an alert box with "Hello, Steve!" in it.

Now that our library is written, let's build it.

### Compiling our code to WebAssembly

To compile our code correctly, we first need to configure it with `Cargo.toml`. Open this file, and change its contents to look like this:

```toml
[package]
name = "hello-wasm"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
description = "A sample project with wasm-pack"
license = "MIT/Apache-2.0"
repository = "https://github.com/yourgithubusername/hello-wasm"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"
```

Fill in your own repository and use the same info that `git` uses for the `authors` field.

The big part to add is the `[package]`. The `[lib]` part tells Rust to build a `cdylib` version of our package; we won't get into what that means in this tutorial. For more, consult the Cargo and Rust Linkage documentation.

The last section is the `[dependencies]` section. Here's where we tell Cargo what version of `wasm-bindgen` we want to depend on; in this case, that's any `0.2.z` version (but not `0.3.0` or above).

### Building the package

 Now that we've got everything set up, let's build the package.
 We'll be using the generated code in a native ES module and in Node.js.
 For this purpose, we'll use the `--target` argument in `wasm-pack build` to specify what kind of WebAssembly and JavaScript is generated.

Firstly, run the following command:

```bash
wasm-pack build --target web
```

This does a number of things (and they take a lot of time, especially the first time you run `wasm-pack`). To learn about them in detail, check out this blog post on Mozilla Hacks. In short, `wasm-pack build`:

1. Compiles your Rust code to WebAssembly.
2. Runs `wasm-bindgen` on that WebAssembly, generating a JavaScript file that wraps up that WebAssembly file into a module the browser can understand.
3. Creates a `pkg` directory and moves that JavaScript file and your WebAssembly code into it.
4. Reads your `Cargo.toml` and produces an equivalent `package.json`.
5. Copies your `README.md` (if you have one) into the package.

The end result? You have a package inside the `pkg` directory.

#### A digression about code size

If you check out the generated WebAssembly code size, it may be a few hundred kilobytes. We haven't instructed Rust to optimize for size at all, and doing so cuts down on the size *a lot*. This is beyond the scope of this tutorial, but if you'd like to learn more, check out the Rust WebAssembly Working Group's documentation on Shrinking .wasm Size.

Using the package on the web
----------------------------

 Now that we've got a compiled Wasm module, let's run it in the browser.
 Let's start by creating a file named `index.html` in the root of the project, so we end up with the following project structure:
```

├── Cargo.lock
├── Cargo.toml
├── index.html  <-- new index.html file
├── pkg
│   ├── hello_wasm.d.ts
│   ├── hello_wasm.js
│   ├── hello_wasm_bg.wasm
│   ├── hello_wasm_bg.wasm.d.ts
│   └── package.json
├── src
│   └── lib.rs
└── target
    ├── CACHEDIR.TAG
    ├── release
    └── wasm32-unknown-unknown
```

Put the following content in the `index.html` file:

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>hello-wasm example</title>
  </head>
  <body>
    <script type="module">
 import init, { greet } from "./pkg/hello\_wasm.js";
 init().then(() => {
 greet("WebAssembly");
 });
 </script>
  </body>
</html>
```

The script in this file will import the JavaScript glue code, initialize the Wasm module, and call the `greet` function we wrote in Rust.

Serve the root directory of the project with a local web server, (e.g. `python3 -m http.server`). If you're not sure how to do that, refer to Running a simple local HTTP server.

**Note:** Make sure to use an up-to-date web server that supports the `application/wasm` MIME type. Older web servers might not support it yet.

Load `index.html` from the web server (if you used the Python3 example: `http://localhost:8000`). An alert box appears on the screen, with `Hello, WebAssembly!` in it. We've successfully called from JavaScript into Rust, and from Rust into JavaScript.

Making our package available to npm
-----------------------------------

We are building an npm package, so you need to have Node.js and npm installed.

 To get Node.js and npm, go to the Get npm! page and follow the instructions.
 This tutorial targets node 20. If you need to switch between node versions, you can use nvm.

 If you want to use the WebAssembly module with npm, we'll need to make a few changes.
 Let's start by recompiling our Rust with `bundler` option as the target:

```bash
wasm-pack build --target bundler
```

We now have an npm package, written in Rust, but compiled to WebAssembly. It's ready for use from JavaScript, and doesn't require the user to have Rust installed; the code included was the WebAssembly code, not the Rust source.

### Using the npm package on the web

Let's build a website that uses our new npm package. Many people use npm packages through various bundler tools, and we'll be using one of them, `webpack`, in this tutorial. It's only a bit complex, and shows a realistic use-case.

 Let's move back out of the `pkg` directory, and make a new directory, `site`, to try this out.
 We haven't published the package to the npm registry yet, so we can install it from a local version using `npm i /path/to/package`.
 You may use `npm link`, but installing from a local path is convenient for the purposes of this demo:

```bash
cd ..
mkdir site && cd site
npm i ../pkg
```

Install the `webpack` dev dependencies:

```bash
npm i -D webpack@5 webpack-cli@5 webpack-dev-server@4 copy-webpack-plugin@11
```

Next, we need to configure Webpack. Create `webpack.config.js` and put the following in it:

```js
const CopyPlugin = require("copy-webpack-plugin");
const path = require("path");

module.exports = {
  entry: "./index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "index.js",
  },
  mode: "development",
  experiments: {
    asyncWebAssembly: true,
  },
  plugins: [
    new CopyPlugin({
      patterns: [{ from: "index.html" }],
    }),
  ],
};
```

In your `package.json`, you can add `build` and `serve` scripts that will run webpack with the config file we just created:

```json
{
  "scripts": {
    "build": "webpack --config webpack.config.js",
    "serve": "webpack serve --config webpack.config.js --open"
  },
  "dependencies": {
    "hello-wasm": "file:../pkg"
  },
  "devDependencies": {
    "copy-webpack-plugin": "^11.0.0",
    "webpack": "^5.89.0",
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^4.15.1"
  }
}
```

Next, create a file named `index.js`, and give it these contents:

```js
import \* as wasm from "hello-wasm";

wasm.greet("WebAssembly with npm");
```

This imports the module from the `node_modules` folder and calls the `greet` function, passing `"WebAssembly with npm"` as a string. Note how there's nothing special here, yet we're calling into Rust code. As far as the JavaScript code can tell, this is just a normal module.

Finally, we need to add a HTML file to load the JavaScript. Create an `index.html` file and add the following:

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>hello-wasm example</title>
  </head>
  <body>
    <script src="./index.js"></script>
  </body>
</html>
```

The `hello-wasm/site` directory should look like this:
```

├── index.html
├── index.js
├── node_modules
├── package-lock.json
├── package.json
└── webpack.config.js
```

We're done making files. Let's give this a shot:

```bash
npm run serve
```

This starts a web server and opens `http://localhost:8080`. You should see an alert box appears on the screen, with `Hello, WebAssembly with npm!` in it. We've successfully used the Rust module with npm!

If you would like to use your WebAssembly outside of local development, you can publish the package using the `pack` and `publish` commands:

```bash
wasm-pack pack
npm notice
npm notice 📦  hello-wasm@0.1.0
npm notice === Tarball Contents ===
npm notice 1.6kB  README.md
npm notice 2.5kB  hello_wasm_bg.js
npm notice 17.5kB hello_wasm_bg.wasm
npm notice 115B   hello_wasm.d.ts
npm notice 157B   hello_wasm.js
npm notice 531B   package.json
...
hello-wasm-0.1.0.tgz
[INFO]: 🎒  packed up your package!
```

 To publish to npm, you will need an npm account and authorize your machine using `npm adduser`.
 When you are ready, you can publish using `wasm-pack` which calls `npm publish` under the hood:

```bash
wasm-pack publish
```

Conclusion
----------

This is the end of our tutorial; we hope you've found it useful.

There's lots of exciting work going on in this space; if you'd like to help make it even better, check out the Rust and WebAssembly Working Group.


Converting WebAssembly text format to Wasm - WebAssembly

Converting WebAssembly text format to Wasm
==========================================

WebAssembly has an S-expression-based textual representation, an intermediate form designed to be exposed in text editors, browser developer tools, etc. This article explains a little bit about how it works, and how to use available tools to convert text format files to the Wasm format.

**Note:** Text format files are usually saved with a `.wat` extension. Historically, a `.wast` extension was also used, however that's now used for the scripting language used by the WebAssembly test suite.

A first look at the text format
-------------------------------

Let's look at a simple example of this — the following program imports a function called `imported_func` from a module called `imports`, and exports a function called `exported_func`:

```wasm
(module
  (func $i (import "imports" "imported\_func") (param i32))
  (func (export "exported\_func")
    i32.const 42
    call $i
  )
)
```

The WebAssembly function `exported_func` is exported for use in our environment (e.g. the web app in which we are using our WebAssembly module). When it is called, it calls an imported JavaScript function called `imported_func`, which is run with the value (42) provided as a parameter.

Converting the text .wat into a binary .wasm file
-------------------------------------------------

Let's have a go at converting the above `.wat` text representation example into `.wasm` assembly format.

1. To start with, make a copy of the above listing inside a text file; call it `simple.wat`.
2. We need to assemble this textual representation into the assembly language the browser actually reads before we can use it. To do this, we can use the wabt tool, which includes compilers to convert between WebAssembly's text representation and Wasm, and vice versa, plus more besides. Go to https://github.com/webassembly/wabt — follow the instructions on this page to set up the tool.
3. Once you've got the tool built, add the `/wabt/out/clang/Debug` directory to your system `PATH`.
4. Next, execute the wat2wasm program, passing it the path to the input file, followed by an `-o` parameter, followed by the path to the output file:

```bash
wat2wasm simple.wat -o simple.wasm
```

This will convert the Wasm into a file called `simple.wasm`, which contains the `.wasm` assembly code.

**Note:** You can also convert the assembly back into the text representation using the wasm2wat tool; for example `wasm2wat simple.wasm -o text.wat`.

Viewing the assembly output
---------------------------

Because the output file is assembly-based, it can't be viewed in a normal text editor. However, you can view it using the wat2wasm tool's `-v` option. Try this:

```bash
wat2wasm simple.wat -v
```

This will give you an output in your terminal in the following way:

![several strings of binary with textual descriptions beside them. For example: 0000008: 01 ; section code ](/en-US/docs/WebAssembly/Text_format_to_Wasm/assembly-output.png)

See also
--------

* Understanding WebAssembly text format — a detailed explanation of the text format syntax.
* Compiling from C/C++ to WebAssembly — tools like Binaryen/Emscripten both compile your source code to Wasm, and create the API code needed to run the module in a JavaScript context. Find out more about how to use them.
* Using the WebAssembly JavaScript API — read this if you want to find out more about how the WebAssembly API code works.
* Text format — more explanation of the text format, on the WebAssembly GitHub repo.
* wast-loader — a loader for webpack that takes care of all of this for you.


Compiling an Existing C Module to WebAssembly - WebAssembly

Compiling an Existing C Module to WebAssembly
=============================================

A core use-case for WebAssembly is to take the existing ecosystem of C libraries and allow developers to use them on the web.

These libraries often rely on C's standard library, an operating system, a file system and other things. Emscripten provides most of these features, although there are some limitations.

As an example, let's compile an encoder for WebP to Wasm. The source for the WebP codec is written in C and available on GitHub as well as some extensive API documentation. That's a pretty good starting point.

```bash
git clone https://github.com/webmproject/libwebp
```

To start off simple, expose `WebPGetEncoderVersion()` from `encode.h` to JavaScript by writing a C file called `webp.c`:

```cpp
#include "emscripten.h"
#include "src/webp/encode.h"

EMSCRIPTEN_KEEPALIVE
int version() {
  return WebPGetEncoderVersion();
}
```

This is a good simple program to test whether you can get the source code of libwebp to compile, as it doesn't require any parameters or complex data structures to invoke this function.

To compile this program, you need to tell the compiler where it can find libwebp's header files using the `-I` flag and also pass it all the C files of libwebp that it needs. A useful strategy is to just give it **all** the C files and rely on the compiler to strip out everything that is unnecessary. It seems to work brilliantly for this library:

```bash
emcc -O3 -s WASM=1 -s EXPORTED\_RUNTIME\_METHODS='["cwrap"]' \
    -I libwebp \
    webp.c \
    libwebp/src/{dec,dsp,demux,enc,mux,utils}/*.c \
    libwebp/sharpyuv/*.c
```

**Note:** This strategy will not work with every C project. Many projects rely on autoconf/automake to generate system-specific code before compilation. Emscripten provides `emconfigure` and `emmake` to wrap these commands and inject the appropriate parameters. You can find more in the Emscripten documentation.

Now you only need some HTML and JavaScript to load your new module:

```html
<script src="./a.out.js"></script>
<script>
 Module.onRuntimeInitialized = async () => {
 const api = {
 version: Module.cwrap("version", "number", []),
 };
 console.log(api.version());
 };
</script>
```

And you will see the correct version number in the output:

![Screenshot of the DevTools console showing the correct version number.](/en-US/docs/WebAssembly/existing_C_to_Wasm/version.png)

**Note:** libwebp returns the current version a.b.c as a hexadecimal number 0xabc. For example, v0.6.1 is encoded as 0x000601 = 1537.

### Get an image from JavaScript into Wasm

Getting the encoder's version number is great, but encoding an actual image would be more impressive. How do we do that?

The first question you need to answer is: how do I get the image into Wasm? Looking at the encoding API of libwebp, you'll find that it expects an array of bytes in RGB, RGBA, BGR or BGRA. Luckily, the Canvas API has `CanvasRenderingContext2D.getImageData` — that gives you a `Uint8ClampedArray` containing the image data in RGBA:

```js
async function loadImage(src) {
  // Load image
  const imgBlob = await fetch(src).then((resp) => resp.blob());
  const img = await createImageBitmap(imgBlob);
  // Make canvas same size as image
  const canvas = document.createElement("canvas");
  canvas.width = img.width;
  canvas.height = img.height;
  // Draw image onto canvas
  const ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0);
  return ctx.getImageData(0, 0, img.width, img.height);
}
```

Now it's "only" a matter of copying the data from JavaScript into Wasm. For that, you need to expose two additional functions — one that allocates memory for the image inside Wasm and one that frees it up again:

```cpp
#include <stdlib.h> // required for malloc definition

EMSCRIPTEN_KEEPALIVE
uint8\_t\* create\_buffer(int width, int height) {
  return malloc(width \* height \* 4 \* sizeof(uint8\_t));
}

EMSCRIPTEN_KEEPALIVE
void destroy\_buffer(uint8\_t\* p) {
  free(p);
}
```

The `create_buffer()` function allocates a buffer for the RGBA image — hence 4 bytes per pixel. The pointer returned by `malloc()` is the address of the first memory cell of that buffer. When the pointer is returned to JavaScript land, it is treated as just a number. After exposing the function to JavaScript using cwrap, you can use that number to find the start of our buffer and copy the image data:

```js
const api = {
  version: Module.cwrap("version", "number", []),
  create\_buffer: Module.cwrap("create\_buffer", "number", ["number", "number"]),
  destroy\_buffer: Module.cwrap("destroy\_buffer", "", ["number"]),
  encode: Module.cwrap("encode", "", ["number", "number", "number", "number"]),
  free\_result: Module.cwrap("free\_result", "", ["number"]),
  get\_result\_pointer: Module.cwrap("get\_result\_pointer", "number", []),
  get\_result\_size: Module.cwrap("get\_result\_size", "number", []),
};

const image = await loadImage("./image.jpg");
const p = api.create\_buffer(image.width, image.height);
Module.HEAP8.set(image.data, p);
// ... call encoder ...
api.destroy\_buffer(p);
```

### Encode the Image

The image is now available in Wasm. It is time to call the WebP encoder to do its job. Looking at the WebP documentation, you'll find that `WebPEncodeRGBA` seems like a perfect fit. The function takes a pointer to the input image and its dimensions, as well as a quality option between 0 and 100. It also allocates an output buffer for us that we need to free using `WebPFree()` once we are done with the WebP image.

The result of the encoding operation is an output buffer and its length. Because functions in C can't have arrays as return types (unless you allocate memory dynamically), this example resorts to a static global array. This may not be clean C. In fact, it relies on Wasm pointers being 32 bits wide. But this is a fair shortcut for keeping things simple:

```cpp
int result[2];
EMSCRIPTEN_KEEPALIVE
void encode(uint8\_t\* img_in, int width, int height, float quality) {
  uint8\_t\* img_out;
  size_t size;

  size = WebPEncodeRGBA(img_in, width, height, width \* 4, quality, &img_out);

  result[0] = (int)img_out;
  result[1] = size;
}

EMSCRIPTEN_KEEPALIVE
void free\_result(uint8\_t\* result) {
  WebPFree(result);
}

EMSCRIPTEN_KEEPALIVE
int get\_result\_pointer() {
  return result[0];
}

EMSCRIPTEN_KEEPALIVE
int get\_result\_size() {
  return result[1];
}
```

Now with all of that in place, you can call the encoding function, grab the pointer and image size, put it in a JavaScript buffer of your own, and release all the Wasm buffers allocated in the process:

```js
api.encode(p, image.width, image.height, 100);
const resultPointer = api.get\_result\_pointer();
const resultSize = api.get\_result\_size();
const resultView = new Uint8Array(
  Module.HEAP8.buffer,
  resultPointer,
  resultSize,
);
const result = new Uint8Array(resultView);
api.free\_result(resultPointer);
```

**Note:** `new Uint8Array(someBuffer)` will create a new view onto the same memory chunk, while `new Uint8Array(someTypedArray)` will copy the data.

Depending on the size of your image, you might run into an error where Wasm can't grow the memory enough to accommodate both the input and the output image:

![Screenshot of the DevTools console showing an error.](/en-US/docs/WebAssembly/existing_C_to_Wasm/error.png)

Luckily, the solution to this problem is in the error message. You just need to add `-s ALLOW_MEMORY_GROWTH=1` to your compilation command.

And there you have it. You have compiled a WebP encoder and transcoded a JPEG image to WebP. To prove that it worked, turn your result buffer into a blob and use it on an `<img>` element:

```js
const blob = new Blob([result], { type: "image/webp" });
const blobURL = URL.createObjectURL(blob);
const img = document.createElement("img");
img.src = blobURL;
img.alt = "a useful description";
document.body.appendChild(img);
```

Behold, the glory of a new WebP image.

Demo | Original Article

![DevTools network panel and the generated image.](/en-US/docs/WebAssembly/existing_C_to_Wasm/result.jpg)


Exported WebAssembly functions - WebAssembly

Exported WebAssembly functions
==============================

Exported WebAssembly functions are how WebAssembly functions are represented in JavaScript. This article describes what they are in a little more detail.

Exported… What?
---------------

Exported WebAssembly functions are basically just JavaScript wrappers that represent WebAssembly functions in JavaScript. When you call them, you get some activity in the background to convert the arguments into types that Wasm can work with (for example converting JavaScript numbers to Int32), the arguments are passed to the function inside your Wasm module, the function is invoked, and the result is converted and passed back to JavaScript.

You can retrieve exported WebAssembly functions in two ways:

* By calling `Table.prototype.get()` on an existing table.
* By accessing a function exported from a Wasm module instance via `Instance.exports`.

Either way, you get the same kind of wrapper for the underlying function. From a JavaScript point of view, it's as if every Wasm function *is* a JavaScript function too — but they are encapsulated by the exported Wasm function object instance and there are only limited ways to access them.

An example
----------

Let's look at an example to clear things up (you can find this on GitHub as table-set.html; see it running live also, and check out the Wasm text representation):

```js
const otherTable = new WebAssembly.Table({ element: "anyfunc", initial: 2 });

WebAssembly.instantiateStreaming(fetch("table.wasm")).then((obj) => {
  const tbl = obj.instance.exports.tbl;
  console.log(tbl.get(0)()); // 13
  console.log(tbl.get(1)()); // 42
  otherTable.set(0, tbl.get(0));
  otherTable.set(1, tbl.get(1));
  console.log(otherTable.get(0)());
  console.log(otherTable.get(1)());
});
```

Here we create a table (`otherTable`) from JavaScript using the `WebAssembly.Table` constructor, then we load `table.wasm` into our page using the `WebAssembly.instantiateStreaming()` method.

We then get the function exported from the module, retrieve the functions it references via `tbl.get()` and log the result of invoking each one to the console. Next, we use `set()` to make the `otherTable` table contain references to the same functions as the `tbl` table.

To prove this, we then retrieve these references back from `otherTable` and print their results to console too, which gives the same results.

They are real functions
-----------------------

In the previous example, the return value of each `Table.prototype.get()` call is an exported WebAssembly function — exactly what we have been talking about.

It is worth noting that these are real JavaScript functions, in addition to being wrappers for WebAssembly functions. If you load the above example in a WebAssembly-supporting browser, and run the following lines in your console:

```js
const testFunc = otherTable.get(0);
typeof testFunc;
```

you'll get the result `function` returned. You can then go on to do pretty much anything to this function that you can do to other functions in JavaScript — `call()`, `bind()`, etc. `testFunc.toString()` returns an interesting result:
```

function 0() {
    [native code]
}
```

This gives you more of an idea of its wrapper-type nature.

Some other particulars to be aware of with exported WebAssembly functions:

* Their length property is the number of declared arguments in the Wasm function signature.
* Their name property is the `toString()` result of the function's index in the Wasm module.
* If you try to call an exported Wasm function that takes or returns an i64 type value, it currently throws an error because JavaScript currently has no precise way to represent an i64. This may well change in the future though — a new int64 type is being considered for future standards, which could then be used by Wasm.


Using the WebAssembly JavaScript API - WebAssembly

Using the WebAssembly JavaScript API
====================================

If you have already compiled a module from another language using tools like Emscripten, or loaded and run the code yourself, the next step is to learn more about using the other features of the WebAssembly JavaScript API. This article teaches you what you'll need to know.

**Note:** If you are unfamiliar with the basic concepts mentioned in this article and need more explanation, read WebAssembly concepts first, then come back.

Some simple examples
--------------------

Let's run through some examples that explain how to use the WebAssembly JavaScript API, and how to use it to load a Wasm module in a web page.

**Note:** You can find the sample code in our webassembly-examples GitHub repo.

### Preparing the example

1. First we need a Wasm module! Grab our `simple.wasm` file and save a copy in a new directory on your local machine.
2. Next, let's create a simple HTML file called `index.html` in the same directory as your Wasm file (can use our simple template if you haven't got one easily available).
3. Now, to help us understand what is going on here, let's look at the text representation of our Wasm module (which we also meet in Converting WebAssembly format to Wasm):

```wasm
(module
  (func $i (import "imports" "imported\_func") (param i32))
  (func (export "exported\_func")
    i32.const 42
    call $i))
```

4. In the second line, you will see that the import has a two-level namespace — the internal function `$i` is imported from `imports.imported_func`. We need to reflect this two-level namespace in JavaScript when writing the object to be imported into the Wasm module. Create a `<script></script>` element in your HTML file, and add the following code to it:

```js
const importObject = {
  imports: { imported\_func: (arg) => console.log(arg) },
};
```

### Streaming the WebAssembly module

New in Firefox 58 is the ability to compile and instantiate WebAssembly modules directly from underlying sources. This is achieved using the `WebAssembly.compileStreaming()` and `WebAssembly.instantiateStreaming()` methods. These methods are easier than their non-streaming counterparts, because they can turn the byte code directly into `Module`/`Instance` instances, cutting out the need to separately put the `Response` into an `ArrayBuffer`.

This example (see our instantiate-streaming.html demo on GitHub, and view it live also) shows how to use `instantiateStreaming()` to fetch a Wasm module, import a JavaScript function into it, compile and instantiate it, and access its exported function — all in one step.

Add the following to your script, below the first block:

```js
WebAssembly.instantiateStreaming(fetch("simple.wasm"), importObject).then(
  (obj) => obj.instance.exports.exported\_func(),
);
```

The net result of this is that we call our exported WebAssembly function `exported_func`, which in turn calls our imported JavaScript function `imported_func`, which logs the value provided inside the WebAssembly instance (42) to the console. If you save your example code now and load it a browser that supports WebAssembly, you'll see this in action!

**Note:** This is a convoluted, long-winded example that achieves very little, but it does serve to illustrate what is possible — using WebAssembly code alongside JavaScript in your web applications. As we've said elsewhere, WebAssembly doesn't aim to replace JavaScript; the two instead can work together, drawing on each other's strengths.

### Loading our Wasm module without streaming

If you can't or don't want to use the streaming methods as described above, you can use the non-streaming methods `WebAssembly.compile()` / `WebAssembly.instantiate()` instead.

These methods don't directly access the byte code, so require an extra step to turn the response into an `ArrayBuffer` before compiling/instantiating the Wasm module.

The equivalent code would look like this:

```js
fetch("simple.wasm")
  .then((response) => response.arrayBuffer())
  .then((bytes) => WebAssembly.instantiate(bytes, importObject))
  .then((results) => {
    results.instance.exports.exported\_func();
  });
```

### Viewing Wasm in developer tools

In Firefox 54+, the Developer Tool Debugger Panel has functionality to expose the text representation of any Wasm code included in a web page. To view it, you can go to the Debugger Panel and click on the "wasm://" entry.

![Developer tools debugger panel highlighting a module.](/en-US/docs/WebAssembly/Using_the_JavaScript_API/wasm-debug.png)

In addition to viewing WebAssembly as text, developers are able to debug (place breakpoints, inspect the callstack, single-step, etc.) WebAssembly using the text format.

Memory
------

In the low-level memory model of WebAssembly, memory is represented as a contiguous range of untyped bytes called Linear Memory that are read and written by load and store instructions inside the module. In this memory model, any load or store can access any byte in the entire linear memory, which is necessary to faithfully represent C/C++ concepts like pointers.

Unlike a native C/C++ program, however, where the available memory range spans the entire process, the memory accessible by a particular WebAssembly Instance is confined to one specific — potentially very small — range contained by a WebAssembly Memory object. This allows a single web app to use multiple independent libraries — each of which are using WebAssembly internally — to have separate memories that are fully isolated from each other. In addition, newer implementations can also create shared memories, which can be transferred between Window and Worker contexts using `postMessage()`, and used in multiple places.

In JavaScript, a Memory instance can be thought of as a resizable `ArrayBuffer` (or `SharedArrayBuffer`, in the case of shared memories) and, just as with `ArrayBuffers`, a single web app can create many independent Memory objects. You can create one using the `WebAssembly.Memory()` constructor, which takes as arguments an initial size and (optionally) a maximum size and a `shared` property that states whether it is a shared memory or not.

Let's start exploring this by looking at a quick example.

1. Create another new simple HTML page (copy our simple template) and call it `memory.html`. Add a `<script></script>` element to the page.
2. Now add the following line to the top of your script, to create a memory instance:

```js
const memory = new WebAssembly.Memory({ initial: 10, maximum: 100 });
```

The unit of `initial` and `maximum` is WebAssembly pages — these are fixed to 64KB in size. This means that the above memory instance has an initial size of 640KB, and a maximum size of 6.4MB.
 WebAssembly memory exposes its bytes by providing a buffer getter/setter that returns an ArrayBuffer. For example, to write 42 directly into the first word of linear memory, you can do this:

```js
new Uint32Array(memory.buffer)[0] = 42;
```

You can then return the same value using:

```js
new Uint32Array(memory.buffer)[0];
```

3. Try this now in your demo — save what you've added so far, load it in your browser, then try entering the above two lines in your JavaScript console.
### Growing memory

A memory instance can be grown by calls to `Memory.prototype.grow()`, where again the argument is specified in units of WebAssembly pages:

```js
memory.grow(1);
```

If a maximum value was supplied upon creation of the memory instance, attempts to grow past this maximum will throw a `RangeError` exception. The engine takes advantage of this supplied upper-bounds to reserve memory ahead of time, which can make resizing more efficient.

Note: Since an `ArrayBuffer`'s byteLength is immutable, after a successful `Memory.prototype.grow()` operation the buffer getter will return a new ArrayBuffer object (with the new byteLength) and any previous ArrayBuffer objects become "detached", or disconnected from the underlying memory they previously pointed to.

Just like functions, linear memories can be defined inside a module or imported. Similarly, a module may also optionally export its memory. This means that JavaScript can get access to the memory of a WebAssembly instance either by creating a new `WebAssembly.Memory` and passing it in as an import or by receiving a Memory export (via `Instance.prototype.exports`).

### More involved memory example

Let's make the above assertions clearer by looking at a more involved memory example — a WebAssembly module that imports the memory instance we defined earlier, populates it with an array of integers, then sums them. You can find this at memory.wasm.

1. make a local copy of `memory.wasm` in the same directory as before.

**Note:** You can see the module's text representation at memory.wat.
2. Go back to your `memory.html` sample file, and fetch, compile, and instantiate your Wasm module as before — add the following to the bottom of your script:

```js
WebAssembly.instantiateStreaming(fetch("memory.wasm"), {
  js: { mem: memory },
}).then((results) => {
  // add code here
});
```

3. Since this module exports its memory, given an Instance of this module called instance we can use an exported function `accumulate()` to create and populate an input array directly in the module instance's linear memory (`mem`). Add the following into your code, where indicated:

```js
const i32 = new Uint32Array(memory.buffer);

for (let i = 0; i < 10; i++) {
  i32[i] = i;
}

const sum = results.instance.exports.accumulate(0, 10);
console.log(sum);
```

Note how we create the `Uint32Array` view on the Memory object's buffer (`Memory.prototype.buffer`), not on the Memory itself.

Memory imports work just like function imports, only Memory objects are passed as values instead of JavaScript functions. Memory imports are useful for two reasons:

* They allow JavaScript to fetch and create the initial contents of memory before or concurrently with module compilation.
* They allow a single Memory object to be imported by multiple module instances, which is a critical building block for implementing dynamic linking in WebAssembly.

**Note:** You can find our complete demo at memory.html (see it live also) .

Tables
------

A WebAssembly Table is a resizable typed array of references that can be accessed by both JavaScript and WebAssembly code. While Memory provides a resizable typed array of raw bytes, it is unsafe for references to be stored in a Memory since a reference is an engine-trusted value whose bytes must not be read or written directly by content for safety, portability, and stability reasons.

Tables have an element type, which limits the types of reference that can be stored in the table. In the current iteration of WebAssembly, there is only one type of reference needed by WebAssembly code — functions — and thus only one valid element type. In future iterations, more element types will be added.

Function references are necessary to compile languages like C/C++ that have function pointers. In a native implementation of C/C++, a function pointer is represented by the raw address of the function's code in the process's virtual address space and so, for the safety reasons mentioned above, cannot be stored directly in linear memory. Instead, function references are stored in a table and their indexes, which are integers and can be stored in linear memory, are passed around instead.

When the time comes to call a function pointer, the WebAssembly caller supplies the index, which can then be safety bounds checked against the table before indexing and calling the indexed function reference. Thus, tables are currently a rather low-level primitive used to compile low-level programming language features safely and portably.

Tables can be mutated via `Table.prototype.set()`, which updates one of the values in a table, and `Table.prototype.grow()`, which increases the number of values that can be stored in a table. This allows the indirectly-callable set of functions to change over time, which is necessary for dynamic linking techniques. The mutations are immediately accessible via `Table.prototype.get()` in JavaScript, and to Wasm modules.

### A table example

Let's look at a simple table example — a WebAssembly module that creates and exports a table with two elements: element 0 returns 13 and element 1 returns 42. You can find this at table.wasm.

1. Make a local copy of `table.wasm` in a new directory.

**Note:** You can see the module's text representation at table.wat.
2. Create a new copy of our HTML template in the same directory and call it `table.html`.
3. As before, fetch, compile, and instantiate your Wasm module — add the following into a `<script>` element at the bottom of your HTML body:

```js
WebAssembly.instantiateStreaming(fetch("table.wasm")).then((results) => {
  // add code here
});
```

4. Now let's access the data in the tables — add the following lines to your code in the indicated place:

```js
const tbl = results.instance.exports.tbl;
console.log(tbl.get(0)()); // 13
console.log(tbl.get(1)()); // 42
```

This code accesses each function reference stored in the table in turn, and instantiates them to print the values they hold to the console — note how each function reference is retrieved with a `Table.prototype.get()` call, then we add an extra set of parentheses on the end to actually invoke the function.

**Note:** You can find our complete demo at table.html (see it live also).

Globals
-------

WebAssembly has the ability to create global variable instances, accessible from both JavaScript and importable/exportable across one or more `WebAssembly.Module` instances. This is very useful, as it allows dynamic linking of multiple modules.

To create a WebAssembly global instance from inside your JavaScript, you use the `WebAssembly.Global()` constructor, which looks like this:

```js
const global = new WebAssembly.Global({ value: "i32", mutable: true }, 0);
```

You can see that this takes two parameters:

* An object that contains two properties describing the global variable:
    + `value`: its data type, which can be any data type accepted within WebAssembly modules — `i32`, `i64`, `f32`, or `f64`.
    + `mutable`: a boolean defining whether the value is mutable or not.
* A value containing the variable's actual value. This can be any value, as long as its type matches the specified data type.

So how do we use this? In the following example we define a global as a mutable `i32` type, with a value of 0.

The value of the global is then changed, first to `42` using the `Global.value` property, and then to 43 using the `incGlobal()` function exported out of the `global.wasm` module (this adds 1 to whatever value is given to it and then returns the new value).

```js
const output = document.getElementById("output");

function assertEq(msg, got, expected) {
  const result =
    got === expected
      ? `SUCCESS! Got: ${got}<br>`
      : `FAIL!<br>Got: ${got}<br>Expected: ${expected}<br>`;
  output.innerHTML += `Testing ${msg}: ${result}`;
}

assertEq("WebAssembly.Global exists", typeof WebAssembly.Global, "function");

const global = new WebAssembly.Global({ value: "i32", mutable: true }, 0);

WebAssembly.instantiateStreaming(fetch("global.wasm"), { js: { global } }).then(
  ({ instance }) => {
    assertEq(
      "getting initial value from wasm",
      instance.exports.getGlobal(),
      0,
    );
    global.value = 42;
    assertEq(
      "getting JS-updated value from wasm",
      instance.exports.getGlobal(),
      42,
    );
    instance.exports.incGlobal();
    assertEq("getting wasm-updated value from JS", global.value, 43);
  },
);
```

**Note:** You can see the example running live on GitHub; see also the source code.

Multiplicity
------------

Now we've demonstrated usage of the main key WebAssembly building blocks, this is a good place to mention the concept of multiplicity. This provides WebAssembly with a multitude of advances in terms of architectural efficiency:

* One module can have N Instances, in the same way that one function literal can produce N closure values.
* One module instance can use 0–1 memory instances, which provide the "address space" of the instance. Future versions of WebAssembly may allow 0–N memory instances per module instance (see Multiple Memories).
* One module instance can use 0–1 table instances — this is the "function address space" of the instance, used to implement C function pointers. Future versions of WebAssembly may allow 0–N table instances per module instance.
* One memory or table instance can be used by 0–N module instances — these instances all share the same address space, allowing dynamic linking.

You can see multiplicity in action in our Understanding text format article — see the Mutating tables and dynamic linking section.

Summary
-------

This article has taken you through the basics of using the WebAssembly JavaScript API to include a WebAssembly module in a JavaScript context and make use of its functions, and how to use WebAssembly memory and tables in JavaScript. We also touched on the concept of multiplicity.

See also
--------

* webassembly.org
* WebAssembly concepts
* WebAssembly on Mozilla Research