JavaScript to Wasi Enabled Wasm: Portable JavaScript Composition

Rate this content
Bookmark

JavaScript is no longer a language confined to the browsers. New standards are enabling fully portable, lightweight runtimes, to make JavaScript the definitive language for isomorphic applications. 

Let's explore use-cases, some experimental, some consolidated, to take our Wasm game with JavaScript, to the next level.

This talk has been presented at DevOps.js Conf 2024, check out the latest edition of this JavaScript Conference.

FAQ

WebAssembly provides enhanced security by executing in a completely encapsulated sandbox environment. This isolation ensures memory safety, prevents WebAssembly code from accessing or modifying memory outside its designated boundaries, and limits direct interaction with other processes. Such features help reduce the risk of malicious activities and supply chain attacks.

JavaScript can interact with WebAssembly modules using the WebAssembly JavaScript API. This interaction typically involves importing a Wasm module into a JavaScript context, compiling it, and creating an instance of the module. JavaScript can then invoke exported WebAssembly functions directly, allowing seamless integration between the two.

JavaScript engines like V8, Chakra, and SpiderMonkey are responsible for parsing JavaScript code, creating an abstract syntax tree (AST), and generating binary code that executes in the browser. These engines also handle the runtime environment for JavaScript and provide the necessary infrastructure to execute WebAssembly modules.

WASI, or WebAssembly System Interface, is a standard that enables WebAssembly to run outside of the browser in a secure and portable manner. It provides system interfaces that are compatible with POSIX, allowing WebAssembly modules to interact with system resources in a controlled environment.

WebAssembly allows web applications to run CPU-intensive operations at a lower level than typical JavaScript code, leading to improved performance. By compiling code into a highly optimized binary format that executes closer to the hardware, WebAssembly can handle complex tasks more efficiently than JavaScript.

Yes, WebAssembly can run in non-browser environments by utilizing additional interfaces such as the WebAssembly System Interface (WASI). WASI enables WebAssembly to operate in a special runtime that can even run on bare metal, supporting a modular system interface compatible with POSIX systems.

WebAssembly (Wasm) is not a programming language but a binary instructions format that serves as a compilation target. This means developers can write code in various supported languages and compile it into binary format as Wasm to run at a low level. WebAssembly operates on the basis of imports and exports, allowing integration with JavaScript via specific bindings or APIs.

Natalia Venditto
Natalia Venditto
21 min
15 Feb, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
JavaScript code is converted to low-level binaries by JavaScript engines like MV8, Chakra, and SpiderMonkey. WebAssembly allows writing code in other languages and compiling it to run on a JavaScript engine. External functions can be imported in WebAssembly using the import statement. WebAssembly can run in non-browser scenarios with additional interfaces like WASI and provides memory isolation. The Jco toolchain is an experimental tool for componentizing JavaScript code into WASM modules.

1. Introduction to JavaScript and WebAssembly

Short description:

I'm a principal lead for JavaScript developer experience on Azure, covering integrations, hosting services, and compute. JavaScript code goes through a flow of execution on the browser, from parsing to code generation. JavaScript engines like MV8, Chakra, and SpiderMonkey convert the code to low-level binaries. WebAssembly is a binary instructions format that allows us to write code in other languages and compile it to run on a JavaScript engine. It works based on imports and exports.

Hello, everyone. My name is Natalia Bendito and I'm a principal lead for JavaScript developer experience end-to-end across the many services and tools that can be used by JavaScript developers to build applications on Azure. That ranges from integrations like GitHub Actions to VS Code extensions, hosting services like Azure Static Web Apps, or compute like Azure Container Apps or Azure Functions.

When we build JavaScript applications, we know that our code or scripts are basically going to go through this flow of execution on the browser. Each instruction goes through this just-in-time journey. The parser or JavaScript engine generates a hierarchical structure called the abstract syntax tree or AST. For example, a variable declaration is a CAPS, variable CAPS declaration, node construct in AST, which the interpreter reads and generates high-level binary code or byte code from. Finally, the compiler generates low-level binary code that speaks to the CPU in a way that can be understood according to the processor or CPU architecture. All of this again happens just-in-time. This flow is mostly the work of the JavaScript engine. MV8 is one of the most popular, but there is also Chakra, there's SpiderMonkey, there are others. The generated machine code may be optimized for a specific set of instructions that are, again, optimal for a specific architecture, as we mentioned before. This means we are converting our high-level JavaScript code to low-level binaries. JavaScript engines can take care of the initialization of the environment or do take care of the initialization of the environment. They add built-in functions and they also handle or run our application code. The engine also provides the runtime, where the application is going to be running on. JavaScript scripts run on a JavaScript engine, obviously, but what does also run on a JavaScript engine, if you can think about it, at that low level, by the way? That's, of course, WebAssembly.

