Hacker News new | past | comments | ask | show | jobs | submit login
Stencil – A reusable web component generator (stenciljs.com)
182 points by reimertz on Aug 23, 2017 | hide | past | favorite | 103 comments

Hey all, founder of Ionic (team behind Stencil) here. Didn't expect to see this up on HN so soon (released this morning), thanks for understanding there's still rough edges with docs, etc

We built Stencil for a selfish reason: we needed more mobile web performance for Ionic apps being deployed as PWAs (in addition to App Store apps) and we were struggling getting that with traditional framework component/bundle approaches.

We realized web components were a way forward and would let us reach more of the web dev community that wasn't just using Angular. However, we felt like there were some big framework features missing from vanilla custom elements (vdom, react fiber style rendering queue, etc), so we built stencil to make it easy to generate web components with these features baked in.

Along the way we figured other teams would benefit and pulled it out into its own project.

Stencil will be used in the next version of Ionic so we are dog fooding this hard, and web components it generated will be in use by thousands of Ionic devs soon.

We just announced this at the Polymer Summit in Copenhagen this morning and the talk is up if you're interested: https://youtu.be/UfD-k7aHkQE

Happy to answer any questions!

The main selling point of web components is that they are built using platform features and so they should be compatible with each other.

So in theory I should be able to mix and match web-components that are built using stencil, skatejs, polymer, or any other future opinionated web component library.

So is this also possible in practice and specifically can I mix stencil generated components with polymer ones (say use a paper-button inside a stencil compoenent) ?

Yeah, as long as you have the polymer as dependency - it should work, you can mix it with vuejs, preact or angular 2+ already.

Hi, wondering what's the main difference between Stencil and [Svelte](https://svelte.technology/)?

They're very similar concepts. Svelte was an inspiration to Stencil. We wanted to take a different approach to developer experience and ship custom elements by default.

Your github link points to the repo for the site rather than the project. https://github.com/ionic-team/stencil-site vs https://github.com/ionic-team/stencil

What kind of events are stencil events? In order to respond to an emitted stencil event, do I have to use the stencil listener, or can I use addEventListener?

Hello! Good question. There are no stencil events, we just use the custom events api that is built into the browser. Therefore, you can use addEventListener.

How Stencil will change Ionic (Angular) apps? As far I understand it will add real lazy loading, which should greatly reduce startup time. What are other benefits?

What about Ionic v4 apps? Will Angular still be used? How we are going to write our app components, they will be based on Angular or Stencil?

What about Cordova hybrid apps? Do you plan to support them or focus exclusively on PWA apps?

First of all, Cordova/App Store apps are still our main focus. However, we are incredibly excited about PWAs and will adjust based on where the market goes. This stuff is still new!

Second of all, we will continue to support building Ionic apps with Angular. In fact, you shouldn't really notice any difference, we've just turned a number of the Ionic components into web components. It'll be fairly seamless but performance on load and code size should improve by a fair margin.

Long term? It's hard to argue against web components being a superior deployment option for both our components and your apps, so if developer preference shifts in that direction we might push stencil/web components as the default. Time will tell

First off, thanks for all your work with the Ionic framework! I use it in education as part of an undergraduate course on cross-platform development, and the students thoroughly enjoy the developer experience.

Question: Do you have an ETA for release of the "Web Componentized" Ionic components? So looking forward to it, especially the potential of teaching e.g. Vue + Ionic components instead of having to put so much focus and effort on teaching Angular (which is a great framework, but requires a lot).

Awesome work Max and team!

Thanks Dan! :D

This could be amazing, whatever it is. But that's the problem.

I have to squint to see the font, there's two headers with two different slogans and a paragraph consisting of 12 words that tell me to go to the docs without providing a link.

The rest of the landing page is white-space.

Come on. Woo the visitor. First impressions are everything, and this fails.

At the very least move 'What is Stencil?' to the landing page.

Should be fixed soon thanks.

