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
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) ?
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.
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).
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.
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?
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)
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.
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.
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.
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.
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.
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).
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.
"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"
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.
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.
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.
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
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.
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.
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.
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).
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).
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!