What is WebAssembly more concretely, or Wasm, as some may refer to? It's not really a language. It's a binary instructions format. Compilation target means that we write our code in the language we prefer as long as it has a Wasm tool chain or compiler that allows us to do so and we compile it to binary as Wasm to run at that low level that we were describing before. How does WebAssembly actually work? Let's imagine we have a program written in C, C++, RAS, or any other language that is supported, and we want to compile it to Wasm. We use its corresponding tool chain or a set of developer tools, and that's what I meant before by is supported. It has this set of developer tools and compilers, which will emit that code as a module, which imports and with imports, sorry, and exports. Then we can import it into our JavaScript to be run with a JavaScript engine using WebAssembly JavaScript bindings or the JavaScript API. Wasm does not really define any APIs. It works like we mentioned on the basis of imports and exports. This is an example of a module written in WebAssembly text. Let's walk through this cycle. If I was going to describe each one of the lines and things that are in this code, it would take a very long time, and it would be a little bit exhausting. But we can define the sections.

2. Using External Functions in WebAssembly

Short description:

The import statement is used to import an external function, such as println from the environment module. The function section exports the function hello world. The memory section declares the size of the memory, and the data section initializes the memory with a string. When importing the module in JavaScript, we fetch the module, process the response, compile the binary data, and create an instance of the module. We can redirect the output of the print line function to console.log. WebAssembly allows us to run CPU-intensive operations at a lower level and compose user interfaces. Page find is an example of using WebAssembly for document ingestion, indexing, and full-text search on the client side. We can achieve this in a static website using WebAssembly.

I think that it's important to start with the import statement that is used to import an external function because we don't have anything in the Wasm native APIs. We are importing this external function named println from a module called environment. This function takes a single parameter of type I32 or 32 bit integer. The important function is given the name dollar println.

Now in the next section, we have the function section. The function is exported with the name hello underscore world. Then we have another section, the memory section, which basically declares the size of the memory. In this case, one page. Finally, we have the data section that initializes the memory, in this case at offset zero with a utf-8 string, hello world of JavaScript.

Now what I think is really interesting is what happens in the JavaScript that is importing this module or fetching this module. We're fetching the module we exported to a file named hello underscore world.wasm. Then the response is processed using response.arrive buffer to obtain the module's binary data. We then use the WebAssembly.compile function to compile the binary data we got from the previous step into a WebAssembly module. We use the WebAssembly.instance constructor to create an instance of the compiled WebAssembly module. As you can see, there is an environment object provided in the second parameter of the constructor, which includes an important function named print line. Do you remember the previous what file? This important function is mapped to console log. The purpose of this mapping is to redirect any output of the WebAssembly module's print line function, as defined in the WebAssembly text code that we provided before, to the JavaScript console.log function. And finally, the exported function hello underscore world is invoked from the WebAssembly module using instance.exports.hello world or hello underscore world.

