Join 5000+ subscribers and get tips for engineering leaders once a month

Back to all posts

Parcel: The Webpack Alternative with Zero Configuration

Posted by James Kolce on May 29, 2018

Building a website has become a complicated process over the years. Writing simple HTML, CSS and JavaScript is no longer the preferred method for the task, either because it’s too dull or too inefficient and error-prone. New tools like frameworks—or even whole new languages—have made the development process more dynamic and efficient. However, while the process has improved once the setup is working, the amount of work to get there in the first place can be tedious and overly complicated.

The most popular tool to coordinate multiple compilation processes and packaging of components into their distributable form is webpack, but the tedious process of configuring webpack is as infamous as the tool itself.

An alternative to webpack

Parcel comes to the rescue by making a bold claim: you can build your website with the technologies you love—including Babel, React, Vue.js, TypeScript, PostCSS, and PostHTML—without having to touch a hard-to-decipher configuration file again. It automatically understands the formats that you are using and puts everything together. Keep in mind, however, that this applies only to Parcel itself. In your project, you might still need to include some technology-specific files, for example, a .babelrc or a .postcssrc if you are using Babel or PostCSS, respectively.

However, true efficiency is more than just not requiring configuration to get started; it’s also about being fast in the development process. Parcel includes a development web server that allows to instantly see changes in the browser by using hot module replacement—what you change is automatically updated in the browser without reloading the page—and thanks to its multicore support, it can be up to twice as fast as webpack or browserify.

Getting Started: A Simple Static Website

It’s true that web applications occupy first place in overall complexity, but static websites remain a particular case. With a static website, all the complications tend to go into the setup instead of any programming that you might do, which most of the time is nonexistent. Parcel solves this problem more elegantly. Instead of preparing boilerplates with a lot of moving parts, we can just write our code in the languages we chose and start being productive.

Let’s see how a regular static site can be built that uses Pug as the templating language that compiles to HTML, PostCSS to transform the custom features that we choose in our CSS (postcss-type-scale and postcss-lh in this example) and Babel to write ES6+ that gets compiled to ES5 using the env preset.

In an empty directory, create a package.json file:

npm init -y

And install all the dependencies mentioned before:

npm install -D parcel-bundler postcss-type-scale postcss-lh autoprefixer babel-preset-env

Note that we don’t have to install Babel, PostCSS or Pug. They are provided by Parcel, and you just install the packages that are used with them.

Open the package.json file and add the following scripts:

"scripts": {
  "start": "parcel src/index.pug",
  "build": "parcel build src/index.pug"

Add the standard HTML boilerplate using Pug in a layout.pug file:

doctype html
	title Demo page
	link(rel='stylesheet' href='./styles/main.pcss')

	block content

Notice the path of the resources that we are using; Parcel picks up any path that starts with ./. Also, we include the extension of the source language that we are writing, as you can see in the main.pcss which is a PostCSS file, instead of the regular CSS extension. After the compilation is finished, the paths are updated pointing to the appropriate files.

Then create an index.pug with some simple content. Here, layout is the path to the file we created previously (the extension is not mandatory in Pug):

extends layout

block content
  h1 Hello

For the styles, let’s use PostCSS. We have included support for an lh unit and for simple font-size definitions, here is the content of main.pcss:

@import './_variables.pcss';

:root {
  line-height: 1.5;
  font-size: var(--font-size);

h1 {
  font-size: 6;
  margin-bottom: 1lh;

As in the Pug template, we can @import other PostCSS files, and they get compiled and merged into a single file at the end. There is no need to add a PostCSS plugin to support imports. 

In the _variables.pcss file we can have something like this, as we are using the --font-size variable in the main file:

:root {
  --font-size: 16px;

Create the .postcssrc file containing the two plugins mentioned before:

  "plugins": {
	"postcss-type-scale": true,
	"postcss-lh": true,

Because we are not using any configuration in those plugins, we add the value of “true” to each key, and in case we need to adjust something we can add an object instead.

The last main component is JavaScript. We have decided to include our scripts written in ES6+ using Babel. The following is the content of the main.js file:

import { appendTo } from './lib.js';

appendTo('h1', 'World!')

and in lib.js:

export function appendTo (tag, content) {
  const node = document.getElementsByTagName(tag)[0];
  node.textContent += ' world!';

As in PostCSS, we have to include the Babel configuration file (.babelrc) to indicate that we want to use the Env preset:

  "presets": ["env"]

Done. The is no need to indicate how we want to compile our files or anything like that. Just start the server to see the project working by running the start command in the terminal:

npm start

In the end, you can get the plain HTML/CSS/JS to put your site online in any hosting provider, just run the build command:

npm run build

You might be thinking that this sounds good for a simple static site, but what about complex projects where JS frameworks are involved? The good news is that the same process applies to most cases, including React or Vue.js. For example, let’s say you want to turn this project into a Vue.js application: all you have to do is to import the Vue.js component into your main.js file (assuming there is a div#app element in your Pug template and a Vue.js component called App.vue already created):

import Vue from 'vue'

// The Vue.js component
import App from './App.vue'

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }

The NPM commands that we have (npm start and npm run build) remain the same to run the server or to compile the distributable files, respectively. Parcel automatically detects the Vue.js component and makes the necessary transformations; there is no need to make any further adjustments. The only difference is when you want to work with a technology that is not yet supported by Parcel. In those cases you might need to do a bit of programming to integrate it yourself.

Customization: A Note for Edge-cases

If you like to experiment with languages and frameworks, there might be cases where your chosen technologies are not included in Parcel by default. In such situations, it’s usually just a matter of finding the right plugin for the job; a quick search in NPM for packages prefixed with parcel-plugin- can give you an idea of the possibilities.

Also, regarding customization, Parcel has an API available that allows you to change the default behavior, to add extra functionality to the build process, or to integrate it into a larger system. You have a couple of options (available in the CLI as well) to change things like the output path and the minification process, or to execute code at certain events, or to use Parcel as middleware for Node.js in a framework like Express.

Check out the API documentation for details.

Final Words

Parcel keeps itself to the promise of zero configuration for most cases. It’s not only useful to pack everything for production, but also useful in the development phase to quickly write code in technologies that you like without having to worry about configuring everything by yourself. The included web server can be handy if the project is a client application or a simple static website. In this sense, you can imagine Parcel not only as a bundler but also as a development environment for the technologies that you love to use.

Enter your email below to be served up tasty tutorials, informative articles and ButterCMS updates to keep your work running smoothly.

Get started now

Sign up with Google Sign up with Github