JavaScript
Workers based on JavaScript work out of the box with Wasm Workers Server. The server integrates a JavaScript interpreter compiled into a WebAssembly module. Currently, the interpreter we support is quickjs and we are working on adding new ones.
Run a JavaScript example
- Download - wws:- curl -fsSL https://workers.wasmlabs.dev/install | bash
- Run the js-basic example from the Wasm Workers Server's repository: - wws https://github.com/vmware-labs/wasm-workers-server.git -i --git-folder "examples/js-basic"
- Access to http://localhost:8080. 
Your first JavaScript worker
JavaScript workers are based on the Request / Response objects from the Web Fetch API. Your worker needs to listen to the fetch event, which will include an associated Request object. The worker function will receive the request and generate a Response object to reply to the request.
In this example, the worker will get a request and print all the related information.
- First, create a new - index.jsfile with the following content. It is the minimum code you need to subscribe to the fetch event and return a valid response../index.js- const reply = (request) => {
 return new Response("Hello Wasm!");
 }
 // Subscribe to the Fetch event
 addEventListener("fetch", event => {
 return event.respondWith(reply(event.request));
 });
- Now, you can add more content to the - replyfunction to show the request information. In addition to that, let's add a response header../index.js- const reply = (request) => {
 // Body response
 const body = `<!DOCTYPE html>
 <body>
 <h1>Hello from Wasm Workers Server</h1>
 <p>Replying to ${request.url}</p>
 <p>Method: ${request.method}</p>
 <p>User Agent: ${request.headers.get("userAgent")}</p>
 <p>Payload: ${request.body || "-"}</p>
 <p>
 This page was generated by a JavaScript file inside WebAssembly
 </p>
 </body>`;
 // Build a new response
 let response = new Response(body);
 // Add a new header
 response.headers.set("x-generated-by", "wasm-workers-server");
 return response;
 }
 // Subscribe to the Fetch event
 addEventListener("fetch", event => {
 return event.respondWith(reply(event.request));
 });
- Save the file and run your worker with - wws. If you didn't download the- wwsserver yet, check our Getting Started guide.- wws
 ⚙️ Loading routes from: .
 🗺 Detected routes:
 - http://127.0.0.1:8080/
 => index.js (name: default)
 🚀 Start serving requests at http://127.0.0.1:8080
- Finally, open http://127.0.0.1:8080 in your browser. 
Add a Key / Value store
Wasm Workers allows you to add a Key / Value store to your workers. Read more information about this feature in the Key / Value store section.
To add a KV store to your worker, follow these steps:
- First, create a - counter.jsfile. It will access the KV store through the- Cacheobject:./counter.js- const CACHE_KEY = "counter";
 const reply = (request) => {
 let counter = Cache.get(CACHE_KEY) || 0;
 counter += 1;
 Cache.set(CACHE_KEY, counter);
 return new Response(`Counter: ${counter}`);
 }
 addEventListener("fetch", event => {
 event.respondWith(reply(event.request));
 });
- Create a - counter.tomlfile with the following content. Note the name of the TOML file must match the name of the worker. In this case we have- counter.jsand- counter.tomlin the same folder:./counter.toml- name = "counter"
 version = "1"
 [data]
 [data.kv]
 namespace = "counter"
- Save the file and run your worker with - wws. If you didn't download the- wwsserver yet, check our Getting Started guide.- wws
 ⚙️ Loading routes from: .
 🗺 Detected routes:
 - http://127.0.0.1:8080/counter
 => counter.js (name: default)
 🚀 Start serving requests at http://127.0.0.1:8080
- Finally, open http://127.0.0.1:8080/counter in your browser. 
Send an HTTP request (fetch)
Wasm Workers allows you to send HTTP requests from your workers. Read more information about this feature in the HTTP Requests section.
To perform HTTP requests from your worker, follow these steps:
- First, create an - index.jsfile. It will call the {JSON} Placeholder API using the fetch method:./index.js- const reply = async (_req) => {
 // Body response
 let body;
 try {
 let res = await fetch('https://jsonplaceholder.typicode.com/posts/1');
 let json = await res.json();
 // Build a new response.
 // Add some basic sanitization
 body = `<!DOCTYPE html>
 <head>
 <title>JSON Placeholder request</title>
 <meta name="viewport" content="width=device-width,initial-scale=1">
 <meta charset="UTF-8">
 </head>
 <body>
 <main>
 <h1>Hello from Wasm Workers Server 👋</h1>
 <p>The post title is: ${json.title}</p>
 </main>
 </body>`;
 } catch (e) {
 body = `There was an error with the request: ${e}`;
 }
 return new Response(body);
 }
 addEventListener("fetch", event => {
 event.respondWith(reply(event.request));
 });
- Create an - index.tomlfile with the following content. It enables the worker to perform HTTP requests to that host given that, by default, HTTP requests are forbidden.- Note the name of the TOML file must match the name of the worker. In this case we have - index.jsand- index.tomlin the same folder:./index.toml- name = "fetch"
 version = "1"
 [features]
 [features.http_requests]
 allowed_methods = ["GET"]
 allowed_hosts = ["jsonplaceholder.typicode.com"]
- Save the file and run your worker with - wws. If you didn't download the- wwsserver yet, check our Getting Started guide.- wws
 ⚙️ Preparing the project from: .
 ⚙️ Loading routes from: .
 ⏳ Loading workers from 1 routes...
 ✅ Workers loaded in 135.717667ms.
 - http://127.0.0.1:8080/
 => ./index.js
 🚀 Start serving requests at http://127.0.0.1:8080
- Finally, open http://127.0.0.1:8080 in your browser. 
Dynamic routes
You can define dynamic routes by adding route parameters to your worker files (like [id].js). To read them in JavaScript, access to the req.params object:
/**
 * Builds a reply to the given request
 */
const reply = (req) => {
  // Build a new response
  return new Response(`Hey! I got this parameter: ${req.params.id}`);
}
// Subscribe to the Fetch event
addEventListener("fetch", event => {
  return event.respondWith(reply(event.request));
});
Read environment variables
Environment variables are configured via the related TOML configuration file. These variables are directly injected as global constants in your worker. To read them, just use the same name you configured in your TOML file:
name = "envs"
version = "1"
[vars]
MESSAGE = "Hello 👋! This message comes from an environment variable"
Now, you can use the MESSAGE constant directly:
const reply = (request) => {
  // Body response
  const body = JSON.stringify({
    success: true,
    // Here you can read the constant directly
    message: MESSAGE
  }, null, 2);
  // Build a new response
  let response = new Response(body, {
    headers: {
      "content-type": "application/json;charset=UTF-8"
    }
  });
  return response;
}
// Subscribe to the Fetch event
addEventListener("fetch", event => {
  return event.respondWith(reply(event.request));
});
If you prefer, you can configure the environment variable value dynamically by following these instructions.
Other examples
Feature compatibility
Workers' features that are available in JavaScript:
| K/V Store | Environment Variables | Dynamic Routes | Folders | HTTP Requests | 
|---|---|---|---|---|
| ✅ | ✅ | ✅ | ❌ | ✅ |