Since we have the ability to fetch and run Wasm, as we just saw, as part of our JavaScript programs, we can compose user interfaces where we run CPU intensive operations at a much lower level or lower level than our typical JavaScript programs run in a more performant way. Let's explore a specific use case of this type of composition. Let's propose we have a static website, like one site created with any meta framework today, like Astro11t and so on, using static data fetching. And we want to run a search functionality for that static content. Well, we can do it with JavaScript client side, but we can also use WebAssembly. So let's use it. And page find is a great example of a Wasm feature that does, in this case, document ingestion, indexing, and runs full text search, filtering, sorting, et cetera, all on the client side at a very low level in WebAssembly. Let me show you now exactly how page find works. We're on the documentation site, but we will go to Starlight, a framework to build documentation sites with Astro. If we pay attention to the top left, we see we have a search bar. Although this is a static generated site, how does this work? Let's run a search for something like div. We notice we get immediate results.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Modern Web Debugging
JSNation 2023JSNation 2023
29 min
Modern Web Debugging
Top Content
This Talk discusses modern web debugging and the latest updates in Chrome DevTools. It highlights new features that help pinpoint issues quicker, improved file visibility and source mapping, and ignoring and configuring files. The Breakpoints panel in DevTools has been redesigned for easier access and management. The Talk also covers the challenges of debugging with source maps and the efforts to standardize the source map format. Lastly, it provides tips for improving productivity with DevTools and emphasizes the importance of reporting bugs and using source maps for debugging production code.
Utilising Rust from Vue with WebAssembly
Vue.js London Live 2021Vue.js London Live 2021
8 min
Utilising Rust from Vue with WebAssembly
Top Content
In this Talk, the speaker demonstrates how to use Rust with WebAssembly in a Vue.js project. They explain that WebAssembly is a binary format that allows for high-performance code and less memory usage in the browser. The speaker shows how to build a Rust example using the WasmPack tool and integrate it into a Vue template. They also demonstrate how to call Rust code from a Vue component and deploy the resulting package to npm for easy sharing and consumption.
The Future of Performance Tooling
JSNation 2022JSNation 2022
21 min
The Future of Performance Tooling
Top Content
Today's Talk discusses the future of performance tooling, focusing on user-centric, actionable, and contextual approaches. The introduction highlights Adi Osmani's expertise in performance tools and his passion for DevTools features. The Talk explores the integration of user flows into DevTools and Lighthouse, enabling performance measurement and optimization. It also showcases the import/export feature for user flows and the collaboration potential with Lighthouse. The Talk further delves into the use of flows with other tools like web page test and Cypress, offering cross-browser testing capabilities. The actionable aspect emphasizes the importance of metrics like Interaction to Next Paint and Total Blocking Time, as well as the improvements in Lighthouse and performance debugging tools. Lastly, the Talk emphasizes the iterative nature of performance improvement and the user-centric, actionable, and contextual future of performance tooling.
Making JavaScript on WebAssembly Fast
JSNation Live 2021JSNation Live 2021
29 min
Making JavaScript on WebAssembly Fast
Top Content
WebAssembly enables optimizing JavaScript performance for different environments by deploying the JavaScript engine as a portable WebAssembly module. By making JavaScript on WebAssembly fast, instances can be created for each request, reducing latency and security risks. Initialization and runtime phases can be improved with tools like Wiser and snapshotting, resulting in faster startup times. Optimizing JavaScript performance in WebAssembly can be achieved through techniques like ahead-of-time compilation and inline caching. WebAssembly usage is growing outside the web, offering benefits like isolation and portability. Build sizes and snapshotting in WebAssembly depend on the application, and more information can be found on the Mozilla Hacks website and Bike Reliance site.
Crafting the Impossible: X86 Virtualization in the Browser with WebAssembly
JSNation 2022JSNation 2022
21 min
Crafting the Impossible: X86 Virtualization in the Browser with WebAssembly
ChirpX is a technology to securely run binary code in the browser, written in C++ and compiled to JavaScript WebAssembly. It can run a full virtualized system in the browser, including Bash and other languages like Python and JavaScript. ChirpX aims for scalability and the ability to work with large code bases, supporting multiprocessing and multithreading. It uses a two-tiered execution engine with an interpreter and a JIT engine. Future plans include running the full X.Org server in the browser and implementing the Windows system call. WebVM, the underlying technology, has a virtual file system backed by Cloudflare.
pnpm – a Fast, Disk Space Efficient Package Manager for JavaScript
DevOps.js Conf 2022DevOps.js Conf 2022
31 min
pnpm – a Fast, Disk Space Efficient Package Manager for JavaScript
Watch video: pnpm – a Fast, Disk Space Efficient Package Manager for JavaScript
pnpm is a fast and efficient package manager that gained popularity in 2021 and is used by big tech companies like Microsoft and TikTok. It has a unique isolated node module structure that prevents package conflicts and ensures each project only has access to its own dependencies. pnpm also offers superior monorepo support with its node module structure. It solves the disk space usage issue by using a content addressable storage, reducing disk space consumption. pnpm is incredibly fast due to its installation process and deterministic node module structure. It also allows file linking using hardlinks instead of symlinks.

Workshops on related topic

