Bundling Your Web App Using Parcel

Published on December 9, 2017


    Bundling Your Web App Using Parcel

    While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

    Parcel is an up-and-coming module bundler that’s extremely fast and that supports HTML, CSS, JavaScript, Image and TypeScript assets out of the box without the need for separate plugins. Best of all, no configuration is needed and it’s as simple as pointing it to an entry file and Parcel takes over with bundling, transforming and minimizing assets.

    Let’s explore how Parcel is used.


    All that’s needed to get started is the parcel-bundler package. Install it globally using npm or Yarn:

    $ npm i -g parcel-bundler
    # or, using Yarn:
    $ yarn global add parcel-bundler


    First, initialize a new npm project:

    $ npm init
    # or, using Yarn
    $ yarn init

    Next, we’ll demonstrate Parcel’s usage with a very simple demo app that contains a main index.html, two JavaScript files and two CSS files. The app has two buttons that change the page’s background color when clicked.

    Here’s the content of our HTML file:

    <!DOCTYPE html>
    <html lang="en">
      <meta charset="UTF-8">
      <title>Color My World</title>
      <link rel="stylesheet" href="./styles.css">
      <div class="controls">
        <button id="color">Color!</button>
        <button id="premium-color">Premium color!</button>
      <script src="./index.js"></script>

    Notice how the paths we use for our styles and script files are relative. This is important for Parcel to work its magic. Other assets like images should also be referenced using relative paths.

    Our entry JavaScript file looks like this:

    'use strict';
    import premiumColors from './premium';
    const colorBtn = document.getElementById('color');
    const premiumColorBtn = document.getElementById('premium-color');
    const availableColors = [
    colorBtn.addEventListener('click', () => {
      const randIdx = Math.floor(Math.random() * availableColors.length);
      document.documentElement.style.setProperty('--bg', availableColors[randIdx]);

    You’ll notice that we’re using ES6 modules here, but Parcel also understands CommonJS syntax. Our second JavaScript file simply contains a default export with our premium colors:

    export default [

    Our main CSS file imports another stylesheet with styles for our buttons and defines style rules for the body element and .controls div:

    @import './button.css';
    body {
      background: var(--bg, paleturquoise);
      height: 100vh;

    And finally, our buttons styles are really simple:

    button {
      background: peachpuff;
      font-size: 1.3em;
      border: none;
      padding: .4em;
      margin: .3em;
      border-radius: 4px;
      box-shadow: 0 0 10px rgba(0,0,0,0.13);

    Parcel also supports SASS, LESS and Stylus out of the box!

    With our simple app ready, we can call parcel and point it to the index.html entry file:

    $ parcel index.html

    Parcel will generate the different bundles in a /dist folder, start a local server at http://localhost:1234/ and start listening for changes.

    You can also specify a different output folder using the --out-dir flag:

    $ parcel index.html --out-dir public

    Parcel also has a watch command to bundle and listen for changes, but without starting a local server:

    $ parcel watch index.html

    When your app is ready for production, you can bundle a production build using the build command:

    $ parcel build index.html

    This will turn off Parcel’s Hot Module Replacement and minimize the JavaScript, CSS and HTML assets (using UglifyJS, cssnano and htmlnano).

    Babel and PostCSS

    On top of bundling, Parcel can, out of the box, perform code transforms using Babel, PostCSS and PostHTML.

    All you have to do is add the necessary dependencies and include the respective configuration files at the root of your project, and Parcel will take care of the rest.

    For example, if you want to want to use PostCSS’s autoprefixer to automatically add vendor prefixes, first install the package:

    $ npm install autoprefixer
    # or, using Yarn:
    $ yarn add autoprefixer

    And then add a .postcssrc file to the root of your project:

      "plugins": {
        "autoprefixer": true

    And that’s it! Now this CSS:

    .controls {
      display: flex;
      justify-content: center;
      align-content: center;
      align-items: center;
      height: 100%;

    Will be transformed to this:

    .controls {
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -webkit-box-pack: center;
          -ms-flex-pack: center;
              justify-content: center;
      -ms-flex-line-pack: center;
          align-content: center;
      -webkit-box-align: center;
          -ms-flex-align: center;
              align-items: center;
      height: 100%;

    You can also specify which browsers to target using Browserlist by adding a .browserslistrc file to your project.


    Parcel even supports TypeScript out of the box. Simply add typescript as a dev dependency to your project:

    $ npm i typescript --save-dev
    # or, using Yarn:
    $ yarn add typescript --dev

    Then create add a tsconfig.json file to your project. For example:

      "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "strict": true

    Now, your index file can point directly at your TypeScript entry file and you call parcel as you would normally and the TypeScript code will automatically be transpilled to JS code:

    <script src="./index.ts"></script>
    $ parcel index.html
    • Check out this post of ours for more help on configuring a new TypeScript project.
    • There’s also a third-party TypeScript plugin for Parcel called parcel-plugin-typescript that has type-checking and error reporting available at build time.

    📦 Now you should be off to the races with Parcel’s zero configuration ease of use and fast bundle generation! To learn more, refer to the official documentation.

    Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

    Learn more about us

    About the authors
    Default avatar


    Still looking for an answer?

    Ask a questionSearch for more help

    Was this helpful?
    Leave a comment

    This textbox defaults to using Markdown to format your answer.

    You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

    Try DigitalOcean for free

    Click below to sign up and get $200 of credit to try our products over 60 days!

    Sign up

    Join the Tech Talk
    Success! Thank you! Please check your email for further details.

    Please complete your information!

    Featured on Community

    Get our biweekly newsletter

    Sign up for Infrastructure as a Newsletter.

    Hollie's Hub for Good

    Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

    Become a contributor

    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

    Welcome to the developer cloud

    DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

    Learn more
    DigitalOcean Cloud Control Panel