DEV Community

Cover image for I'm going to give Snowpack a try now ️📦
Pascal Thormeier
Pascal Thormeier

Posted on • Edited on

I'm going to give Snowpack a try now ️📦

Last week, I didn't have much to write about, so I tried to learn about Brunch and documented my journey. I'll link this journey at the end of this post. User YJDoc2 suggested to also have a look at Snowpack. I heard a bit about Snowpack before (mainly a tweet or two telling how awesome it was), but haven't used it myself. Time to change exactly that!

Let's have a look

Ok, so the website says that Snowpack is the "faster frontend build tool":

Screenshot of the official Snowpack website

Brunch managed to start between 70 and 100ms. I suspect Snowpack to be in that ball park as well, I mean, this thing has to execute something, right? Brunch already had its problems when Tailwind was added to the build and suddenly we were talking about 70 and 100hms (err, hecto-milli-seconds, basically seconds divided by ten... I should've just written 7-10s. Or deciseconds? ds? Whatever.). But that was mostly PostCSS. I actually suspect the same thing to happen here: A lot of tools (like TypeScript, JSX, CSS, etc.) supposedly work out of the box, but PostCSS needs a plugin. TypeScript is also supported at "build only" and extra type checking would need an extra plugin. Fair enough, I don't expect my build tool to handle everything from the start. But that TypeScript stuff does sound interesting.

(The attentive reader might've caught that I was referencing the docs. I'm not gonna do the same mistake again and just get going without knowing how!)

Boilerplating

Same setup as last time: Tailwind + Alpine. Maybe I should change that to a more complex setup to really see where the tool starts to work against me and find possible pit falls, but those two things should do the trick for now.

I'm actually starting to wonder if there's an Alpine-like framework written in TypeScript. Alpine is written in plain ol' JS, so with the stack above I can't really test the TS capabilities of the build tool without having to write custom stuff. Just thinking aloud here... But maybe I'll just write a show/hide component in TS to use with Alpine and see if that plays out nice.

Anyways, I'm eager to try Snowpack now. npm init and lot's of hitting enter it is. I'm really curious about the supposed speed of this tool. So instead of installing a lot of things, I just install Snowpack itself, add the "start" and "build" commands to package.json and add an index.html containing a Hello World:

<!DOCTYPE html>
<html>
<head></head>
<body>
  <h1>Hello, World!</h1>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

And now I type npm run start and slooowly hit the enter button...

Woah

Seriously, woah. That dev server is basically instant. Gimme a sec, that caught me off guard...

It did log something to the CLI, that much I can tell, but I wasn't even able to read a single word before my browser jumped right in my face, eager to greet the planet like an over-motivated hamster on its first day at its dream job.

I want to know what snowpack wanted to tell me before the browser interrupted it, though, so let's have a look:

> snowpack dev

[snowpack] Hint: run "snowpack init" to create a project config file. Using defaults...
[snowpack] Welcome to Snowpack! Because this is your first time running
this project, Snowpack needs to prepare your dependencies. This is a one-time step
and the results will be cached for the lifetime of your project. Please wait...
[snowpack] No dependencies detected. Ready!
[snowpack] Server started in 8ms.
[snowpack] Local: http://localhost:8080
[snowpack] Network: http://192.168.1.50:8080
Enter fullscreen mode Exit fullscreen mode

Well, hello Snowpack. The browser was faster.

Wait - 8ms? Are you kidding me? How does it do that? It does feel right, though. (As if I could tell the difference between 8 and 80ms...)

Snowpack apparently used its built-in defaults here. I don't think adding a basic config file would slow it down much. I'm amazed that it just works as a plain server, too. Usually I use serve to quickly look at some built stuff, but this thing feels way faster. I think I'll get rid of serve on my system and just use Snowpack instead.

Back to business. Snowpack tells me to create a project config file with snowpack init, so I'm doing just that and do a re-run to see if that has any impact.

Nope, no impact. That thing stays super fast.

Let's get back to boilerplating

The Snowpack documentation has a guide on how to set up PostCSS. I'll follow just that and alter the package.json, add a postcss.config.js and an index.css.

Snowpack config:

// Snowpack Configuration File
// See all supported options: https://www.snowpack.dev/reference/configuration

/** @type {import("snowpack").SnowpackUserConfig } */
module.exports = {
  mount: {},
  plugins: [
    "@snowpack/plugin-postcss"
  ],
  packageOptions: {},
  devOptions: {},
  buildOptions: {},
}
Enter fullscreen mode Exit fullscreen mode

The package.json:

{
  "name": "snowpack-tryout",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "snowpack dev",
    "build": "snowpack build"
  },
  "author": "",
  "license": "",
  "devDependencies": {
    "@snowpack/plugin-postcss": "^1.2.2",
    "autoprefixer": "^10.2.5",
    "snowpack": "^3.1.2"
  },
  "dependencies": {
    "tailwindcss": "^2.0.4"
  }
}
Enter fullscreen mode Exit fullscreen mode

Postcss config:

// postcss.config.js
// Taken from: https://tailwindcss.com/docs/installation#using-tailwind-with-postcss
module.exports = {
  plugins: [
    require('tailwindcss'),
    require('autoprefixer'),
  ],
}
Enter fullscreen mode Exit fullscreen mode

And index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Nothing out of the ordinary, right? Right. Let's try this again:

Server the starting is fast, loading stuff is slow

As you can see, the server still starts in around 10ms, which is awesome, but the entire Tailwind thing needs its 10s. Instead of waiting for the browser window to open, I wait for stuff to load instead. Fair enough, it has to execute the entire Tailwind stuff somewhen. But the hot reloading is blazing fast:

Blazing fast hot reloading

