Discovering Snowpack

In today's article, we'll do some exploring to see what Snowpack is and what are its advantages.

In the last few months, I've heard a lot of talk about Snowpack and I hadn't given it a chance. The time has come.

Snowpack logo

Working with ESM

To understand what Snowpack does, let's see first how to work with ESM directly, without any tools.

Currently, if we want for example to setup a Preact app without any tooling, we can do something like this:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta charset="utf-8" />
    <script type="module" src="index.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css" />
    <title>Example app</title>
  </head>
  <body id="app" />
</html>

Adding the type="module" to the script tag is enough to tell the browser that we are using ESM.

Then, the index.js will be the entrypoint of our Preact app, the top of the Component tree.

index.js

import { html, render } from 'https://unpkg.com/htm/preact/standalone.module.js'
import { Example } from './example.js'

function App() {
  return html`
    <h1>Some example</h1>
    <${Example} />
  `
}

render(html`<${App} />`, document.getElementById('app'))

This works well. However, it has certain drawbacks that current tools such as Webpack or Parcel already solved. Among the most important:

  • Hot reloading in development
  • Importing other files as .json, .css...
  • Tooling as Typescript, JSX, PostCSS, Sass, Babel...
  • Compatibility with legacy browsers
  • Managment of thirty party libraries

So... Why not use Webpack or Parcel to cover this? It may still make sense to use bundlers such as Webpack or Parcel. Let's keep asking... What does a bundler do? Why do we really need a bundler?

Module bundlers

In 2012 there were no ESM and with the arrival of Webpack the use of bunlders began to be relevant. Thanks to them it's possible to use .js files as if they were modules, being able to use import and export everywhere.

Bundlers still make a lot of sense today, since many browsers do not yet support ESM. We can use the same process to minimize and optimize our production code.

The main question here should be "Does it make sense to keep using a bundler in development?" Running your entire application through a bundler introduces additional work and complexity to your dev workflow that is unnecessary now that ESM is widely supported.

Unbundled Development

Snowpack was intended to use an unbundled development, using directly ESM. Among other advantages:

  • Much faster (no-wait build time, reflecting changes immediately)
  • Easier to debug
  • Project size doesn't affect dev speed
  • Simpler tooling
  • Minimal configuration

It also provides a solution to the ESM problems we have mentioned. Although you can do the production build directly with Snowpack, it gives you the flexibility to still optimizing your production builds with Webpack or Parcel.

Image of dog and packages

Preact with Snowpack

Let's create a Preact project with create-snowpack-app CLI:

npx create-snowpack-app preact-snowpack-example --template @snowpack/app-template-preact --use-yarn

Then:

cd preact-snowpack-example
yarn start

After yarn start, in ~50ms we have our Preact dev environment up under http://localhost:8080, with Babel, JSX and familiar Webpack things.

You can test it to see how fast and easy it is.

Example Snowpack with Preact

If you inspect the source code you'll see that ESM is used behind the scenes, with some differences:

import { h, render } from '/web_modules/preact.js' // Uses /web_modules/* for dependencies
import '/web_modules/preact/devtools.js'
import App from './App.js'
import './index.css.proxy.js' // Uses .js files for css imports

Conclusion

We have seen a bit of Snowpack's surface, enough to start understanding how it fits into the JavaScript ecosystem.

I hope this article will make you curious and eager to try Snowpack. It's not a guide, to know more details about Snowpack and ESM I recommend to visit the reference links.

References

Discuss on Dev.toDiscuss on TwitterEdit on GitHub
More...
Power of Partial Prerendering with Bun

Power of Partial Prerendering with Bun

👋 Say Goodbye to Spread Operator: Use Default Composer
Creating Scalable and Reusable React Components

Creating Scalable and Reusable React Components

🏝️ i18n translations in Next.js 13's app-dir for server/client components 🌊