I'm not sure I'm understanding the point behind this. If the main point is to allow people to reuse components (i.e. a calendar widget) across frameworks, then good, but it's going to be quite messy when things start to get complicated and we start hitting integration problems, because some guy on the Internet writing a widget is not going to test & maintain it on all frameworks.

It also bothers me the whole Typescript deal. I might be wrong, but I don't want to have Typescript installed & integrated into my build process so I can use a widget. The only way I can see this working out is that I suck it and follow the Typescript paradigm or widget creators can distribute their widgets on some sort of "built" pure JS file, something like JAR files... and we know how well that goes.

That's a very "get off my lawn" argument against Typescript :). You install it off npm and type one command to compile everything to JS, then you can pretend it doesn't exist.

It's like you're arguing against distributing a large number of files in a zip archive. Actually... that's what a jar is. They're not scary, you can just unzip them to see everything inside.

Here an engineer at Ionic. You don't need to integrate typescript to use a "widget" generated with Stencil. Stencil is a compiler that generates vanilla web components in javascript. You can just import the generated .js and use the component just like a "button" or native "input".

Great, that makes so much sense. But then, how about other dependencies that might come into play? For example, underscore, is that "packaged" with this generated JS file or some other way around?

Thanks for the prompt response BTW.

No, Stencil.js is like a "real stencil", it is used to produce something, but it is not in the final product.

There is nothing like "window.stencil" or any stencil related API in the output of the stencil compiler. It generates vanilla JS web components without dependencies.

The documentation of stencil linked in this HN post was in fact created with stencil itself. Just open the Dev Tools!

