---
name: azion-create-a-function-with-webassembly
description: >-
  Compile and instantiate a WebAssembly module inside a function, from a byte array in the code or from a .wasm file the handler fetches.
---

# Create a function with WebAssembly

A [function](/en/documentation/platform/functions/) compiles and instantiates a [WebAssembly](https://webassembly.org/getting-started/developers-guide/) module with the WebAssembly API, inside the handler. Azion Runtime provides that API with the interface MDN defines. For the static methods and constructors it carries, refer to [WebAssembly](/en/documentation/devtools/runtime/api-reference/webassembly/).

The steps below use Azion Console. The module on this page exports one operation, `increment`, and the handler returns its result in the response body. The module bytes reach the handler in two ways: as a byte array in the function code, or as a `.wasm` file the handler fetches over HTTP.

---

## Prerequisites

- An Azion account. To create one, refer to [How to create an account on Azion](/en/documentation/fundamentals/creating-account/).
- The **Edit Functions** permission on the account. It grants permission to create, edit, and remove functions, and it also requires the permission **View Functions**. Refer to [Teams Permissions](/en/documentation/fundamentals/teams-permissions/).

---

## Create the function with an embedded module

The `wasmCode` array holds the module, so the handler compiles it without a network request. To create the function:

1. **Open the Functions page**

   Access [Azion Console](https://console.azion.com/) > **Products Menu** > **Libraries** > **Functions**.

2. **Select + Function**

3. **Name the function**

   Enter a name for the function. For example: `wasm-increment`.

4. **Paste the code in the Code tab**

   In the **Code** tab, paste the following code:

   ```javascript
   export default {
     fetch: async (request, env, ctx) => {
       const wasmCode = new Uint8Array([
         0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 127, 1, 127, 3, 2, 1, 0, 7, 13, 1, 9, 105, 110, 99, 114, 101,
         109, 101, 110, 116, 0, 0, 10, 9, 1, 7, 0, 32, 0, 65, 1, 106, 11,
       ]);

       const wasmModule = new WebAssembly.Module(wasmCode);
       const wasmInstance = new WebAssembly.Instance(wasmModule);
       const increment = wasmInstance.exports.increment;
       let value = 0;

       if (request.headers.has("value")) {
         let number = request.headers.get("value");
         if (!isNaN(number)) {
           value = parseInt(number);
         }
       }

       let incremented = increment(value);
       return new Response("incrementing " + value + " we have " + incremented);
     },
   };
   ```

5. **Select Save**

The function is saved and available to instantiate on an application.

The `wasmCode` array is the binary form of the following [WAT](https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format) module, which adds 1 to its `i32` parameter and returns the result:

```text
(module
  (type (;0;) (func (param i32) (result i32)))
  (func (;0;) (type 0) (param i32) (result i32)
    local.get 0
    i32.const 1
    i32.add)
  (export "increment" (func 0)))
```

> **Note**
>
> WAT is the textual representation of the WebAssembly binary format. It exists so that a person can read and edit a module.

A byte array is part of the function source code, so the module counts toward the code size limit: 6 MB in Azion Console, and 20 MB through the Azion API. Refer to [Functions limits](/en/documentation/platform/functions/limits/).

---

## Load the module from a URL

A handler reads the module bytes over HTTP instead of carrying them. Replace the byte array with a `fetch` call, and pass the response body to `WebAssembly.instantiate()`:

```javascript
export default {
  fetch: async (request, env, ctx) => {
    const wasmResponse = await fetch("https://example.com/increment.wasm");
    const wasmCode = await wasmResponse.arrayBuffer();

    const { instance } = await WebAssembly.instantiate(wasmCode);
    const increment = instance.exports.increment;
    let value = 0;

    if (request.headers.has("value")) {
      let number = request.headers.get("value");
      if (!isNaN(number)) {
        value = parseInt(number);
      }
    }

    let incremented = increment(value);
    return new Response("incrementing " + value + " we have " + incremented);
  },
};
```

The handler compiles whatever the URL returns, so a new build of the module reaches the function without a code change. Each `fetch` call counts as a sub-request, and an invocation makes at most 50 of them. Refer to [Functions limits](/en/documentation/platform/functions/limits/).

---

## Verify the response

A function runs only after a [function instance](/en/documentation/platform/applications/functions-instances/) binds it to an application, and a Rules Engine rule selects that instance. To build that chain, refer to [Functions quickstart](/en/documentation/platform/functions/quickstart/).

To read the response, request the URI set in the rule:

```bash
curl https://<your-azion-domain>/<your-uri>
```

The module increments the default value, `0`:

```
incrementing 0 we have 1
```

The handler reads the `value` request header when the request carries one. To increment a different integer, send it in that header:

```bash
curl -H "value: 41" https://<your-azion-domain>/<your-uri>
```

```
incrementing 41 we have 42
```

The response body carries the result the WebAssembly module computed.

---

## Next steps

- [Functions quickstart](/en/documentation/platform/functions/quickstart.md): Instantiate the function on an application, and add the Rules Engine rule that runs it.
- [WebAssembly API](/en/documentation/devtools/runtime/api-reference/webassembly.md): Every static method and constructor Azion Runtime carries, with its syntax and parameters.
- [Migrate handler patterns in Functions](/en/documentation/guides/application-development/functions-and-runtime/migrate-handler-patterns.md): The ES Modules and Service Worker handler shapes, and how to move code between them.
- [Functions limits](/en/documentation/platform/functions/limits.md): The code size, sub-request, and CPU time ceilings a function runs inside.
