Skip to main content

An Introduction to Parcel.js, the No-Config Web Application Bundler

Parcel.js website

Why use a web app bundler?

I won’t spend too much time discussing the reasons for using an app bundler like Parcel.js, because that topic has certainly been covered before. But here’s a basic rundown of the benefits to using such a tool:

  • Your app will have fewer HTTP requests due to scripts or stylesheets being combined
  • Scripts and stylesheets can be loaded on demand, further improving performance
  • Scripts and stylesheets can be automatically minified to deliver fewer kilobytes to the user
  • Bundling and minification work is done automatically by the tool, minimizing manual work
  • Development files are organized modularly, making your code much easier to maintain and debug

As you can see, the benefits are many, and mostly related to performance and project maintenance. There certainly are lots of reasons to use a bundler, if this is something you haven’t yet considered.

With that out of the way, let’s get started with the basics for getting up and running with Parcel.js. I’ll slowly go over the features in this tutorial using some simple examples that you’ll easily be able to follow along with.

Installing Parcel.js

You can install Parcel.js in your terminal using Yarn or npm. For this tutorial, I’ll use npm. Here’s the command to install it globally so you can use it on any project:

npm install parcel-bundler -g

The -g flag installs it globally. If you only want to install it for a single project and add it to your project’s devDependencies in package.json, you can run the same command inside the root folder of the project using the --save-dev flag instead of -g:

npm install parcel-bundler --save-dev

With the global install (which will be the most common use case), you can initiate any given project using the init command. Use the terminal to navigate to the folder you want to use as the root of your application and run:

npm init -y

The -y flag prevents npm from asking any questions, using the defaults for the setup. Assuming my project is called parcel-demo, this creates a package.json file at the root that looks like this:

  "name": "parcel-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  "keywords": [],
  "author": "",
  "license": "ISC"

If you find any of the above confusing due to your lack of familiarity with npm, you can check out my comprehensive tutorial on npm. It’s focused on helping front-end web developers understand the tool.

Creating a file entry point

For a basic project setup, I’m going to use Parcel.js on an index.html file that points to a primary JavaScript file called index.js (as shown in the package.json file). This HTML file will serve as my Parcel entry point. My HTML file will have a script element that points to my JavaScript file, so it will look something like this:

<!doctype html>
  <title>Parcel Demo</title>
    <script src="./js/index.js"></script>

Once I have the correct HTML file and JavaScript file in place, I can start Parcel’s built-in development server by running the following in my terminal inside my project’s folder:

parcel index.html

This starts the server and tells it what file to use as the entry point. As a result, I get the following message in my terminal session:

Server running at http:
√  Built in 887ms.

I can now open http://localhost:1234/ in my browser to view what I’ve built so far. The live server uses live reload and something called hot module replacement. This will automatically update modules on a page without doing a full page refresh. This way I can see the progress of my build in faster increments, as I work.

Once I have Parcel.js running with its server active, any changes I make to a file will automatically rebuild my app each time the file is saved. To see this in action, I’m going to add a simple console log line in my script. This will trigger the following message in my terminal:

$ parcel index.html
Server running at http:
√  Built in 1.08s.
√  Built in 28ms.

Each “Built…” line represents one build, triggered by a change in content and save.

If I want to use my own server, rather than Parcel’s built-in development server, I can use the watch command:

parcel watch index.html

I get the same result in my terminal session, with Parcel.js building my app then waiting for changes:

$ parcel watch index.html
√  Built in 855ms.

The dist/ folder

Once I’ve started Parcel.js either in watch mode or via the built-in server, if I look inside my project’s folder, I’ll see a folder and file structure like the following:

 └───── index.js
 └───── index.html
 └───── js.00a46daa.js

Notice the dist folder that gets created automatically. This is where my production files are; I don’t touch any of these files. Notice that my Parcel build has automatically converted my index.js file to one with a unique cache-friendly version (with a revisioned or “revved” file name). It’s also added a source map file (you can read about source maps in this post).

If I look in my index.html file inside the dist folder, I’ll see the following:

<!doctype html>
  <title>Parcel Demo</title>

    <script src="/js.00a46daa.js"></script>

Notice the dist version of my index.html file points correctly and conveniently to the dist version of my .js file.

If my website includes multiple files that point to the same scripts (for example, about.html, contact.html, etc.), I can use the following command:

parcel index.html about.html contact.html

This tells Parcel that I want to use multiple entry points to build from. I can also use the following command to tell Parcel.js to use all my HTML files as entry points:

parcel *.html

Using Parcel.js with Babel

Parcel.js has built-in support for different code transpilers, including Babel, the popular tool for converting modern next-generation JavaScript to equivalent code that can be understood by all browsers. Because Babel is built into Parcel.js, you don’t need a special plug-in to use it, it just works. Let’s look at an example.

I’m going to add the following code to my index.js file:

function getInfo (name, year = 2018, color = 'blue') {
  console.log(name, year, color);

getInfo('Chevy', 1957, 'Green');
getInfo('Benz', 1975);

This code uses an ES6 feature called default parameters, which you can see specifically in the function head. Older browsers don’t support default parameters for functions. To make sure the code doesn’t throw an error, I need Babel to transpile the code into equivalent code that works in all browsers. Once I’ve saved my index.js file, Parcel.js will rebuild my app and produce the following in place of the ES6 code I wrote:

WordPress Design, WordPress Development, cPanel Hosting, Web Design, Web Development, Graphic Design, Mobile Development, Search Engine Optimization (SEO) and more.