OK, so if I want to use a calendar Stencil (there will be lots of this for sure), which depends on Moment I would have to include Moment into my dependencies and manage all the dependency clashing (the stencil used 2.x but I'm using 1.x)

In fact we use the type information provided by typescript to generate the web component as performant as possible.

I think you should consider disassociating the TypeScript requirement in the compiler. You'll alienate developers (like me) who prefer Vanilla™ JavaScript. It's one of the things I love about Svelte (which you claim heritage to), in that they really try to conform to vanilla everything, i.e., HTML, CSS, JS.

Everything else sounds terrific, though, especially the ability to do SSR.

It isn't really true that Svelte is just "vanilla" Javascript. For example, the compiler looks at the argument names of your computed properties to determine which data they depend on, which breaks with the semantics of Javascript. This means that Svelte only allows you to use function literals for computed properties.

It was announced today at Polymer Summit, please take it a look: https://youtu.be/rY233a4tp2s?t=2h6m50s

Gosh, the content is illegible on Chrome and Windows 8.

14px and a lightweight font does not make for happy reading.

Sure looks terrible on Edge, Chrome, and Firefox on Windows 10. Gray on gray makes for terrible contrast.

Hello all! We just deployed a new version of the site that should solve some of these problems, thanks for the feedback.

The font is still pretty tough to read on Windows/Firefox. It would be way more legible with a 400 font-weight.

Hey! Just wanted to mention that i pushed a deploy a few hours ago that changed it to a 400 font-weight.

It's more the OS than the font choice, different OSes render text better or worse. The site looks great on a 15 inch macbook pro.

Designers only looking at their sites on their MacBook Pros is exactly what produces these pretty but unreadable websites.

Adding a "Yes, but..."

Microsoft's refusal, or inability, to release a version of Edge (or even a port of an earlier IE) for macOS exacerbates this situation.

I virtualize Windows on my MacBook for IE/Edge testing of my designs and code, but it requires a workflow and context shifting that I'd perfer I didn't have to do.

Edit: s/I.E./IE

Ironically we have the exact same problem, except worse with Safari, since it has (relatively) poor support for some cutting edge APIs, and unlike Edge/IE we can't even legally test it in a VM because Apple doesn't even allow their OS to be put in a virtual machine.

At least Microsoft has the good grace to put up free VMs for browser testing - https://developer.microsoft.com/en-us/microsoft-edge/tools/v...

You can rent a MAC server here: http://www.macincloud.com/

At least you don't have to buy a whole different computer to do your job. I have to buy a Mac just to test websites and compile apps for iOS.

The only way for me to avoid using the Macintosh OS or having to buy a Mac is to switch careers or specialize.

Thankfully, cross-platform kits such as Cordova and React-Native let me use my preferred OS for development most of the time!

With Parallels that's at least a bit less painful, but yeah, we shouldn't need to virtualize at all.

Well, I'd disagree and say they are the ones who picked the fonts:

-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"

And have picked one on Windows that does not render well at the size and weight they want to display the text.

They could have had a more universal font selection like Arial.

I was about to defend the choice made, because they use a typical system font stack, just like GitHub. But it was deliberately set to `font-weight: 300` (light), which really is unreadable on anything but "retina" displays.

And on an iPhone 7 running iOS 11.

Thanks for the note, the site is a rapid work in progress! Will get that fixed soon

How is this licensed? Perhaps I'm missing it, but I can't seem to find mention of it on the site or in the repo: https://github.com/ionic-team/stencil

Ah good catch. It's MIT (will get that up soon)

Have you considered a BSD + PATENTS license? :P

Nothing wrong with that. In fact google releases quite a few projects like that - the important thing is what is inside the patents clause. Apache 2.0 also has one and no one argues against it.

Fact: The website linked in this HN (stenciljs.com) was itself created with stencil. I encourage you guys to open the Dev Tools and dig into it!

nice diamond emoji

Huh, that's a rather interesting approach to building Web Components. I'll have to see if it gets anywhere, but the idea has potential, and feels like it avoids many of the pain points of Polymer (although I'm not quite sure yet which you'll get in return).

Yeah, indeed it does look really nice, the API feels a bit weird though, not sure why lifecycle events are named after react.

We are fans of react and think the events fit the component model well, it's not a perfect 1-1 though

I'm curious, why build this instead of using [skatejs](https://github.com/skatejs/skatejs)?

If we use third party library code in multiple stencils. Will they be included separately in each one of them. Let's say d3 for graphics?

Yes right this second, but next on our list is providing a seamless solution to dependency dedupe. Not yet ready but it's promising.

Okay, that is definitely needed if we want to build serious components. Else it's gonna go crazy heavy!

A simple solution today would be to put the shared, heavy code in it's own component and call methods directly on that component. That's how we're share code across components in Ionic.

Could you please add an example of this in the documentation? It looks great BTW.

"Stencil is a new approach to a popular idea: building fast and feature-rich apps in the browser. Taking advantage of new capabilities in the browser, such as Custom Elements V1, Stencil enables developers to write faster and lighter components without the weight of frameworks.

The tooling also a solution to teams and library authors building components that support many frameworks. Stencil components work in Angular, React, Ember, and Vue as well as they work with jQuery or with no framework at all, because they're just standards-based components.

Compared to using Custom Elements directly, Stencil provides extra APIs that makes writing fast components simpler. APIs like Virtual DOM, JSX, and async rendering make Stencil Components easy to approach, while maintaining compatibility with Web Components"

So which browsers would this work in?

Hello all! Just to clear up the confusion here. Components built with stencil are, after compiling, just custom elements. Custom elements (the V1 of the spec) are supported in Chrome and Safari natively. According to https://www.w3counter.com/globalstats.php that means about 77.6% of users globally are running a browser that supports custom elements natively. For these browsers stencil will not load the custom elements polyfill. For IE 11, Edge and Firefox we load a 5KB gzipped custom elements polyfill automatically for you. Its also worth mentioning that Firefox and Edge are both working on custom elements, so eventually these browsers will not need the polyfill either.

To add to the other links: we built this to primarily help make Ionic faster, and we target mobile and web. So, it has to work everywhere we run. Some browsers require polyfills but still have improved performance making it worth it. Others, like iOS safari which is a major target for us, support it natively in 2017. The trend is more and more native support.

basically Chrome (I just saved you a click)

Although, their demo works perfectly fine in Firefox: https://corehacker-10883.firebaseapp.com/

It's probably using a polyfill for the functionality.[1]

[1] - https://www.webcomponents.org/polyfills#custom-elements-poly...

Our testing and shown that it works in IE11 and above. Both Safari and Chrome support custom elements natively, so no polyfill is required. Additionally, Edge has it under construction, and Firefox has custom elements behind a flag. For Edge, IE and Firefox the polyfills are downloaded on demand, rather than every browser always downloading every polyfill.

If this is true it's not practically useful yet. There must be more to it.

You can use a polyfill to get it working in browsers without custom elements support.

...and Safari? Which is actually a pretty popular browser (with good reason).

Safari 10.1 = 2.64%

Safari 10.0 = 0.64%

Safari 8.0 = 0.33%

Safari 9.1 = 0.27%


Total = 3.88%

For July 2017 according to NetMarketshare.

I wouldn't call a 3.88% install base "pretty popular". It's also offers a terrible developer experience

cf: https://www.netmarketshare.com/browser-market-share.aspx?qpr...

"desktop market share" != "market share"

Safari as well.

Basicly everything on par with IE11 and above (with polyfills or without).

I see two problems with stenciljs at the moment, but perhaps they can be fixed? 1, going back and forth in browser history, there is a flash of the footer being displayed before the actual content is loaded - it's just 1-2 frames, but very noticeable and disturbing. 2, scroll position is lost when visiting another page and going back.

Those are typical single page app problems, but they will probably not matter when using the framework for a hybrid app (no back button). If I'm to use this for a web app though, those would be nice to have addressed.

> scroll position is lost when visiting another page and going back

Who ever thought that keeping scroll position was a good idea anyway?

Use #s if the position is relevant.

Am I getting this right?

Stenciljs is: * Another way to create web components - using Typescript/JSX. * Provides SSR support

Other than that: * Is there anything else that we get from stenciljs? * How is it different from Polymer? * What Polymer problems does it solve?

content won't show for me (latest firefox beta, 56b05) :

   Failed to register/update a ServiceWorker for scope ‘https://stenciljs.com/docs/’: Bad Content-Type of ‘text/html’ received for script ‘https://stenciljs.com/docs/sw.js’.  Must be ‘text/javascript’, ‘application/x-javascript’, or ‘application/javascript’.
   Error DOMException [SecurityError: "The operation is insecure."
   code: 18
   nsresult: 0x80530012]  intro:19:41

Refresh on the home page and it should be fixed (:

What is the browser support for web components? I worry that tools like this are only targeting the last two versions of the major vendors.

IE11+ will work and everything modern. If you don't have native support things get polyfilled. Youtube nowdays runs on Polymer, web components and they support older browsers.

This sounds awesome! The Github link on the website should probably link to the main repo instead of stencil-site?

Gah! Thanks, fixing now

Does this mean we will be able to use Ionic components with React or Vue in the not too distant future?

You will be able with Vue and preact, react has some issues (that hopefully will be adressed soon). https://custom-elements-everywhere.com/ check this site for more info.

Does not work in firefox developer addition. Navbars work fine but nothing else.

Thank you for this, was looking for something like this!

Why did it name as stenciljs? Hope it is TS no? Then it should be setncil no?

Here's a new library to solve a problem you don't have yet.

We built it at Ionic to solve a problem we do really have. Might be useful to others, we hope :)

> "Here's a new library to solve a problem I don't have yet."

Fixed that for you :)