React, TypeScript, and TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
Mastering advanced concepts in TypeScript
React Summit US 2023React Summit US 2023
132 min
Mastering advanced concepts in TypeScript
Top Content
Featured WorkshopFree
Jiri Lojda
Jiri Lojda
TypeScript is not just types and interfaces. Join this workshop to master more advanced features of TypeScript that will make your code bullet-proof. We will cover conditional types and infer notation, template strings and how to map over union types and object/array properties. Each topic will be demonstrated on a sample application that was written with basic types or no types at all and we will together improve the code so you get more familiar with each feature and can bring this new knowledge directly into your projects.
You will learn:- - What are conditional types and infer notation- What are template strings- How to map over union types and object/array properties.
Integrating LangChain with JavaScript for Web Developers
React Summit 2024React Summit 2024
92 min
Integrating LangChain with JavaScript for Web Developers
Featured Workshop
Vivek Nayyar
Vivek Nayyar
Dive into the world of AI with our interactive workshop designed specifically for web developers. "Hands-On AI: Integrating LangChain with JavaScript for Web Developers" offers a unique opportunity to bridge the gap between AI and web development. Despite the prominence of Python in AI development, the vast potential of JavaScript remains largely untapped. This workshop aims to change that.Throughout this hands-on session, participants will learn how to leverage LangChain—a tool designed to make large language models more accessible and useful—to build dynamic AI agents directly within JavaScript environments. This approach opens up new possibilities for enhancing web applications with intelligent features, from automated customer support to content generation and beyond.We'll start with the basics of LangChain and AI models, ensuring a solid foundation even for those new to AI. From there, we'll dive into practical exercises that demonstrate how to integrate these technologies into real-world JavaScript projects. Participants will work through examples, facing and overcoming the challenges of making AI work seamlessly on the web.This workshop is more than just a learning experience; it's a chance to be at the forefront of an emerging field. By the end, attendees will not only have gained valuable skills but also created AI-enhanced features they can take back to their projects or workplaces.Whether you're a seasoned web developer curious about AI or looking to expand your skillset into new and exciting areas, "Hands-On AI: Integrating LangChain with JavaScript for Web Developers" is your gateway to the future of web development. Join us to unlock the potential of AI in your web projects, making them smarter, more interactive, and more engaging for users.
From Todo App to B2B SaaS with Next.js and Clerk
React Summit US 2023React Summit US 2023
153 min
From Todo App to B2B SaaS with Next.js and Clerk
WorkshopFree
Dev Agrawal
Dev Agrawal
If you’re like me, you probably have a million side-project ideas, some that could even make you money as a micro SaaS, or could turn out to be the next billion dollar startup. But how do you know which ones? How do you go from an idea into a functioning product that can be put into the hands of paying customers without quitting your job and sinking all of your time and investment into it? How can your solo side-projects compete with applications built by enormous teams and large enterprise companies?
Building rich SaaS products comes with technical challenges like infrastructure, scaling, availability, security, and complicated subsystems like auth and payments. This is why it’s often the already established tech giants who can reasonably build and operate products like that. However, a new generation of devtools are enabling us developers to easily build complete solutions that take advantage of the best cloud infrastructure available, and offer an experience that allows you to rapidly iterate on your ideas for a low cost of $0. They take all the technical challenges of building and operating software products away from you so that you only have to spend your time building the features that your users want, giving you a reasonable chance to compete against the market by staying incredibly agile and responsive to the needs of users.
In this 3 hour workshop you will start with a simple task management application built with React and Next.js and turn it into a scalable and fully functioning SaaS product by integrating a scalable database (PlanetScale), multi-tenant authentication (Clerk), and subscription based payments (Stripe). You will also learn how the principles of agile software development and domain driven design can help you build products quickly and cost-efficiently, and compete with existing solutions.
Building Pinia From Scratch
Vue.js Live 2024Vue.js Live 2024
70 min
Building Pinia From Scratch
Workshop
Eduardo San Martin Morote
Eduardo San Martin Morote
Let's dive into how Pinia works under the hood by building our own `defineStore()`. During this workshop we will cover some advanced Vue concepts like dependency Injection and effect scopes. It will give you a better understanding of Vue.js Composition API and Pinia. Requirements: experience building applications with Vue and its Composition API.
Mastering 3D Web Development with TresJS ecosystem: A Vue.js Workshop
Vue.js Live 2024Vue.js Live 2024
119 min
Mastering 3D Web Development with TresJS ecosystem: A Vue.js Workshop
Workshop
Alvaro Saburido
Alvaro Saburido
Introducing "Mastering 3D Web Development with TresJS," a specialized workshop crafted for Vue.js developers eager to explore the realm of 3D graphics within their web applications. TresJS, a powerful custom renderer for Vue, is specifically designed to work seamlessly with Vue's reactive system. This workshop offers a deep dive into integrating sophisticated 3D visualizations and interactive experiences directly into Vue applications, leveraging the unique strengths of both Vue and TresJS ecosystems.
This workshop is designed for Vue.js developers looking to expand their skill set into the third dimension, UI/UX designers interested in incorporating 3D elements into web applications, and front-end developers curious about the potential of 3D graphics in enhancing user experiences. You'll need to be familiar with Vue.js to benefit from this workshop fully.
What You Will Learn- Introduction to TresJS: Discover the fundamentals of TresJS and how it integrates with the Vue ecosystem to bring 3D graphics to life.- Creating 3D Scenes with Vue: Learn to construct intricate 3D scenes utilizing Vue components, enhancing your user interfaces with dynamic and immersive visuals.- Interactivity and Animation: Master the techniques to make your 3D scenes interactive, responding to user inputs for a captivating user experience.- Integrating with Vue Features: Explore advanced integration of TresJS with Vue’s reactivity, composables, and the Vuex store to manage state in 3D web applications.- Performance and Best Practices: Gain insights into optimizing your 3D scenes for performance and best practices to maintain smooth, responsive web applications.