Not too bad at all! Now I wanna get some TypeScript and Alpine in there.

TypeScript + Alpine

I install Alpine by executing npm i alpinejs and create a simple index.ts:

import 'alpinejs'
Enter fullscreen mode Exit fullscreen mode

(Yup, that's all so far)

And I adjust index.html a little:

<!-- ... -->
  <h1 
      class="text-4xl text-red-600" 
      x-data="{ text: 'Hello, World' }" 
      x-text="text"
  ></h1>

  <script type="module" src="index.js"></script>
<!-- ... -->
Enter fullscreen mode Exit fullscreen mode

No server restart, no nothing, it just works™. Hot reloading is fast as always, so the entire thing apparently didn't slow down Snowpack at all. I'm still amazed.

Next up, a little Alpine component:

interface TabNav {
  init: () => void
  show: (selector: string) => void
}

export default (): TabNav => ({
  init (): void {
    console.log(this.$el)
  },

  show (selector: string): void {
    this.$el
      .querySelectorAll(`.content:not(${selector})`)
      .forEach((el: HTMLElement) => {
        el.classList.add('hidden')
      })
    this.$el.querySelector(selector).classList.remove('hidden')
  }
})
Enter fullscreen mode Exit fullscreen mode

This I can import in my index.ts:

import 'alpinejs'
import tabNav from './tabNav'

// @ts-ignore
window.tabNav = tabNav
Enter fullscreen mode Exit fullscreen mode

And then it can be used with some DOM:

<!-- ... -->
  <div x-data="tabNav()" x-init="init">
    <ul class="flex">
      <li class="p-4 cursor-pointer" @click="show('#a')">Show A</li>
      <li class="p-4 cursor-pointer" @click="show('#b')">Show B</li>
      <li class="p-4 cursor-pointer" @click="show('#c')">Show C</li>
    </ul>

    <div id="a" class="content">
      Content A
    </div>
    <div id="b" class="content hidden">
      Content B
    </div>
    <div id="c" class="content hidden">
      Content C
    </div>
  </div>
<!-- ... -->
Enter fullscreen mode Exit fullscreen mode

Instant. It really actually positively just works. Amazing. I'm convinced.

Summary

I haven't tried the native Svelte integration yet, but if it works like the rest of it, this will probably blow my mind even more. The TypeScript support works with no additional config or even an extra package. If your IDE does the extra type checking Snowpack mentions, you don't even need that.

Zero-config, blasting off at what feels like near light-speed, TypeScript out of the box. I mean, what's not to love?

About Brunch

Here's the article I mentioned above:


I hope you enjoyed reading this article as much as I enjoyed writing it! If so, leave a ❤️ or a 🦄! I write tech articles in my free time and like to drink coffee every once in a while.

If you want to support my efforts, buy me a coffee or follow me on Twitter 🐦! You can also support me directly via Paypal!

Buy me a coffee button

I want to thank Martina who supported me two weeks ago!

Top comments (10)

Collapse
 
pavelloz profile image
Paweł Kowalski • Edited

Heh, recently our webpack (and tailwind) build was getting slow, so we did some research and turned out swapping, configuring is also making a huge difference without boiling the ocean.

Take a look at some of my recent posts to see details (tldr: esbuid-loader, tailwindcss jit, ignoring node_modules in css processing)

I hope one day we wont need build step altogether... :)

Collapse
 
thormeier profile image
Pascal Thormeier

Competition usually sparks innovation, so I hope that webpack and the like take some notes of each others progress and improve ever more. I too hope that we don't need those tools in the long run, native TypeScript support by browsers would be an amazing start! :D

Collapse
 
pavelloz profile image
Paweł Kowalski

And cutting off support for old browsers so that developers can actually focus on using modern tech insted of searching for polyfills and workarounds :)

Thread Thread
 
thormeier profile image
Pascal Thormeier

Oh, how I long for that day! :D Luckily the situation is getting better, slow but steady progress.

Collapse
 
crimsonmed profile image
Médéric Burlet

Discovered it a while back randomly and fell in love with it. It is so blazing fast.
We made a simple template for creating web packages with it:

GitHub logo pixiumdigital / typescript-package-boilerplate

webpack package with typescript support

Typescript Webpackage Boilerplate

In this boilerplate we have a simple look at a very basic typescript package exported for the web.

We leverage the use of webpack to expose our package to the browser.

Installation

install the dev packages with yarn:

yarn

Developement

yarn start

This will start webpack to compile the library on changes. This will also start snowpack which will update the index.html in test once the library from webpack has been compiled

Build

yarn build

Publish Package

First login to the npm cli if not already done

npm login

You will need to remove the following line in your package.json

private: true,

To publish a patch

yarn patch

To publish a minor

yarn minor

To publish a major

yarn major



Here is the explanatory article:

Collapse
 
thormeier profile image
Pascal Thormeier

That's looks very useful! Noted for future projects, thank you so much for sharing :)

Collapse
 
omawhite profile image
Omar White

I worked with snowpack on a project once. It was a really great experience. I don’t have any new projects to use with it at the moment, but I definitely see myself using it again in the future.

Collapse
 
thormeier profile image
Pascal Thormeier

Absolutely agreed, although I usually work with Vue a lot and since Vite seems to operate in about the same execution time ballpark, I don't know when I'll be able to actually use it outside of some playground... But: the tool is nevertheless amazing!

Collapse
 
bugsysailor profile image
Bugsy Sailor

Love the name! ❄️

Collapse
 
laegel profile image
Laegel

Snowpack is great, it also supports many transpiled languages such as ReScript. I've used it on a project of mine and worked seamlessly. Webpack's Hell is now far behind us. :D