WebComponents in general are a solution in search of a problem.

Despite being 6 years in development:

- they basically delivered none of the original promises

- they are extremely cumbersome to use without a library/framework on top (Polymer is the jQuery of WebComponents)

- they are plagued by multiple problems and shifts in the ecosystem (browsers don't want to support `is=`, HTML imports are being dropped in favour of ES6 imports)

- they have multiple problems integrating with existing frameworks: https://custom-elements-everywhere.com (basically any framework that bastardises HTML syntax is ok, anything relying on Javascript only is in trouble)

Don't hold your breath for the next couple of years as everyone tries to figure out how to work with them.

Custom Elements are quickly gaining traction. They're in Chrome and Safari, and will be in Edge/FF soon based on discussions with those teams. The Angular team is toying with using them directly (not sure if this will ever come to fruition or not). We'll work with the React team to get it working with better compatibility. Right now our components work in React use just need to use a tiny "polyfill" wrapper. The experience in React isn't as good as we'd like, but it's pretty darn solid in Preact.

To me, it doesn't seem like too big of a stretch to think that the popular frameworks of today will move to the custom element spec instead of their own proprietary component model.

> WebComponents in general are a solution in search of a problem

Maybe they don't solve your problem, but they certainly seem to solve Ionic's or Netflix's problems (or mine for that matter).

"React seems to solve Facebook's problems (or mine for that matter)"

"Vue.js seems to solve Gitlab's problems (or mine for that matter)"


Throwing big names around amounts to pretty much nothing.

But thats exactly true, companies build solutions that solve their problems. No secret knowledge here.

> Stencil components are rendered using JSX...

What's the point? Why not just use React?

Like many others - I dropped Cordova and Ionic in favor of React-Native. So, what is Ionic trying to do here? Are they throwing in the towel and adopting React? Will they end up making a kit that renders native components using JSX just like React-Native?

There are hundreds of thousands of people using Ionic so we're certainly not throwing in the towel. One of the goals when creating Ionic was to build re-useable components that could be used by anyone. At the time (2013), this wasn't really feasible, so we went all in on Angular. Now that Web Component adoption in browsers is pretty solid, it has enabled us to fulfill the original vision of enabling developers using any web-based toolset to build incredible apps.

We're all in on web tech. We think it's the smarter choice long term.

The point is that you push more work to the browser, which has let us get a lot more load performance, much smaller bundle sizes, and much snappier apps and mobile websites (PWAs). We use React and Angular quite a bit internally at Ionic and the reality is that both produce very large code bundles and pulling those apart is proving to be a really hard technical challenge.

We're not throwing in the towel at all, rather we're embracing web standards 100% and think Ionic is and will continue to be the best way to build an app that works in the app stores, on the web as a PWA, and increasingly on desktop. Cross-platform is our main focus.

> Like many others - I dropped Cordova and Ionic in favor of React-Native.

Few years ago PhoneGap apps were really slow and ugly. So I built native Android app. This year I started building hybrid Ionic 3 app because it has to work on Android and iOS. It works good enough on Nexus 5 (Snapdragon 800). The biggest problem is 4-5 seconds startup time. Stencil and component lazy loading should greatly reduce that startup time (to 1-2 seconds I hope).

Quick tip, did you remove the hardcoded 3000ms splash screen delay? https://github.com/ionic-team/ionic-conference-app/blob/mast...

Thanks. And yes, this will fix that problem for good, and should be quite a bit under that budget for Cordova apps!

React is not really interoperable with other frameworks, libraries. Thats probably one of its bigger drawbacks. It is not an issue if you create a react application, but when you want to provide reusable components it might be problematic.

As kind of an old dog, I can't help but think of Active X controls from back in the day. That's what this reminds me of. Kinda.

Are there some guidelines and standardization of the kinds of events components emit, and what data is passed with the event? So that I don't have to look up all the variants of event names and data.

A custom element is just an HTML element, so it is a part of the HTML standard. If you log the object you can see it has all of the same properties as an HTML element, plus whatever you've extended it with. So all emitting events and event callbacks will behave the same as a standard element (except for any custom event listeners and emitters that you add).

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact