Wasm Workers Server 1.0: support for Python and Ruby
Wasm Workers Server is a WebAssembly framework to develop and run serverless applications. It aims to bring the benefits of WebAssembly to your apps without changing your development workflow. If you are new to Wasm Workers Server, here you have a quick 5 minutes introduction.
In v1.0.0, you can now write Workers-based applications in additional dynamic languages: Ruby and Python. Before, wws
only identified .wasm
modules and .js
files as workers. Now, you can extend the supported languages by installing language runtimes locally.
By default, wws
relies on the WebAssembly Languages Runtimes project, which has support for Python, Ruby, and PHP. From the wws
CLI, you can list, install and use the available language runtimes and start creating new workers.
Can't wait to try it? Just update or install wws
and try the new runtimes
command:
curl -fsSL https://workers.wasmlabs.dev/install | bash && \
wws runtimes list
You will get the list of available language runtimes:
⚙️ Fetching data from the repository...
┌────────┬─────────┬───────────────────┬───────────┬─────────────┐
│ Name │ Version │ Tags │ Extension │ Binary │
├────────┼─────────┼───────────────────┼───────────┼─────────────┤
│ ruby │ 3.2.0 │ latest, 3, 3.2.0 │ rb │ ruby.wasm │
├────────┼─────────┼───────────────────┼───────────┼─────────────┤
│ python │ 3.11.1 │ latest, 3, 3.11.1 │ py │ python.wasm │
└────────┴─────────┴───────────────────┴───────────┴─────────────┘
The v1.0.0 version comes with more features. For example, we introduced dynamic routes and several bug fixes. We will dig into all of them in this article. If you prefer a video version, you can check all the new features on Youtube 👇

Multi-language support
Reusing your existing knowledge, such as programming languages, is key to being productive. If you are used to developing applications with JavaScript, Ruby, or Python, we want you to be able to continue using them while leveraging new and exciting features. For this reason, we introduced a new command in wws
to extend the number of programming languages to write workers.
By default, wws
identifies .wasm
modules and .js
files as workers. With the new runtimes
command, you can download different language runtimes to increase the number of supported languages. When you install a new language, wws
downloads three main files:
- The Wasm module that contains the language runtime.
- A polyfill to provide the
Request
andResponse
entities. - A wrapper to connect your worker code with
wws
. It initializes theRequest
and formats theResponse
.
When you run any runtimes
subcommand, it fetches the metadata from the Wasm Workers Server repository and downloads the binaries from the WebAssembly Languages Runtimes project. You can also configure your repository by following this guide.
Install a new language runtime
To install a new language runtime, check the available runtimes:
wws runtimes list
⚙️ Fetching data from the repository...
┌────────┬─────────┬───────────┬───────────┬─────────────┐
│ Name │ Version │ Tags │ Extension │ Binary │
├────────┼─────────┼───────────┼───────────┼─────────────┤
│ ruby │ 3.2.0 │ latest, 3 │ rb │ ruby.wasm │
├────────┼─────────┼───────────┼───────────┼─────────────┤
│ python │ 3.11.1 │ latest, 3 │ py │ python.wasm │
└────────┴─────────┴───────────┴───────────┴─────────────┘
Let's say you want to create a worker using Python. You can install the runtime using the name and alias:
wws runtimes install python latest
⚙️ Fetching data from the repository...
🚀 Installing the runtime...
✅ Done
Now, wws
is ready to load .py
files as workers! Note that wws
stores the runtime in the current folder. It will detect the .py
files in this folder and subfolders.
You may notice two new resources in your folder:
- A
.wws
folder - A
.wws.toml
file
wws
stores the runtimes required files in the .wws
folder. The .wws.toml
file contains the metadata of the installed runtimes. If you retrieve this project in a clean environment, you can install the required runtimes by running wws runtimes install
. wws
will read the metadata from the .wws.toml
file and install the missing runtimes.
Your first Python worker
You are now ready to create your first Python worker! Let's begin with a simple "Hello World". For that, create a new index.py
file. The file must include a worker
function that receives a Request
object and returns a Response
one. You can use the code below:
def worker(req):
return Response("Hello from Python in Wasm")
After saving the file, run the wws
command:
wws
⚙️ Loading routes from: .
🗺 Detected routes:
- http://127.0.0.1:8080/
=> ./index.py (name: default)
🚀 Start serving requests at http://127.0.0.1:8080
wws
quickly identifies the index.py
file as a worker. You can access http://localhost:8080 to see the result. As a next step, let's read the request details and modify some of the headers:
def worker(req):
# Body response
body = '''\
<!DOCTYPE html>
<body>
<h1>Hello from Wasm Workers Server</h1>
<p>Replying to {url}</p>
<p>Method: {method}</p>
<p>User Agent: {agent}</p>
<p>
This page was generated by a Python file inside WebAssembly
</p>
</body>
'''.format(
url=req.url,
method=req.method,
agent=req.headers["user-agent"]
)
# Build a new response
res = Response(body)
# Add a new header
res.headers["x-generated-by"] = "wasm-workers-server"
return res
Restart wws
and reload your page to see the changes.

