📦 Parcel v1.5.0 released: Source Maps, WebAssembly, Rust, and more! 🚀

Today I’m super excited to release Parcel v1.5.0, the largest release since 1.0! Check it out on Github!

It has been just under 2 months since Parcel’s initial announcement, and the response has been tremendous. As of this writing, we have over 17,000 stars on Github, over half a million downloads on npm, and over 60 contributors who have submitted over 200 pull requests! I am truly blown away. 🙏

Parcel v1.5.0 is a HUGE release. The highlights include:

  • 🗺 JavaScript Source Map support — this was a huge ask from the community, and we have it now. A ton of work went into making sure this is blazing fast, just like the rest of Parcel so you can have good debugging and good build performance together. 🚀
  • ⚙️ WebAssembly support — an emerging technology, this will become more important in the future and enable a diversity of languages on the web and native-level performance. Parcel makes it super easy to get started — we handle many of the details for you with zero configuration!
  • 🦀 Rust → WebAssembly support — continuing on the above, the first language to support compiling to WebAssembly out of the box is Rust! Now you can import a .rs file just like you can .js!
  • 💸 Config files invalidate cache — files like .babelrc are now added as dependencies of your source files. When you change your configuration, everything automatically rebuilds as needed!
  • 🌎 .env file support — now you can specify environment variables needed to build your application in a .env file, or even a deployment environment specific file like .env.production.
  • 🚀 Even faster for smaller projects — Parcel’s multicore approach was fast for large projects, but caused a bottleneck for smaller projects. Now Parcel warms up workers in the background so smaller projects build faster too!
  • 👌 Many bugfixes and improvements!

The best part is that ALL of this was contributed by the community! Thank you all. 🙏

Source Maps

From day one, source maps were one of the most highly requested features that Parcel lacked. Initially, I was concerned about performance generating the source maps. In many tools that I’ve worked with in the past, generating source maps has a huge effect on build times. We wanted to avoid that in Parcel, and keep our builds blazing fast.

These concerns turned out to be founded in reality. The initial version of source map support in Parcel caused a fairly large project to go from a 6 second build time to 53 seconds. This was unacceptable.

After a bit of research and inspiration from the React Native packager, we were able to increase performance almost to the level of non-sourcemap builds. The project now builds in just 800ms longer with sourcemaps than without! This is mainly due to avoiding parsing and re-generating source maps from Babel and other compilers in order to combine them together, and doing more work in parallel.

HUGE thanks to Jasper DeMoor, who implemented source maps and many other features in Parcel lately. 👏

Source Maps are turned on by default in development mode, but can be turned off with the --no-source-maps flag to the Parcel CLI. I hope you enjoy a better debugging experience with Parcel! 😍

WebAssembly

WebAssembly is an emerging technology, but one that will have a huge impact on the web in the near future. Now supported by all major web browsers, as well as Node, WebAssembly will enable a diversity of languages on the web, and not just those that can transpile to JavaScript.

Low-level languages like C and Rust can compile to WebAssembly, which is a binary format for smaller file sizes and faster runtime. Near native-level performance can be had with WebAssembly compiled code, often much faster than equivalent JavaScript. It is likely that we will see JavaScript libraries starting to take advantage of WebAssembly for performance-critical sections of code in the near future.

Parcel makes it extremely easy to get started with WebAssembly. Assuming you already have a .wasm file (see the next section for an even easier way!), you can just import as usual. Both synchronous and asynchronous imports are supported.

// synchronous import
import {add} from './add.wasm';
console.log(add(2, 3));
// asynchronous import
const {add} = await import('./add.wasm');
console.log(add(2, 3));

When synchronously importing a .wasm file, Parcel automatically generates extra code to preload the file prior to executing your JavaScript bundle. This means that the binary WebAssembly file is not inlined into your JavaScript as a string, but actually served as a separate binary file as you’d expect. In this way, your code still works synchronously, but Parcel takes care of loading dependencies for you up front.

This is all enabled by Parcel’s internal support for bundle loaders, which are runtime modules which know how to asynchronously load a particular file format. In prior versions, there were hard-coded bundle loaders for JavaScript and CSS, which enabled dynamic import support. In Parcel v1.5.0, this is completely pluggable — you can define your own bundle loaders in plugins! This will enable lots of cool functionality in the future for custom binary formats like Glimmer’s binary templates, etc. Super excited to see what this enables!

Rust Support

Rust is a systems programming language developed by Mozilla, which offers native performance with some interesting memory and thread safety characteristics. Rust recently added support for compiling to WebAssembly, and now Parcel makes it super easy to get started with zero configuration!

You can now simply import .rs files just like any other file type in Parcel! Assuming you have Rustup installed, Parcel automatically takes care installing the right toolchains, targets, and other build pre-requisites. It works with Cargo projects, as well as straight-up Rust source files, automatically tracks your dependencies so files are watched and rebuilds happen when you save, and more!

Just like with .wasm files, .rs files can be imported with either synchronous or asynchonous imports.

// synchronous import
import {add} from './add.rs';
console.log(add(2, 3));
// asynchronous import
const {add} = await import('./add.rs');
console.log(add(2, 3));

On the Rust side, you just need to make sure that function names aren’t mangled and are public.

#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
return a + b
}

That’s all there is to it! Using Rust on the web could not be simpler. ✨

HUGE thanks to Jose Albizures for contributing Rust support to Parcel! 🙏

Try it out!

Parcel has had a tremendous beginning, but is really just getting started. I can’t wait to see what you do with it!

Please report any bugs you find on Github. You can also find me @devongovett on Twitter.