Michael Yuan
Michael Yuan is the founder and maintainer of WasmEdge, an open-source WebAssembly runtime hosted by the CNCF for edge computing, service mesh, and embedded functions. Dr. Yuan is the author of six books on software engineering, and a long-time open source contributor. He is the co-founder of Second State, a venture-funded startup that supports and commercializes enterprise applications in the WebAssembly and Rust ecosystem.
Vercel is a leading platform for developing and hosting Jamstack applications. Unlike traditional web apps, where the UI is dynamically generated at runtime from a server, a Jamstack application consists of a static UI (in HTML and JavaScript) and a set of serverless functions to support dynamic UI elements via JavaScript.
There are many benefits to the Jamstack approach. But perhaps one of the most significant benefits is performance. Since the UI is no longer generated at runtime from a central server, there is much less load on the server and we can now deploy the UI via edge networks such as CDNs.
However, the edge CDN only solves the problem of distributing the static UI files. The backend serverless functions could still be slow. In fact, popular serverless platforms have well-known performance issues, such as slow cold start, especially for interactive applications. That’s where WebAssembly could help.
With WasmEdge, a cloud native WebAssembly runtime hosted by the Cloud Native Computing Foundation, developers can write high-performance serverless functions deployed on the public cloud or on edge computing nodes. In this article, we will explore how to use WasmEdge functions, written in Rust, to power a Vercel application backend.
The Vercel platform already has a very easy-to-use serverless framework for deploying functions hosted in Vercel. As we discussed above, the reason to use WebAssembly, and WasmEdge, is to further improve performance. High-performance functions written in C/C++, Rust, and Swift can be easily compiled into WebAssembly. Those WebAssembly functions are much faster than JavaScript or Python commonly used in serverless functions.
However, if raw performance is the only goal, why not just compile those functions to machine native executables? That is because the WebAssembly “container” still provides many valuable services.
For starters, WebAssembly isolates the function at runtime. Bugs or memory safety issues in the code will not propagate out of the WebAssembly runtime. As the software supply chain gets more complex over time, it is important to run code in containers to prevent unauthorized access to your data by dependency libraries.
Second, the WebAssembly bytecode is portable. Developers only need to build it once and do not need to worry about changes or updates to the underlying Vercel serverless container (OS and hardware) in the future. It also allows developers to reuse the same WebAssembly functions in alternative hosting environments, such as in another public cloud such as Tencent Serverless Functions, or in a data streaming framework like YoMo.
Finally, the WasmEdge Tensorflow API provides the most ergonomic way to execute Tensorflow models in the Rust programming language. WasmEdge installs the correct combination of Tensorflow dependency libraries, and provides a unified API for developers.
Enough with the concepts and explanations. Without further ado, let’s jump into the example apps!
Since our demo WebAssembly functions are written in Rust, you will need a Rust compiler. Make sure that you install the wasm32-wasi compiler target as follows, in order to generate WebAssembly bytecode.
$ rustup target add wasm32-wasi
The demo application front end is written in Next.js, and deployed on Vercel. We will assume that you already have the basic knowledge of how to work with Vercel.