Your first Ruby worker
Wasm Workers Server allows you to mix programming languages in the same project. To create a new Ruby worker, first install the ruby runtime:
wws runtimes install ruby latest
⚙️ Fetching data from the repository...
🚀 Installing the runtime...
✅ Done
All workers follow the same Request
/ Response
approach. To create your first Ruby worker, create a ruby.rb
file and define a worker
function:
def worker(req)
Response.new("Hello from Ruby in Wasm")
end
Now, run wws
and check how both /
and /ruby
endpoints work together:
wws
⚙️ Loading routes from: .
🗺 Detected routes:
- http://127.0.0.1:8080/
=> ./index.py (name: default)
- http://127.0.0.1:8080/ruby
=> ./ruby.rb (name: default)
🚀 Start serving requests at http://127.0.0.1:8080
Finally, access http://localhost:8080/ruby to see the result.
Dynamic routes (parameters)
Apart from the addition of new language runtimes, we have additional major features to share with you! In v1.0.0, we introduced support for dynamic routes. In many cases, you want a worker to process multiple URLs. For example, your application may use identifiers to identify resources:
/room/iu812kjas
/room/jdki2312d
...
In v1.0.0, you can create workers that process multiple URLs by using the [PARAM_NAME].*
pattern in the filename. For example, a worker called room/[room].js
manages the previous URLs. The worker will receive a params
object that includes the route parameter key and value ({ "room": "iu812kjas" }
).
You can create dynamic routes using folders too. Imagine you have a players
' subresource inside every room (like /room/ID/players
). To create a worker to manage the players, add the identifier to the folder that contains the worker: room/[room]/players.js
.
Your first dynamic route
This feature applies to all the supported languages, so let's try it with Python. First, create a new [id].py
file in your current project. If you didn't install the Python runtime before, just run wws runtimes install python latest
. In Python, you can retrieve the route parameters directly from the request
instance:
def worker(req):
# Body response
body = '''\
<!DOCTYPE html>
<body>
<h1>Hello from Wasm Workers Server</h1>
<p>Replying to {url}</p>
<p>Parameter: {param}</p>
<p>
This page was generated by a Python file inside WebAssembly
</p>
</body>
'''.format(
url=req.url,
param=req.params["id"]
)
return Response(body)
After restarting wws
, access http://localhost:8080/python to see the result. The worker will receive python
as the value for the id
parameter.

New documentation
The project documentation is available at workers.wasmlabs.dev. We introduced new sections about the project, supported languages, and new features. We are also introducing more video content for developers (like us) who sometimes prefer videos over text.
Please, feel free to provide feedback and suggestions to our documentation via Twitter or in the project issues.
Your workers, from any language, anywhere
The v1.0.0 release was a bit milestone. The team put a lot of effort into the language runtimes project. We want to provide a seamless developer experience for interpreted languages in WebAssembly. The goal is to make wws
extensible, so you can install new language runtimes without releasing new wws
versions.
In the upcoming weeks, we will publish more tutorials and guides about developing applications with wws
. You can expect new articles, videos, examples, and documentation 🤓.
If you are developing some cool apps with wws
, feel free to show them to us. We are eager to learn what you are building! You can find us on Twitter and in our GitHub repository ⭐️.