Jan 2, 2019

I spent a little time over the holidays playing around with Stencil, a JS compiler for web components. I wanted to look at it because we've been comparing component libraries at work, and we were finding a surprising number of them that were going all-in on web components, usually generated by Stencil. Some quick notes about it in general, and comparing it against React, our current JavaScript library of choice:

  • Stencil reminds me a lot of the joys of jQuery plugins, where deciding between creating an element and passing in children or creating an element and passing in attributes is just a flip of the coin kinda choice. That's not to say React is better - see the arguments for or against higher-order components - but at least in React everything is in React, unlike web components where your children / attributes are in HTML and the handling is in JavaScript.
  • I hate carousels. I wanted to try to recreate a carousel that's on our current public site - it kind of magically appears when the viewport gets small enough and is just a glorified overflow slider. I feel like I've built variations of carousels a thousand times now, so there's a certain appeal in building a web component and never ever doing it again.
  • HTML doesn't understand TypeScript. I use TypeScript on all my React projects, and having attribute completion is 💯so going back to "just" HTML made me a little sad. It also made me realize how long it's been since I've written anything in an .html file that wasn't just <div id="app"></div>.
  • ... but it is just HTML + JS so it works anywhere.
  • ... but Stencil is a compiler that requires a build step, so you haven't quite gotten away from build steps in your front-end development process, but you're closer for every project that uses the Stencil-generated components.
  • I would have killed for this setup 3 or 4 years ago. TypeScript? Sane JavaScript templating? Not having to transport the same stupid widget between HTML, Angular, and React projects? It would have been amazing. Now that I do everything in React it's less exciting.

Overall I was impressed by Stencil. The documentation could be better, but they make it pretty easy to fire up a project and figure it out, and TypeScript + JSX is by far my favorite combination for JavaScript templating. Some of the decisions are close to React but not quite the same, like having props and state but not state update batching, or at least not that I could find. Digging through the shadow DOM in the Chrome inspector is painful compared to using React dev tools, especially if you're using child elements, which exist in some sort of alternate reality that allows you to interact with them like normal DOM elements. I built the carousel as a web component that accepts any children because that's how I would do it in React, but dealing with children beyond using the web component <slot> tag required some Stack Overflow searches and some solutions that I'm still not sure I grok.

If there was ever a chance we were moving away from doing everything in React I'd jump to web components in a second, but when we are building everything in React, adding in another compiler feels like it's overcomplicating our development tooling. But maybe I'll regret saying that when we switch to Vue and have to build another carousel.

I put the demo up on GitHub, it's probably broken in IE. I hate carousels.

Posted: January 2019