ht. So it's lunchtime. And I just wanted to do a couple quick announcements first. So food will be over across the way. There is a station over there for kosher and halal meals if you can't find them, just ask any staff member. At the same time, in about 15 minutes in the code lab space, we're going to start a casual Q&A session about the modules change. You can bring your lunch in there and ask questions in there. Steve and Kevin will be talking about Game of Thrones and everything they just talked about over in the Ask Polymer lounge. And there's also a Polymer quick start or quick tour area over there where you can preview sort of our new Getting Started guide and give us feedback and help us really hone that. So we'll be back here at 1.30. Matt, again, just got a lot shorter this time around. Getting no. Hi, I'm Elliot. I am a software engineer on the Polymer team. Welcome again to the Polymer Summit 2017 over in Copenhagen. Hope you all had a great lunch. We have a lot more talks on the way. It's going to be a lot of fun. Actually, so up next, we have Zilling and Mikhail. They're part of the YouTube team. Actually, Mikhail almost didn't get here because of visa issues. So I guess you might say some of our YouTube content wasn't available in this country.  Hi, everybody. My name is Mike. And I'm Zilling. I'm a software engineer at YouTube. I work on features and cool new tech. And I also work at YouTube. And I work on web architecture and infrastructure. So we're going to talk about how we use Polymer at YouTube. But before that, let's talk about just YouTube, just for a second. So I know it's kind of an obvious question, what is YouTube? You can ask anyone. And the person will say, well, it's where you go and you watch videos. And it's a popular website. And everybody are using that. It kind of makes sense. But so we know that YouTube is popular. But how popular? We went to Alexa to check. And apparently, we're number two. And unsurprisingly, it means that we have a lot of users who actually have 1.5 billion logged in users that are using our website every month. And not all of these users are desktop users. And actually, some of these users are never using desktop at all. But still, desktop is one of the largest and one of the fastest-growing platforms that we have. Unsurprisingly, people come and watch a lot of videos. How much? One billion hours a day. And again, this is across all platforms. But what is it billion hours? Well, it is 140,000 years. It's not 114,000, which would be a time before the ice cream cone was invented or an M-tube. It actually enough time in one day to go back all the way to the Stone Age. So every time you talk about anything that we do, you have to add that we are one of the largest at doing that, be it just pushing bites through the inner tube, or maybe image hosting, or a social network, or even a search engine. So hopefully, it gets the idea. We're kind of a really big website. So our motto is, broadcast yourself. And that means being inclusive. So we right now offer ourselves in 80 different languages, and this continues to grow. Additionally, we're accessible, and we consider it a first-class citizen. That means even if we're building a website from scratch, it has to be accessible from day one. Also, we have to deal with all kind of weird browsers. We have a lot of extensions that are specifically targeting YouTube. And while we're dealing with this crazy world that's happening outside of us, we do the main thing that we want to do on YouTube, we serve our videos. And we do it pretty efficiently, thanks to all the amazing job of many engineers that spent a lot of their time making sure that we do it really fast. Actually, it takes us less than two seconds worldwide to start video playback. In Denmark, that's 1.5 seconds on the median. Way to go, Denmark. Anyway, YouTube is a very huge and a complex project. And by no means it is a monolithic website. We have dozens of internal and external mini websites that fulfill different roles within the YouTube ecosystem. And also, YouTube is, I think, 12 years old right now, which means that we have over a decade of engineering decisions. We have over a decade of code that we have. I mean, we rewrite the code from time to time, but still we're talking about more than a decade. So we found this post on Reddit that we want to share with you. I'm fairly certain that in the eight years since Google bought YouTube, that very little of the original code remains. This guy has a lot of faith in us. The thing is, when you spend 12 years working on something, you end up optimizing that product. And despite having this very large code base, despite working on it for so long, it is a very highly efficient platform, because a lot of clever engineers spend their time working on this platform. Yet, we realize that this platform has limitations. And at some point, these limitations became too obvious for us. We were hitting some of the performance limitations that we were unable to overcome with the stacks that we had. And we were hitting some of the engineering problems that were unable to move as fast as we wanted to do. So we started to think, how can we make things better? How can we move forward? And what will be the next thing that powers the YouTube? So what did we have? What was our starting point? We have a server-side rendered application. And we always render on server-side. This happens even when you go through pages. And when we do an Ajax navigation, all the magic still happens on the back end. We built a lot of homebrew frameworks. They're not real frameworks. It's more like tools that we built for our products. We do have homebrew frameworks for JavaScript. We do have them for styling. We do have them for layout. So basically, we built things that fit our needs at a specific time frame. And the thing is, we're looking for some things that would be a little bit more modern than what we had before. And we had a couple of goals. We had a couple of restrictions of what we wanted. We have a couple of requirements from the framework that we use a framework or a library. We wanted a lightweight framework, and both in terms of the size that it will add to what we have and in terms of the footprint on our ecosystem. We wanted something flexible. We didn't want a framework that would force us to do things. We have a lot of unique challenges. We have a lot of unique business reasons to do things some specific way. So we didn't want the code to be in our way. We knew that component model is what we really, really want. There are a lot of benefits of using components. And you can look at these benefits from different angles. There are benefits of organizing your code as a component just because everything is very localized. There are benefits of deploying and building application as a set of components, because by doing that, you create clear boundaries. And then if the framework can provide you with encapsulation that happens on the clients, that's even better. So we wanted components. We wanted to iterate fast. And at some point, we realized that what we had was good enough that way our engineers work is not efficient. We want to be faster. We want to build new cool features. And when new engineers join our team, we want them to be able to get up to speed faster. We don't want them to spend a lot of time learning. Also, we didn't want to stay with a stagnant technology. And we wanted to do as few infrastructure work as possible. It's always very beneficial when you have a team of specialists working on a platform that you build your application on top of. So we wanted to be able to work with the platform and build relationships and feedback loops that are beneficial to everyone. After all, YouTube.com runs on the web platform. And the health and growth of that platform is good for YouTube. Also, this is kind of a big surprise, but we had a very direct and simple order from our president to make YouTube great again. And that is a real tweet. We don't know why, but that was pretty obvious. And we did. Anyway, back to reality, we had a lot of requirements, a lot of features, a lot of processes at our website. We do things specific way because YouTube is an existing product. It's been live for a long time. We had to make sure that whatever we do next will help us to transition into a new world, not break it. We looked at Polymer. We actually looked at many different frameworks. And now, because we are here at the Polymer conference and we're talking about YouTube at Polymer, it kind of makes sense. We picked Polymer. It wasn't that obvious when we just started because Polymer was actually not the first choice on the list. But as we went through this list, as we checked the checkboxes, we realized that now other frameworks, while great and sometimes fulfilling a lot of the checkboxes that we had, not necessarily give us the flexibility and the full picture that we wanted. And also, the Polymer at the time was just metering enough. It was going from 0.5 to 0.8, I believe. So it took some time for us to get used to the idea that we're going to use Polymer potentially. And just going and rewriting YouTube in Polymer, that would be too crazy, even for us. We didn't want to do something that big. So we wanted to try something smaller. We started with some tiny experiments, some tiny internal tools. And then after that, we launched YouTube gaming. This happened about a year ago. It's a variation of YouTube that's focused on videos and live streams of games. Afterwards, we launched YouTube TV. This is recent in the last few months. YouTube TV focuses on TV streaming and DVR. These two are both complex projects with a large user base, but they're not on the scale of YouTube.com. Also known as one of the largest Polymer deployments in the world, because again, YouTube, we do everything at this crazy scale. And building all these amazing websites gave us an opportunity to learn. It gave us an opportunity to polish our infrastructure, develop best practices. And at some point, we finally realized that maybe it's now the time to do what we planned all along right from the beginning. And we announced that we're launching or we're building YouTube on Polymer during the last Polymer Summit. And we're actually launching YouTube on Polymer. And I don't have an exact date, but we're this close to doing this. We're excited about that. And this is going to be the largest Polymer deployment in the world, obviously, right? Because this is YouTube and we do everything at scale. I mean, we're pretty confident it's going to be the largest one. I really hope. Some of you may have already seen articles or have even tried it. The important thing is YouTube is available for opt-in right now. Yep. You just go to youtube.com. There is a big button right in the middle of the screen. You press it. You get the new experience. And also, please, there are a lot of articles on the internet talking about how you can edit cookies and everything will be great. Everything will not be great. Don't do this. It's not the right way. Just go to youtube.com slash new. So what is it made of? Well, the site is 100% Polymer. And by that, I mean, from the app tag down, you can inspect the site. And you can see all the components right there. We have about 400 components that are just YouTube specific. More than 1,000 components across all the code bases. And we are happy that we can share a lot of our components across different projects. So let's talk a little bit more about how we use Polymer at YouTube. But before I go into that, let's take a small step back. And let me explain to you that we have this thing called, it's our universal data API. And it kind of shapes all the applications that we build. Keep in mind that YouTube runs on everything. Also, following a very sophisticated naming process, we internally called it inner tube. So here's a small set of apps that run on this universal data API. And we're not just talking about web. We also have apps on iOS, Android, game consoles, TVs, and of course, different verticals. We have apps for kids, apps for creators, apps for TV, apps that replace your TV, that run on TVs, and everything. And all of these run on this universal data API. So what does it look like? Well, what we ended up with is a presentational API, which is an API that structurally kind of defines how your page structure will be based on the data response in JSON. And we found that this structure maps really well to web components. As each web component receives data, that data defines the children that that web component will render underneath it. And then in that component, it takes a subset of the data, some subtree, and passes it down to the child. This continues until you hit a leaf node. And while doing this, we realized that what we do is render a lot of lists.  You may think that we serve video, but from a web framework side of view, what we do is draw lists over and over. And these lists are super dynamic. The machine learned, they experimented on, they're ranked in their massage. And every single time that you come to YouTube, these lists are re-ranked, re-experimented on, and it's going to change.  So this is a standard YouTube channel page. There's some obvious lists here if you think about it. But I'm going to highlight just a few to make it a little bit more obvious. There's menus, we've got navigation bars, search results, subscriptions, horizontal shelf video lists, lists of horizontal shelf video lists, and again, these change. They're dynamic, and every time you come to the site, we've got to redo it. Also, we had to stop at some point, and this is not all the lists we have, but the screenshot became too crowded to actually show all of them. So because this is so important, we spent some time and optimized our list rendering. We do some of the basic stuff that's pretty well known now, DOM diffing, efficient reuse of the DOM, but we also do other things like signal-based deferral. That means that we can block some of the content rendering until we get a specific signals, and to name a few, we can wait for the content in the viewport to appear, or we can wait for the video to start playback. As well as doing that, we also do lazy and budgeted rendering. To explain that, I have kind of a simplified view of how the render thread works. People think you play video, you go fetch some video bytes, you give it to the browser and video plays, but YouTube's not that simple. We do adaptive bit rate, we use dash, that means you have to use the media source extensions, which means the render thread kind of looks a little bit more like this. This is still a simplified view, but you got to fetch the audio bytes, the video bytes, you got to initialize the video API, you got to append those bytes, and then at some point, video starts playing. And so you can see that the render thread is actually fairly busy handling asynchronous events, and then you introduce UI code. UI code can take a lot of render thread time, and so in this case, you get these squiggly lines, and what those curved lines mean is that we're not able to receive an event on the render thread as fast as we'd like it to be. So how do we solve this? Well, with the scheduling system that we have with lazy rendering and budgeting, we try to break up our tasks, our UI code, into small chunks and fit it in between the time that these events come back. Also, we're cheating a little bit on screenshot because this screenshot, well, there are no user interactions here and our users tend to do all kinds of weird stuff like typing or scrolling or sometimes resizing the page. And while that obviously can affect the performance, splitting our UI into smaller tasks allow us to have as high FPS as possible in these cases. Also, I mentioned scheduling. We have a global scheduler on the YouTube website and also deals with priorities. This is very important because not every single piece of code and not every single piece of UI is of the same importance. So let's say you come to the YouTube watch page. The most important thing for us is that video. This is the thing that we want to prioritize over all other elements on the page. But following that, we have things like the watch next. This generates a lot of watch time on YouTube, so we want to render this next and we do this in a lazy budgeted format. Some things then are actually extremely deferrable like my comment here. Also, we know that YouTube comments doesn't have the best reputation, but they're kind of still important. They've gotten a lot better. Basically, list rendering, it's a foundation of performance at YouTube. So let's talk about the development process. How does it look from inside for an engineer working for Google? Well, the cool thing about having components is that as long as you can render this component, as long as you can create it separately from the rest of your application, you can bypass a lot of issues that we had before. And again, YouTube is very large, bringing up the development environment to work with YouTube, take time, and take resources, and being able to just take one component and then test it separately or create a demo or feed it with some data to put it into a specific state is critical for development process. So this is an example of a component, and the image on the left is what the engineer created. This is components that consist of some other components, but the pictures in the center and on the right is the two special flavors that are created automatically unless the engineer wants to change them in some way. And the middle screenshot is the dark mode. Also, I will highly recommend trying it on the new YouTube. And the right image is the RTL, so right to left version of the website. And all of these versions of the component are being tested, screenshotted separately. So you can see here. There's some changes on this component. It's not very obvious just looking at it, but once we add screenshot dipping, we can tell that things have shifted down, some padding has changed. This is a level of testing that has never been possible at YouTube before, but we've really embraced it and it's a core part of how we develop now. In addition to that, we took this granular component and testing approach and took it a little bit further, and we created something called Storybook. And what Storybook is, is a way for you to interact with the component during development. We have here a Storybook for something called a video list cell. And on the left of that Storybook, or the component, is a list of stories that have been generated. This is either a fixture that we saved before or some data that was automatically generated. And this allows you to kick up a Storybook and then click on any of these stories and you can see your component rendered in that state. This is the pretty much one of the best ways to interact with the component during development. But moving further, we integrated Storybook into our internal Polymer catalog, which is another way for you to bring up a component without needing to type anything on the command line. You can search for a component and bring it up in any time in its commit history because we've integrated this with our version control system. You can browse the documentation, you can bring up the Storybook, run unit tests, and look at the API and all that stuff. Also, all of these tools are Polymer projects. So welcome to the component inception because the Polymer dashboard is a component or a set of components rendering a Storybook which is a set of components, rendering a component which renders a lot of lists. So what's the state of Polymer at YouTube? We've mentioned that we have over 400 components on YouTube.com and over 1,000 components across all properties. So we have a data model that maps really well the web components. We have a highly optimized list rendering system and we have a suite of component level testing and debug tools. But there are a few things that we're still trying to bring up to date. Which probably not a big surprise from a website that just dropped IE9 support. So we're still on Polymer 1.x. We got a lot of stuff to migrate and we're moving to hybrid elements which have made it a very easy migration path. We're really excited about Polymer 2. It has a lot of increased flexibility and expensibility that we're looking forward to. And we're still on Shady Dom. So YouTube's a little bit more conservative when using these really cutting edge APIs. So we're still reliant on polyfills but we're really excited about Shadow Dom and we're moving our tools and our infrastructure to support this in the future. So to wrap it up, we feel like we're building for the future. We finally have modern tools and we're working with a web platform and we help push the web forward. The site is now faster to iterate on and we have much better test coverage than we ever had before. And while this is partially thanks to the major rewrite, Polymer played a major role helping us organize our internal workflow. Overall, the site is faster. That's up to 15% faster depending on the page. And developers are happier. We finally share components across our projects and we're using a standard stack instead of developing everything by ourselves. And we can't wait to start shipping all these cool new features after we launch. Thank you. Thank you, everybody. So up next, we have Kunal. He is from Netflix and Netflix, as you guys know, have been going through a lot of modernization throughout the last few years. If you think about it, they used to actually mail out physical DVDs and not use web components. But also, I don't know if you guys have heard about, have seen Netflix's recent financial report, but they're actually spending $16 billion on web components. So to hear you tell you more about their new Netflix original series on web components, we have Kunal Kundaje. Hello, everyone. My name is Kunal Kundaje and I'm a software engineer on the cloud platform team at Netflix. Today, I'd like to talk to you about our journey to reboot the cloud platform user experience within Netflix and how we're using Polymer as we go about doing that. So let's get started. Here's a quick overview of the topics we'll be covering today. I'll start with a brief introduction to the cloud platform engineering organization at Netflix and what we do. We'll then go on a quick whirlwind tour of a few different types of apps we've been building using Polymer, five apps in about five minutes. Next, I'll talk about reboot, our internal component library and some tooling that we built for a better developer experience. Then we'll look at the road ahead with Polymer 2 and I'll share an incremental approach that we're taking to migrate with minimal pain. And finally, we'll circle back to apps, specifically state management in larger apps and some experimenting we're doing in that space. So cloud platform engineering, who are we and what do we do at Netflix? Well, here's our team's charter at a high level. We provide a common set of foundational building blocks to Netflix engineers so that they can focus on core business value rather than recreating these infrastructure layers. So some examples of these building blocks include data stores like Cassandra, Dynamite and Elasticsearch as a service, Kafka Messaging and Stream Processing as a service. Atlas, our internal system for aggregating operational metrics across all of our services and so on. So all of this sounds like a lot of server-side stuff, right? But all of these services that we provide as an organization become much more usable when we offer cell service apps that empower our engineers to get onboarded quickly and leverage the capabilities of our systems without roadblocks. Insight tools like dashboards and visualizations, together with control planes, also help our engineers detect issues and fix them quickly and effectively without having to switch between multiple tools and command line scripts when they get paged in the middle of the night. And building all of these apps is where we come in. So let's go on a tour of some examples of apps that have been built for these various systems. They're all quite different from each other. So this segment should give you a good sense of the variety of app types that can be built using Polymer and Web Components. We'll start with Lumen. Lumen is our dashboard builder for operational insights. And it's widely used by engineers across the company to plot time series data, collected and aggregated by Atlas, our metrics data store, so that they can observe meaningful changes in these metrics over periods of time. So here's an example of a time series dashboard that's used by our cloud databases team to track various Cassandra cluster metrics, like IO operations and latencies over time. So Web Components are a great fit for this use case because we can have a simple public API for these graph components and encapsulate all of the logic to fetch these metrics and render them and then enable anyone to drop these components into any other internal app that we have, including those that are built in other frameworks like React, Angular and Ember, which we have within Netflix as well. But Lumen also supports more than just time series data. It also supports the concept of cell types, which are components that visualize the data that's passed into them in different ways. So for example, there are cell types for pie charts, histograms, bubble charts, data tables, what have you. And each of these is written as a custom element using Polymer. So here we can see a single real-time data source that's been connected to six different cell types to visualize the data in different ways. Users can also write custom data mappers, which are just JavaScript functions that take the data that's passed into them and then convert that to a format that can be understood by any visualization type. So here's an example that shows data from Elasticsearch being mapped to different cell types and visualizing that data in different ways. Next, let's take a look at Casper, a custom health check dashboard that we built for our fleet of Cassandra database clusters. So at a high level, Casper visualizes the entire health of all of our Cassandra clusters in the fleet as a tree map showing simple red, yellow, or green states. The sizes of the boxes are proportional to the footprint of the cluster itself. Obviously, the cluster names have been anonymized here. You'll often find this page projected onto a wall-mounted TV right next to where our cloud database team sits in the office. So what makes this dashboard quite unique from a front-end perspective is that the data source is a high-volume firehose of data being streamed in via web sockets from a job that's aggregating all of this health check data from over 10,000 different Cassandra cluster nodes. So in order to not completely lock up our main rendering thread, we process this incoming data in a web worker and post-message back when we need to re-render changes. So when a specific cluster goes red, an on-call engineer can look at Casper's cluster detail page to quickly get oriented with the current state of the cluster without having to switch between multiple apps or command line scripts. So this page describes the topology of the cluster, how many instances it has, what regions it's in, any running maintenance jobs that may be impacting cluster performance. And it even includes charts of some of the most relevant metrics like read and write operations and so on. And in fact, the Atlas charts that you see at the bottom here are the same ones that you saw in Lumen earlier. That's the power of web components there. Now you'll notice that this dashboard also sports a dark theme which is unlike most of our other apps. So this was a good test for the teamability of some of our components. So our polymer elements expose CSS custom properties that Casper could override with its own color scheme to get them all to blend in with its look and feel. So now that you've seen a couple of examples of dashboard-style apps, let's continue our tour with something a little different. So Keystone is our near real-time data pipeline that allows engineers to send events and logs to hive tables, elastic search clusters, and Kafka topics. This is the collection pipeline that's used to gather data for hundreds of the AB tests that we run, as well as some of our personalization algorithms. And this is Keystone self-service, a web app for engineers to manage their data streams. So we use D3 to build out a visual representation of the data stream as a directed graph with colors, motion, and tooltips along the edges, reflecting actual data flow metrics. Engineers can also use this view to make any config updates for any of their outputs or to change the topology of the cluster of the data stream by simply dragging and dropping nodes to rearrange them. So the encapsulation provided by custom elements and Shadow DOM was really beneficial here because we could build a simple graph, this graph component as a self-contained component with a simple public API and all of its complex implementation details neatly hidden away. Since all of the SVG nodes are within the element's shadow root, they're protected from the rest of the apps code and CSS styles. Moving on to the Netflix Data Explorer, and as the name suggests, this is a tool that allows our engineers to explore and update their data in our cloud data stores. So here we're looking specifically at the Data Explorer for Dynamite, our key value store that's built on top of Redis. Although the app's architecture allows us to layer in support for other data stores as well. So using the Redis API, Dynamite Explorer allows users to search for data by keys. Now we needed to scale to handle millions of keys per cluster, so we used a virtualized list, like the awesome iron list element, an infinite scroll style pagination to keep the UI running smoothly without skipping a beat. So you can see that it's handling about like 145 million keys in this case, right, so. In addition to simple data types like strings, Dynamite Explorer also supports complex data types like JSON values, hashes, lists, sets and sorted sets. And with Data Explorer, our engineers no longer need to figure out like which boxes to hop on to and what data store specific commands they need to run when they simply need to look up or update some data. So you may have noticed that this app heavily makes use of the paper and iron elements along with the material design styling, right. So having this rich palette of well built, well tested components available to us allowed us to rapidly prototype and build out this UI in a very short period of time. So we could spend time also building out and optimizing our Node.js API layer, as well as like adding additional features like single sign on, auditing and so on. And last but not the least is Winston Studio, our app for operational run book automation. So let's say you're an on-call engineer and whenever you get paged in the middle of the night for a particular issue, you perform a series of steps from a run book to diagnose and fix the issue. So Winston is our internal platform that lets you automate those steps in response to alerts. And Winston Studio is the web app that they use to wire up, author and test these automations. So here's an example of a simple automation that collects logs from a service and emails them to me when a health check failure email fires. So you can edit the Python code for this automation right in the browser itself with syntax highlighting and basic syntax checks. And before promoting it to test or prod, you can actually test this incrementally with a fixed set of input parameters. So this is another unique app compared to some of our other examples because it's almost like an IDE in the browser itself. We're using code mirror for the editor component here. And the nice thing about a component-based app architecture is that we can lazy load some of these larger third-party dependencies only when a user actually gets to this page in the app. So those were just some of the many apps that we've been busy building using Polymer within Netflix. To recap, here are some of the interesting takeaways that emerge from some of these app examples. So custom elements and shadow DOM give us a great encapsulation model allowing us to build complex components with simple public APIs and shadow routes that shield them from global styles. Theme ability can be achieved using CSS custom properties and the add-apply mix-in. And we're also looking forward to the part and theme specs that we talked about earlier. Web workers are a great way to do background work off of the main UI thread. Virtualized lists, like the iron list, for example, combined with paginated APIs, can give us fast fluid performance even when we're dealing with huge amounts of data. And a component-based app architecture allows us to lazy load just the dependencies we need for the views that a user has requested. All right, so now if you're looking closely, you may have noticed that many of these apps have a lot of things in common, right? So modern web development across most libraries and frameworks these days is centered around apps composed of components. In the case of Polymer, these components are web components or more specifically, custom elements. In this section, I'll talk about our approach to building component libraries and some tooling that we built for a better developer experience. So being a small team with lots of apps to build and improve and maintain, we take us a more pragmatic approach to building new components. When we can find high-quality, styleable components in the vibrant open-source ecosystem, and there are many, we use them and build on top of them rather than reinventing our own. We then augment these with our own elements that are specific to our internal use cases. And we use CSS, custom properties, and the app apply mixins from our internal style guide to apply consistent styling across all of these components in terms of colors, typography, spacing, and so on. Now when it comes to building our own components, we also wanted to have a consistent and streamlined developer experience. This includes things like scaffolding out new elements and iterating on them, generating API docs, demo pages, and making it really easy to do semantic versioning when you need to release new versions of your elements. So a couple of years ago, before the awesome Polymer CLI as we know it today existed, we built the reboot CLI internally. So this is a command-line tool that a developer can install using NPM, and then use it to scaffold up new components with a consistent structure, a common ESLint profile, and a set of common NPM tasks to perform various actions. The NPM run dev task like you probably expect just fires up a polyserve dev server so you can begin building and iterating on your new component. But there are a couple of other interesting things that the reboot CLI can do. The first of these is auto-generating API docs for elements, properties, and events. We do this by piping the element definition through a custom Babel plugin that traverses the syntax tree and generates a markdown file containing the list of property names, their types and descriptions, list of custom events, the element emits, and so on. And this also includes links to the specific line numbers in the source code for all of these things. So having this in a markdown file makes it really easy to look up the API docs for an element either directly in the Git or stash repo where it lives, or in our element catalog where we convert that to HTML. The second is easy and consistent semantic versioning of elements. So when you're ready to release a new version of your element, you simply run NPM run release and you tell it if this is a major, minor, or patch version bump. Reboot version then automatically figures out what the current version number is, auto increments the appropriate position in the version string, updates package JSON, creates the Git tag and pushes to origin all in one quick step. So as you can see, we've been using Polymer One for a little while now and we've built a bunch of components and a bunch of apps and now it's time to start migrating all of those over to Polymer Two. So we just started going down that path fairly recently. So I thought I'd share an approach we're taking depending on sort of what the app type is and so on. So to start with, we're making the latest stable version of Polymer One, the baseline across all of our shared elements and the apps that use them. This basically ensures that we can safely use hybrid style elements everywhere. It's a good practice to regularly keep up with the latest Polymer versions anyway. So this step shouldn't involve any big breaking changes. Now we recently started working on a couple of brand new apps. These were perfect candidates for actually starting out with the new Polymer Two library and ES6 classes for the app-specific elements. But these new apps also depend on some shared elements from our component catalog, right? So we took this opportunity to convert those shared legacy elements to the hybrid style so that they can work in both Polymer One apps and the new Polymer Two apps that we're building. When we eventually have ES6 class versions of those shared components, we can simply swap those in and now we have a fully migrated Polymer Two app. But what about existing apps, right? Existing apps, I think we can take two different approaches depending on the size, complexity, and rate of change. So for small apps and apps that aren't being updated much anymore, we start using Polymer Two and upgrade their app-specific elements directly to ES6 classes. Because these apps are small and not changing very frequently, we can skip the intermediate step of converting these to hybrid elements. And again, once when we have the shared elements upgraded to ES6 classes as well, we can simply swap those in and we have a fully migrated app. For larger apps, and ones that are still in active development, things get a little trickier, right? It's a bit more challenging to do a Big Bang migration all at once. So for such apps, we started converting their app elements to the hybrid style first while still running the Polymer One 1.9 version of the library. Once that's done, we can just replace Polymer One with Polymer Two and continue running in hybrid mode. Any new app-specific elements that we're writing now will then be written as ES6 classes and we can retroactively start converting some of the older app elements to the ES6 style as well. And again, like the previous two cases, once the shared elements are upgraded as well, we simply swap those in and we have a fully migrated app. So those are just some of the different strategies we can take depending on what type of app we're talking about. And that brings us to our last topic, which is state management. Also happens to be my favorite one probably just because of the stranger things reference. So as we were working on a number of apps, especially larger ones, composed of lots of nested components, we started running into some pain points around state and shared states specifically. So let's briefly dive into what the problem was using a couple of examples. So say you've got a parent component in its child that shares some common bit of state. A common pattern in such a situation is to make the parent component the source of truth for that state and pass it down to the child as a property. If the child then needs to change the value of that state, it simply emits an event that the parent listens for. The parent then makes a change to that property and passes it back down to the child and everything just works. But consider this example. Here's a deeply nested child that cares about the same bit of state as a parent a few levels up. In this case, the property has to be passed down every intermediate component in the hierarchy. Even though these intermediaries don't really care about that state besides just passing it down. So they're just acting as pass-throughs. Same thing with the events bubbling up from the child. And here's another situation. In this one, two sibling components need to share a bit of common state. So now you'd have to find a common parent ancestor and store the state in that, even though it doesn't actually do anything with that state besides passing it down to the children as properties. This example also illustrates a potential problem when a refactor or design change causes one of these child components to move elsewhere in the visual hierarchy. You now have to move this component there, find a new parent, a new common parent and then play the property passing game all over again. So it turns out that there's a very popular project Redux that aims to ease some of this pain. It's described as a predictable state container for JavaScript apps. And you heard Kevin talk about this a little earlier today as well. So we've had several teams within Netflix using Redux quite successfully with React. But there's nothing really React specific about Redux. So we've started experimenting with it in some of our larger Polymer apps as well. So the central concept in Redux is a store which is an object tree containing all of the shared state for an application. Properties on individual components can be mapped to specific slices of the store so that they're automatically updated when the state changes. Components can also dispatch actions to the store when they need to update some part of the state. So this is great because our shared state now all lives in one place and is only passed to components that actually care about it. So an open source library called Polymer Redux by Christopher Turner makes using Redux with Polymer quite simple. Once your component class extends a mix and create of this library, you can add the state path to any of your property definitions and they'll basically change whenever the store updates that value of the path in the state tree. Components also inherit a dispatch method from the mix and that they can use to dispatch actions instructing the store to make a state change. So what's next for our experiment with Redux? Well, firstly, we're still evaluating. So Redux may or may not be the right solution for every app type or every use case. So we're still trying to figure out where it makes sense to use it versus not. Second, in apps that are using Redux, most of our shared app state already lives in this Redux store. But there's also this additional state that lives in the URL in the form of path parameters and query parameters. So could we have the Redux store capture some of that as well so the app can now handle all of that state in the same way? Can we keep the URL in the Redux store and sync bidirectionally? That's something that we've just started exploring recently just a few weeks ago, in fact. It looks something like this. So similar to how the Polymer Redux library has the state path concept, we can declare this query parameter here. And then our mix-in now is responsible for keeping the URL always in sync with the Redux store. So our app now needs to, our app can basically read the state exactly the same way. So diving into the depths of Redux can be a whole talk in and of itself. And we don't really have much time for that today. Props down and events up works really great in many, many cases. And you should stick to that pattern if it's working for you. But if you'd like to learn more about Redux here and how it can be used with Polymer, here are some resources that you can check out. So there's the Redux site itself, of course. There's the Polymer Redux library that I mentioned. And then there's these couple of awesome polycast videos on YouTube by Rob Dodson that actually show you how to use the Polymer Redux library as well as do some of the async stuff with it using thunks. Yeah. And that covers everything I wanted to talk to you about today. Again, my name is Kunal Kundaj and you can find me on Twitter as at Kunal. Thank you for being a great audience and have an awesome time at the rest of the summit. Cool. All right, so coming up next is one of four, yeah, I counted four Australians giving a talk here. We actually, so many Australians that we're actually going to rename is the Polymer Australia Summit. So get your passports out. Australian Border Security's going to come by and check it. I'm just kidding though. But Bede's going to come up here and give a great talk about how Web Components makes CMS with Simplr, Simplr. So give a big Aussie welcome to Bede. Hi, everyone. So my name's Bede. I'm a developer from Melbourne in Australia. And I work on a content management platform called Simplr. So I'm here to talk to you a bit about Web Components for content management systems. So I've been working with CMSs for a while. And honestly, I've been a bit frustrated with them. Essentially, I've been frustrated both from a developer's point of view and also as a content editor, I've been frustrated. A couple of years ago though, I started using Web Components. And I realized these could potentially really change the way we look at content management. And they could help resolve some of these frustrations. So that's what I'm going to talk about today. I'm going to talk a bit about content management systems, where they have been in the past and where they are now, and how Web Components could potentially change them. I'm also then going to go over some of the patterns you might use to build out your own custom element for content management. So let's first look at a monolithic CMS. So a monolithic CMS is essentially your traditional CMS, such as a WordPress or a Drupal. It essentially gives you all of the functionality that you need in one single app. So on the one hand, this is great. It means it's really easy to set up and get going with. But like any monolithic system, it means it's quite rigid. So from a developer's perspective, it can be quite difficult, for example, to change the way you're displaying that content. For example, if you want to use a different framework or a different templating system, it's going to be really hard to wangle that in with the monolithic system. Also, for a content editor, you're going to have a bit of frustration there. So most of these systems, you're going to have some kind of a dashboard where you log in and you edit that content in a form. The problem with this is that that content there is in a completely different context to what your user is going to see. It's a very different environment. So for your content editor, they're going to get a real disconnect between what they're seeing and what the user is going to be seeing. Over the last few years, though, there's been a huge, huge rise in popularity for something called the Headless CMS. So the Headless CMS essentially takes this monolithic system and gets rid of the view layer. Instead, it replaces it with, generally, a really consumable JSON API or similar. Essentially, for developers, this is fantastic, because at this point, they don't actually have to deal with a CMS. Instead, what they're dealing with is just an API. So they can really use whatever framework or library backend that they want to talk to that content. Generally, though, these systems are going to end up with a dashboard just like the monolithic systems where you have to go into some form and edit that content in a different environment to your users viewing the content. So this is where components come in. What if we had a componentized model for content management? The idea here is that you essentially build upon a headless system with that API to consume content, except you take that view layer on the monolithic system, and you break it down into really small chunks of data, such as image text or something a bit higher level like a blog post. So this is already being done on the dashboard of these other systems. If you go in, you'll edit a content type, so in a kind of componentized manner. But the idea here is that that view layer is embedded into the component itself when it's delivered to the user in the browser. On top of this, we're also adding in a editing layer that's embedded inside the component itself. So for our content editors, they're actually able to go in and edit that content in the exact same place and same environment that users are going to be viewing that content. Also because this is a small modular and componentized system, we're trying to retain a level of flexibility for the developer so that they can still have control over this content and how it's displayed. So why am I talking about this now in the context of web components? So first of all, custom elements is the first time that we truly have interoperability. Before any componentized model was going to be restricted to the framework it was working in. This way, we can build components that can actually be distributed to any HTML environment. More than this, we also have encapsulation through ShadowDom so that we can make sure that editing UI isn't having any side effects to the rest of the DOM. So what would this look like? So here, I've got a dynamic image custom element with a path property that maps to some URL somewhere, essentially it's just pointing to some data. I want at some point for it to fetch from an API and I want to render out that content. So in this scenario, that means an image tag. Later on, I then want it to save back to that same endpoint. So we'll do a put request there. So this is for a developer. This is generally what we'll see. But what about that editing experience? So for example here, we want the editor to be able to come in, interact with that image in an isolated environment, maybe upload a new one, manipulate it in some way, and then be able to escape all in the context of that one image and see what the user's going to see. So how would we build that? So I'm going to go through a basic primitive. I'm going to go through that dynamic image and I'm going to focus on the fundamentals of the content part of that component. So I won't touch on the server and I won't touch on the internals of that editing UI. So this means I'm going to look at how do we store that content? How do we render it onto the page for the user? How do we toggle that editing UI to manipulate it? And obviously, how do we get and set that content over a network? So first of all, we need to create a basic dynamic image element and that's inheriting from the base Polymer element. And straight away, as early as possible, we want to set up an image on our instance that's going to act as a rendering point for all that data we're going to have. Next up, we want to append this into the light DOM in the connected callback. So we want to do this in the connected callback because only once the element is inserted into the DOM do we know that the user actually wants to start consuming this content. We also need to make sure that we're doing this into the light DOM, not the shadow DOM at this point. And that's because content should fundamentally still be accessible to the user. For example, if they want to use any third-party style sheet or any third-party library that expects an image tag to be on the screen, you need to be able to make sure that's accessible. This also opens up the door for really easy server-side rendering. So as long as your content is in the light DOM, anything that can spit out a HTML string can server-side render. So let's look at some properties here. Essentially what we want is we want some properties that are going to be able to hold all of the content to display that image. So for us, that's pretty simple. That's just a source and an alt property. You could add some more meta information if you need, but this is fundamentally what we need. We also have a render function. So this is an observer for those two properties. So this is going to get called every time and just pass those props down to our image. This might be more complex in other scenarios, say if you're building an article element that's based on markdown. You might store the content in markdown so your render function is actually going to have to take that markdown and convert it into HTML. So at this point, we're storing some content. We're rendering it out to the DOM, which is great, but it's pretty basic. It's essentially just a wrapper for an image. It's not doing much. So let's look at adding in some editing controls. So on the right, I've got my template, which is how I want my shadow DOM to look for this dynamic image element. And essentially, we're encapsulating all the editing functionality into it. Now you'll note my editor controls is surrounding the content, but really, that's just depending on the structure of your editing UI. It is important, though, it's beneficial for all of your editing functionality to be packaged into one element, just because this means that it's a clean separation of concerns and it also is going to give you a performance benefit, which I'll talk about later. So first off, we need a way to make sure that we can toggle those controls open and closed. So we've just added an editing property to the host and an open property on our editor controls. And all this is doing is just making sure our host can control when they're open and closed. We also obviously need to pass down those properties and that data to our editor controls. And at this point, we don't really know what editor controls is doing under the hood. It might prompt the user for a file. It might bring up a canvas to manipulate it. But essentially, we're just giving it the data. And at some point in the future, we know we're going to want that changed data. Lastly, I want to look at a load controls method. So most of the time with the dynamic image, most people that use it, most people that come to your site with a dynamic image on it, are just going to be viewing the content. They don't actually want to edit it. So we don't want to burden them with the functionality that comes with the editor controls. So what we want to do is we want to have this observer function that when editing goes to true, we can then import a HTML file that has the definition of editor controls inside of it. And only at that point, once we know that the user definitely wants to edit, we can load in and pass and boot up the JavaScript needed for editing. You can actually do more than this. You'll notice this entire shadow DOM is only for editing. So you could actually defer all of your work for dealing with a shadow DOM until the user is actually editing content. So now we have a dynamic image. It can display some content for the user. And you can add an editing prop, which will open up some controls that you can start manipulating it. This is pretty simple. And it's a nice base to work on. We have an interactive and dynamic image element. But it's not there yet. We really need to have some kind of networking to be able to load and persist that data. So first up, you need some kind of property which is going to let you uniquely identify the data it's talking to. So I've chosen a path here to map to some kind of URL. But you could choose a unique idea, whatever essentially is going to pass you back to a unique URL. We're also going to need a deserialized function, essentially just a way to take whatever the server is giving to us and hydrate our own properties from that information. Again, this API is pretty simple. It's giving us nice those source and alt properties straight up. But in other scenarios, you might not have control over that API. So your deserialized function might have to do a little bit more work. Conversely, we're also going to need a serialized function, which is just going to do that same process in reverse. We just want to take the content stored. For us, that's our properties, package it into an object literal that can be sent over the wire later on. And obviously, we need some methods to actually perform these requests. So our load method is fetching a URL based on that path property. We're taking that JSON, passing it, and giving it over to our deserialized function. The same, again, pretty similar, just doing it in reverse. So we're getting that serialized function. We're calling it, turning it into a string, and sending it over to our API via a put method. So this save function, you're probably going to want to wire that up to some external UI. For example, a save button that you might have on a page, or perhaps an internal event such as those editor controls, maybe when they close, you want to automatically save. Lastly, we want to make sure that we're loading in that content at the appropriate time. So I'm doing this in the connected callback because, basically, you want to make sure that you're not making a network request too early, but you want to make sure they're getting it at the right time. So once the element is in the DOM, we're making that network request. But you could be a bit smarter than this. For example, you could use something like an intersection observer so that you could load in that content only once the element has been scrolled onto the page itself. So now we have a pretty simple image, but it can display content. It can provide an editing UI so that you can edit it in place and get feedback on that editing. And it can also dynamically fetch that content from a network endpoint and persist it back to that same endpoint. But this is just one component. Ultimately, to get to a CMS, you need more than this. You need a whole library of components. And that's what we've been doing with Simpler. So we've been developing out a bunch of primitive elements such as video or image and text and bringing them all together using other mechanisms such as authentication systems and global management systems that are able to synchronize save events amongst all of the elements and make sure they're all editable at the same time. But more than just a single CMS, wouldn't it be great if we had an ecosystem of these dynamic elements where people could mix and match and use the ones they need based on their website or app? And what if we could have a plugin system for those APIs so that you could choose the content source that you're using for a specific element? You could have multiple content sources on the one page. Ultimately, I think using all of these together and utilizing web components and the features that it gives us, I think we could really see a different approach and a better way to manipulate and use content on the web. So thanks very much. I hope this has been interesting. Please, if you're interested at all, come and chat to me afterwards. Thanks. Awesome. So last year, we had Gannett up here. They gave a talk, and they loved the Polymer Summit so much that they had to just come right back and bring a friend on top of that. Fun fact, one of the speakers up ahead is a blacksmith. He also brews his own beer and lives on a mountain, and his name is not Ron Swanson. So also Gannett is the parent company of USA Today, and most of these people are from USA Today. And so to bring you the USA of tomorrow, today we have Josiah, Josh, and Marianne. Well, hello. Good afternoon, everybody. Welcome to the talk with a very long name. Designing a design system for modular modules and building a team to build it. My name is Josiah McCann. Joining me on stage are Marianne Epstein and Josh Trout. Josh and I are representing the core web development team, and Marianne is here representing the UX design team at USA Today. First, I want to start off by saying thank you, Polymer team, for having us out to speak again. Last year was a really, really fun year, very, very practical talks, and I'm really excited about the talks tomorrow and the rest of the talks today. It's been a great conference so far. So I want to share a little bit about the USA Today network and what we're all about. And we're all about making communities stronger. And to do that, we have to inform them, equip them, and empower them, fostering deep and vital connections between members of our community and the world around them. And we connect these communities all together through our national brand, USA Today, and our 109 local media organizations, merging our national voice with the local communities. As an award-winning news organization and a modern media company, our 500 plus digital products reach 110 readers every single month. We reach 43% of the internet population with our content, resulting in 1.5 billion page views every month. And as you can imagine, this level of scale and fragmentation between so many websites has its challenges. And today, we want to share our success as a dev and a design team, focusing on very practical points you can immediately walk away with and apply to any size team or project. So to give you a little bit of context, here's what we've been up to since we last spoke. A year ago, we launched our new Polymer-based web framework. We're test driving it with a few, we test drove it with a few different microsites. We talked about one last summit, our Olympics coverage, our data-driven Olympics coverage. And after that, we launched our continuous coverage of the election, all converging on election night, the biggest news night of the year, where the framework made its big stand, taking on heavy amounts of traffic. And the entire process, it was a great way to see how much faster and more efficient we could build on this new framework, while also identifying areas that needed to be improved. And at the beginning of this year, we began replatforming our current sites onto this framework and doing a complete redesign at the same time. Right now, USAToday.com on mobile devices is completely powered by this new Polymer web framework. Part of this new framework is we want to figure out, can we build quickly, can we build more efficiently? And it really, really worked for us. But this new approach that we took, this module everywhere approach, is key to our success in building for a large news organization with many developers scattered all over the nation. So this approach, it's adopting a module way of thinking and web components on the client are front and center, or Polymer-based approach. But also, not just our client, but our servers, we have server-side moduleization through microservice through a microservice ecosystem. This module's everywhere approach is very decoupled, allowing for maximum component reuse across not just our team, but through any of our web developers spread across the entire network. Reducing the cost of experimentation, maximizing shared code use across each and every property. And to support this development philosophy, design had to be on board and think modularly as well. And here to talk about our new design system that supports this framework is Mary Ann. Everyone, as Josiah said, our design team has spent the past year working on a new modular design system. And today I'm gonna talk about what a big change this was for us, as well as what worked well for our design and dev teams in case your teams might be approaching sort of similar challenges. Heading into our redesign last spring, we had separate desktop and mobile sites, and we'd been adding new things to them for a couple of years. And over time, our designs had veered off in many different directions. Here you can see a story coming into our desktop site, and that same story also coming into our mobile site, and they look very different from one another. And if you were to hide the logo at the top, you might even think that these came from two different publications. And these differences were causing problems for our business. Our journalists couldn't predict how their stories were going to look, which was very frustrating for them. And from analytics, we knew that our readers weren't as happy as they could be either. And because these same sites were being sent to 100 different newsrooms, our designs were frustrating a lot of people every day, which on the UX team is the opposite of what you want. So there were some good reasons behind everything looking so different at this point. First, a lot of things had changed since these sites were built. Reader habits, our storytelling and response to those, and our scale, we had grown a lot as a news network in the past few years. Meanwhile, we were not set up well for all of this change. We didn't have a style guide. So whenever we needed something new, which was pretty much all of the time, we would do our best to make it match. But more often than not, we would have to design it from scratch. So we wanted to really understand our problems before diving into redesign. So we shadowed our journalists to find out what they really needed from our sites. And then we took inventory. So we screen capped every page of our websites to understand how we were currently meeting the journalists' needs. And what we found were just hundreds and hundreds of single-use one-off experiences. So here's a specific example to show you what was happening. We are a news organization, so one of the most important things we do is promote stories to help readers find things that they're interested in. And we call these story promos. And at the time of our inventory, we found this. So this is 12 versions of a very similar-looking story promo. But each one of these could only be used in a specific place. So this one only ever showed up on home pages. And this one only ever on blog pages. This one only ever appeared on mobile article pages. And this one only in desktop search results. And on and on for all of these. And if you look at these more closely, almost every style here is unique. So every headline has a slightly different font treatment. Even the hex values of all of these grays, they're all different. So not only had this same thing been designed 12 times, but it had also been devbed 12 times. And this was just one example. So we saw this same sort of duplication and variation happening for our video promos, our share tools, pretty much everything else on our site. So to step back for a second, as a designer, unearthing all of this was actually very, very exciting. So seeing the same thing done so many times at such scale and knowing how it was really causing problems for our journalists and our users, that meant we had a really good problem to solve. And it was actually two problems. We had a lot of design sprawl and a lot of inefficiency. And the design team thought a lot about how to solve these problems in such a way that we wouldn't have the same ones again in another year. And we realized our focus had to be reusability. So we needed to take anything we were doing over and over and do one thing instead. And that meant we needed smarter modules. So for us, that meant modules that would either do the same job in different places, so for example, a promo that can live on a homepage or an article, or to do the same job across use cases, so one promo that could support a video story as well as just a regular story. And we needed smarter styles, so that we wanted to be able to reuse them across these modules to keep everything cohesive and help fight design sprawl. So here's a very short version of how we got there. Based on our inventory, we distilled the needs of our site into module categories. So for us, as a news site, ours were promo, story, media, ads, a couple of others. Then we distilled all of our style needs into style ramps. So anything we used again and again, like type, color, spacers, we abstracted those into variables. And finally, we designed some documentation to help us stay organized. And for us, documentation was absolutely the key part of getting all of this to work, because if there's one thing we learned from our inventory, it is that reusability does not happen by accident. So even if Dev moved to a component-based approach, design still had a role in making sure those components actually met the right needs and actually fit together visually on the page. And we found that reusability only happens when we pay extremely careful attention to details and then write them down. So this was quite an adjustment for our team, because not everyone loves writing things down. But we have come to love what it does for us, which is to help us design things that are, in fact, reusable. And I'll share our version of design documentation in a moment, but first, I want to show you where we ended up. So here's our new Story Promo, which now has a real name. Promo Story Thumbs Small, or P1 for short. And this was our single reusable module answer to the 12 different versions we had before.  It can live in the main content well, or in the side rail. It can promote a video story, or a 360 video story. It can promote a story without an image, which is often the case for breaking news. Or a story without a timestamp, which helps us showcase our best evergreen content. And it can live on a homepage, or an article page, or search results, or any other page we build in the future. And it is made entirely of reusable styles. So here you can see that everything in this module is pointing to one of our style variables, even the space between elements. And Josh is going to talk a little bit about that for a second. So we implemented this through the usual ways of styling Polymer applications and elements. Custom style element for our theme. And that had CSS, custom properties, mix-ins, and some classes. This sample shows the colors and typography used in that promo. And also shows how we mirror some of the mix-ins into classes so we can use that in server-side HTML. We also built custom elements for some of the more complex design elements, like icons and buttons. And this example on the screen, which is like a little label header that goes above a lot of our list of promos. And now Marianne's going to keep talking to us more about documentation. Thanks, Josh. OK, back to our friend P1 here. A lot of attention to detail went into making this one module smart enough to be reused in so many ways. And that's where our documentation came in. So we wanted to keep documentation as minimal and lightweight as possible, while also making sure we weren't missing anything. And one exciting thing we learned as we troubleshot that is that dev and design actually needed to know the same things. So we found that to make a module reusable, we all had to agree on the answers to five basic questions. What is it called? What is it made out of? What variants do we need? How does it scale? And what styles is it using? And here is a peek under the hood at our version of design documentation for that P1 module. So on the left, we have our functional spec and on the right, our design spec, which we call our matrix because it's a visual matrix of how this module can look. And together, these documents answer those five questions. So question one, what is it called? We never used to pay attention to this, but now anything we build gets a specific name, so we can keep track of it and reuse it. And we collaborated with dev on a naming system, which includes three parts, a shorthand ID. So in this case, it's P1, and that just makes it easier to talk about things. Category ID, here it's promo, and a descriptive ID. So this is StoryThumbSmall, which tells us this has a small thumbnail image. Next question, what is it made out of? Here we established that this module has a headline plus some optional things, like labels and image and other nested modules, like a timestamp and an icon. Question three, what variants do we need? This is where we capture our module's use cases. So for the P1, we have our default display, then variants for no image, different media types, advertiser content, and a couple of others. Question four, how does it scale? So here we see we have a narrow version and a wide version, and the matrix tells us how these sit on the grid, as well as what the two sizes look like. And finally, our styles. We call out our style variables over here, and this helps us avoid those one-off styles we used to have so many of. So I hope you can see that for us, documentation is not an end in itself. It has really turned into a thinking tool for our teams to help all of us check our work for reusability. And over the past few months, we've used this method to build out an MVP set of modules for our new site, which launched to 100% last week. And here it is. Here is our new story page design. And we think it looks much cleaner and more on-brand and much more trustworthy than the old one, and is going to be much more predictable for our journalists and our readers. But what's even more beautiful to me about this new design is that we now have this kind of X-ray vision into it. So anyone on our team can look at this page and know exactly the modules that came together to build it. And this X-ray vision makes us so much more efficient than before. When we need to change something, which we know we will, as we test things and get feedback and as our needs change, we can change it in one place instead of 12. And we can quickly build new pages by repurposing things we've already built. And the last thing I want to share with you all is that we've been beta testing this for a few months. And we can see that our readers are now spending significantly more time with us per visit on the new site. So while we love the new design system, our readers loving it is what we care the most about. So we're really happy with that result. And we're excited to keep evolving all of this because it's brand new, it's a work in progress, and there's still a lot to learn. Thank you so much, and Josiah is going to take it from here. Thank you, Marianne. Very good stuff. So building a team to build stuff. So we've unified around a module-based, decoupled web framework. We've established a shared design system that organizes our vision behind every component we build. But we need to think about how to structure a web development team around component-driven web development. Because I believe we're in the post-abstraction era of coding for the web. And as we unify as a team around a standards-based approach, element encapsulation, and heavy reusability, we need to structure our team for maximum efficiency and effectiveness. We've all been building websites and web things the same way for a very long time now. But web components changes this work dynamic entirely. And because of that, it was time to think about a new kind of team organization. In our internal observation, we identified three coding styles that make up our team. The innovative artists, the disciplined scientists, and the very reliable craftsmen. And it's really important for us to understand how these different coding styles work together in order to build an effective team. And every style has its strength and weakness. No one's greater than the other. And some of us don't really fall cleanly into one column or the next. But some projects may benefit from one style being more dominant than another style. For example, a banking application is very focused on being accurate and not time to market, while if you're working for an innovative startup pushing that code out the door that's changing the world, we want to do that very, very quickly for our investors. A balanced team can cover the weaknesses of one single type, but only when good communication and empathy driven teamwork is applied. So let's learn a little bit more about these different coding styles. Let's take the artists, the adventurer, the innovator, the fast moving, the problem solver, always figuring out the problem, always finding a better way, while cutting a few corners in there. I can identify with the artists the most. It's like tests. What are tests? I don't know. I don't know what a test is. Our weakness as an artist, unique solutions are great for pushing innovation and doing things better. But unique means it's harder for someone else to pick up and maintain code. How an artist would approach building the P1 modules, they might say, oh, I'm going to use the new CSS grid framework, and that's how I'm going to make this happen. But we already have a grid framework for the company, and we've just fragmented company standards. All of a sudden, someone else comes around to reuse it, and they're like, what did you do with the CSS grid framework? So instead, artists need to innovate the right way by focusing on things to improve everyone's workflow, not just the current vertical that they're working in. The scientists pursues code as a discipline to be mastered. They're focused on best practices, have very well tested code. And this is really, really good, but it can all come at the cost of over-engineering solutions and slower time to market. And the scientists, they would approach that P1 promo module that Marianne showed us. They might look at it and say, oh, we need to use the image resizer for this image. Oh, this image resizer, it's really clunky to work with. It needs some refactoring. Or, oh, how we're fetching data over here for this P1. It's not very elegant. I think I'm going to rewrite it. And so all of a sudden, we've taken a very small scope module and really, really extended the scope. But the positives are they're continuing to improve on a framework and plugging holes in framework and pieces of code. Carefully tested, disciplined, always seeking the industry, best industry standard practices. Slower time to market, over-engineering. You don't know anyone like that, do you? Maybe. The craftsmen, very, very important. These are often under-looked coding styles and people that you work with every day. They are the steady, dependable, delivering consistent on-time code that's very, very reliable. Sometimes they can lack innovation and deeper technical expertise. They might approach that P1 module like this. They're using two keyboards in Emacs. No, not really. Who uses Emacs? They might approach it. Oh, I wrote 60% of this code last week or code like it. I'm just going to copy my code. I'm going to bring it over here. And I'm going to reuse all this code. Great. And that's awesome because we're keeping on the company's standards. We're doing a lot of reusing. But not so good because no one has stopped to think, hey, is there a better way to do what I'm doing? Is there a better way to solve this problem? And maybe copying the code that I used from last week is great. But if I'm copying codes from a month ago, a lot of things can change in a month. Overall, the craftsman is a very, very important addition to the team, often overlooked by the other coding personalities. Now, adding web components in the mix on top of these styles, web component development really resonates with each of these styles in different ways. The artists, they get to forge ahead on these new best practices. They get to blaze a new trail because we've been building things the same way for a very long time. They get to go back to the drawing board. The scientists, well, they get their standards-based web development. Even though this is a very free solution, they get that encapsulation. They get clean organized code and the ability to test things logically. So the scientists, they love this. And the craftsman, well, they get to use familiar tools and technologies that they already know, HTML, CSS, and JavaScript. And Polymer has such a straightforward, simplified API, it's not like throwing a whole new abstracted web framework at a craftsman expecting to them to learn a completely new API and framework. They get to use the tools that they already have. That's how web components resonates with each of these styles. So important, we know and we understand these different styles a little better. So how do each of these styles work together? How do you balance a team with these styles? And we have to remember, and when you're working with a team with different style coders, we're all in this together. And we can either be building each other up or tearing each other down. And balance is really struck by the scientists bringing that structure, bringing the, hey, we need to harden this and test this to the artist. And the artist saying, hey, let's solve this problem that no one's been able to solve yet. Let's do it with innovation. And he's bringing that to the craftsman, the scientist. And the craftsman is like, hey, reality check everybody. We need to be on schedule. We have something to deliver. And we just got to go, go, go. So the other interesting thing is that this can also be applied to entire dev teams as entire development teams sort of lean one way or the other. And how do you solve for team to team interaction? That's even harder than just managing a team and figuring that out amongst a team. And it's through empathy. It's through clear communication. And it's through cooperation. So empathokies throughout that word, well, what does that really look like practically?  And we do this all the time. So stop and let's empathize. What does empathy look like here? Well, empathy and understanding says, well, maybe the team is focused on delivering something fast with imperfect code. Maybe that's what this particular team needs to be focused on right now. And then the artists, why aren't they using the absolute newest way to build things? Well, let's empathize. Maybe it's safer and easier to build on a proven industry standard for their project than going off the rails and building something else. Because what we want to do, we want to fight against extremes. And both the artists and the scientists, they can look at the craftsman and say, they're not real coders. They're not up at 3 o'clock in the morning contributing to open source repositories every night. But they're the bread and butter. They're the ones that are churning out all this work. And we have to fight against extremes. And we have to remember to empathize or else craftsmen will get impostor syndrome. And the walls of hubris and ego will be built up with scientists and with artists. So now Josh is going to talk about how we've structured our web component developer experience specifically. Josh? So we put this into practice on our dev team in a few ways. The first is focusing on the API over the element implementation. Because there always be times when you must compromise on code quality, where speed to market is just more valuable to the business than having the absolute most rock solid code ever. So what that means is like focusing on reviewing the API, which is the names, the properties, and public methods of an element. The implementation of all those things can be refactored later very safely without having to worry about breaking anybody else's code. The way we actually make sure that that refactoring actually happens on our team is we have a program we call adopt a module. And that means we just bake in some time to every sprint where we allow developers to go back and review modules that have been maybe sitting around for a while that we haven't touched. And clean up documentation, clean up some JavaScript that might be a little messy. Maybe some styles aren't implemented as cleanly as possible. And that lets us kind of get code out to market quickly, but still come back and make sure we are having really good code that will be maintainable and long lasting. So what that looks like in practice is this is a really simple sample element and showing a good API with some bad code.  But it's got a nice name for the element. It's got a good property title. And all the bad stuff can be refactored out later. On the flip side, you've got a bad API good code module, which has got a really nice implementation for the filtering. It's just much cleaner. It's got some error checking. But there's a problem with it. There's misspelling in the title change handler. And you can't go back and fix that because if somebody else is already using that, you can't fix that spelling. And the property is just called t. So now all the elements that are set t equals whatever, they're going to have to change that. And then the element name's not even that great. So this is an even bigger problem when you're dealing with other teams using your code. And it's the biggest problem when you're actually open sourcing your code. And the rest of the world is using your stuff. You don't want to be breaking their applications because you've got a little sloppy at the start. So to get this focus, we kind of build things backwards. We call it demo driven development. We start by building examples of how the code will be used, how the element will be used. And this is pretty easy because of the spec documents we have. They list out all the different variants that design has told us that we should account for so we can show what each of those look like and think about how the element will be used to build out each of those things. Once we have that solid and we like it, then we actually build out the element's implementation. And then finally, we'll come through and add tests and make a production ready. So what this looks like for our promo module is listing out stuff like the normal variants, the version with no image, a version for video, version for galleries. And all of this lives in a demo file that's right next to the element. And it gets served through our custom dev server. So as you're developing your element, you can be testing on this demo page. And as you build out the implementation, things start to come to life. And when the whole page is working, you know you're done and you ready to start building those tests. So the last thing that we get from web components is division of labor. And what's nice is you can break out who works on which element based on their skill set. So if you've got an element that you say, well, we're really not sure how to build this thing out very well, so let's give that to our artists because they're gonna be able to come up with an interesting solution for this. If you've got an element that's really complicated and you need someone who's gonna really put a lot of tests behind it, then get that one to the scientist. And then if you've got an element that you know exactly how you wanna build it, but you just need it to be built on time and get it out at the right moment, give that to your craftsman. And then the great thing is you can always come back and have the other style do the refactoring later. And so the scientist can come in and clean up the artist code and add some more tests or the artist could come in and say, oh, craftsman, you could have built this a little bit better. And so if you get that kind of interaction, it's great. So we hope this glimpse into how we build things will help you build great things with Polymer as well. Thanks for having us here and have a great rest of the conference. So howdy, everybody. So before we go for a break, I have just a few announcements. So in 10 minutes, the code lab's gonna start with Valdrin Koshy. He is a really interesting code lab about animations, making the performance. Light snacks and coffee are right across. And if there's anybody that you heard earlier today and you have any questions for them, they should be hanging out in the Ask Polymer lounge. And we will be back at 4 p.m. with Monica Rob Dodson and some more webpack and stuff like that. It's gonna be a lot of fun, guys. Have a great break. Hello, Polymer afternoon audience. Is everyone still awake? My name is Brendan. I'm on the tools team of Polymer, working on some fabulous tools as the CLI and Bundler and Build and Polyserve and many, many tools. Our next guest is a developer advocate. Developers, developers, developers. No, you know him from Polycast and the many good videos that he does. I had a special introduction to Rob when I was recovering from surgery. I watched about 9,000 videos of his as I was learning Polymer. So he's sort of the angel that ushered me into the future of web components. Here he is, Rob Dodson. How y'all doing? Good. So this talk is gonna be about my journey to try to get the whole world using custom elements and some of the interesting things that I've learned along the way. So I've been at Google for maybe like a little over three years at this point and during pretty much that whole time, I've worked on custom elements and web components and it's my belief that if you're building a UI library and you're working at like a mid to large size company so you wanna build a whole bunch of components and share it with a bunch of teams that are all on different stacks that custom elements and web components are really like the way to go about doing that. And this story is basically what I've been advocating for all these years. And being the point person for custom elements and web components means I get a lot of feedback on that idea. And feedback that kind of looks like that. So this is a tweet from a fellow Googler who was trying to use web components with another framework. And he said, every few days I see someone like Rob say that web components work in all frameworks, all of our problems are solved and it's really clear that no one has tried any of the above. And you will notice that this is tweet 6B of a very long list of grievances and subordinate sub grievances that rolled up into the larger tweet storm. So very organized and very emblematic of a lot of the feedback that I've gotten over the years. And it kind of boils down to this. We say that custom elements should work everywhere, that they are based on web standards, that they are the future of the platform. So we say that and then like why don't they? And the more I thought about this, the more I started to wonder if like, perhaps we put the cart before the horse. And did we maybe get so caught up in the fact that we could build custom elements that we didn't stop and spend time to think about how we should build them in the first place. And if custom elements and the things that we build, if they are unpredictable or they are inconsistent, does that then make it harder for frameworks to work with them? And so that's really what I set out to find out. So I split this talk into two parts. The first is my journey just to identify what a quote unquote good custom element would look like. And then the second part is looking at how frameworks should work with those elements. And my hope is that by the end of this, you all will have a better understanding of how to author your components and also what to expect when you try to use those components with other frameworks or libraries. So let's dive into that first point. What is a good custom element? And to start this journey, I actually went to the Chrome engineer who was in charge of implementing custom elements APIs in the browser. And I said to him, I was like, hey, do you know if there are any reference custom elements that I could look at? Stuff which you think really lives up to the standard. My thinking there was that the people that write the specs and the people that actually implement the APIs in Chrome, surely they've gone and built a bunch of custom elements and they're like, these are our ideal components and all components should live up to these. His response was a bit surprising because he was like, nope, none that I've seen. And that really got me thinking. I was like, hmm, all right. So we need to identify the best practices for custom elements. And I'm not really sure how to do that, but maybe what we could do is assemble like a crack team of engineers. And then together we could probe the depths of the HTML spec and would uncover all the treasures that lay within. So that is exactly what we did. Working with my teammates, Serma, Monica, and Eva, we began writing a set of vanilla custom elements. So not using Polymer or anything like that, just vanilla JavaScript custom elements. And we wanted to figure out how the heck these things should actually be authored. And along the way we learned a lot. And in fact, we're still learning a lot. But what I wanted to do is go through some of the stuff that we've tried to capture so far. And we've been doing this work inside of an element set which we call the how-to components. So the how-to components, these are a collection of educational custom elements. We're saying that this is sort of like literate code. So we want folks to actually look at the implementation, read them, look at the comments, and understand why we did the things that we did. Now I want to be really clear. These elements that I'm talking about here, these are not things that you should use in production. They're not even styled, really. These won't be going on webcomponents.org or anything like that. Instead, we wanted to create a resource where developers could read the source code kind of side by side with the comments and then learn from the elements and understand why we made certain decisions. And then take that knowledge and actually go apply it to the custom elements that they are building within their own company. I want to be also really clear that this is a work in progress project. Don't be surprised if you're looking at the repo, we start changing things around because basically as we learn new ideas and it happens all the time, we learn new ideas and we bring them to all the elements and we update them all at once. So again, it's not a production thing. It's not something you should actually use the code or anything. We just want you to read it, interpret it, and think about it. Because what we want to do is create a resource where we can all learn in the open and have discussions on GitHub about like, okay, well, why should we do this? Why should we not do this? So if you want to check these out, you actually can. The repo is available up on GitHub. Here's a direct link to it. And I'd like to walk through some of the best practices we learned as we were doing this. So I split this up into kind of three topics. We're going to try and cover. How do you deal with Shadow DOM? How do you handle attributes and properties? And how do you manage events in your elements? And I want to be clear that what I'm going to talk about today are guidelines. So these are not meant to be like rules or laws that you like have to follow. Because the web platform is not really consistent all the time, not by a long shot. And so you should always feel free when you're building your own element to color outside of the lines if you need to. If your element calls for it, right, you get to make that decision. But having said that, I do want to dive into some of these best practices and we'll start with Shadow DOM and some of the things that we learned. Now, the first question that comes to mind when you think about Shadow DOM and you're building a custom element, especially if you're doing it as a vanilla custom element and you're writing all the JavaScript yourself, you're not using a library or anything, is like, does my element even need Shadow DOM? And I have to admit, personally, over the last, maybe a year and a half, I kind of got a little cranky with Shadow DOM. I got a little frustrated with it at times. And I've got the team, the Polymer team, they're like, dude, you got to use Shadow DOM. You got to use Shadow DOM. When you're building custom elements, you always got to use it.  Like Shadow DOM, it can be kind of annoying to work with at times. It can be hard to re-theme. The polyfill can be a little wonky. And you know what? Maybe you just don't tell me what to do and I'll build my own elements, okay? And so, yeah, deal with it, boom. And so that is actually how we started this process. We were like, we're just going to build vanilla custom elements, we're not going to use Shadow DOM, we're just going to do our own thing. So the first element we created was a checkbox. Here it is, very simple, how to checkbox, right? Seems straightforward enough. It's a single tag. It doesn't have any children. I didn't see why something like this would need Shadow DOM. So instead, we were like, okay, cool. We have a JavaScript file for our element definition and then we have a CSS file for all of the styles, okay? But very quickly, we discovered that if someone takes your element and you're using a global style sheet like that, so they take your element and they put it inside of another element that uses Shadow DOM. Okay, well now all of your styles are broken because you don't have a way of getting your style sheet into that other element's scope. I mean, maybe they can like link out to your style sheet or you could have like a build tool or some build process like inject your styles into their element or something. But it basically means that like, it's up to you and that developer to figure out how you're going to get your styles into their scope. So that was a little, I felt kind of not awesome about that, but whatever. And oh, I should point this out because this is actually really interesting. There is actually a discussion to see if we can streamline this little bit. So there's a thread on the W3C GitHub where Steve Orville, a member of the Polymer team, has proposed this notion of if you have a very simple custom element, like a single tag, something that doesn't have children or anything like that. Could we maybe, as you registered the element, also give it a style sheet object and that would work almost like a user agent style sheet just for that tag. So this is a really cool proposal and something that I actually hope we land at some point. But today, this is not real. It's not shipping anywhere. And it made me realize that you probably need to create a shadow root if your element is going to self-apply any styles. And you might have a shadow root that only contains a style tag and that's totally okay. The benefit is that your element starts to become a lot easier for people to reuse. They can use it outside of Shadow DOM. They can use it inside of Shadow DOM. Right, they can put it inside of more complex elements and it just works. Now as we were working through this first element, a conversation kind of popped up on my Twitter feed. And someone said, I'm kind of paraphrasing the original tweet here, but someone said, you know, since we have things like CSS and JS for scoping our styles, do we actually still need Shadow DOM? I mean, can I just use these like fancy build tools? And it was actually a Trey Shigart who'll be speaking tomorrow who responded on Twitter and he said, you know, style scoping is a really cool benefit of Shadow DOM, but aside from style scoping, one of the other major benefits is DOM encapsulation. So if you're building an element when it like creates its own children as part of its implementation, you can actually hide those children, you can hide that implementation inside of that little DOM scoping bubble. And this is really crucial for framework interoperability. And so he shared a example that I wanna walk you all through because I think it's really interesting. So let's say we're building an element and we're building a counter. So it's just gonna say the word count and then have like a number next to it, like count one, two, three, and so on, right? So I've got a little div here in my template with the word count and then I'm gonna slot because I'm gonna assume that this framework or library that I'm using my element with that they're gonna put the number in there for me. I'm gonna create two versions of this element. So the first one is count with shadow. So here I'm creating a shadow root. I'm just appending my template content inside of the shadow root when my element is constructed. The other version that I'm gonna create is gonna be called count without shadow. So this time instead of using shadow DOM at all, we're just going to stamp that template content into the light DOM. Now I'm cheating a little bit because slot elements don't work outside of shadow roots, but whatever, go with it, go with it, pretend it does. So let's look at what happens when we try and use this inside of something like react. So in react, I've got my little render function here and I'm going to try and stamp out both of those elements and I'm just gonna have react pass in the count. So every tick is just gonna pass a number as a child of each of these elements. One, two, three, and so on. So what do we get when this renders? Well, you might be a little surprised. The first element looks like we would expect it to, right? So you've got count one. The second element though looks totally broken and I wanted to dive into that a little bit. So why is that? So in this first implementation, all react can see inside of this element is just the number one which you put inside of there. Now we know there's a shadow root and inside of that shadow root is the word count and our slot tag, but react isn't able to see any of that because it's not piercing shadow boundaries or anything and this is good. It means our implementation is hidden. If we look at this second element though, it's kind of more interesting because it seems like react created an element and then put some text inside of it and then attached it to the document and then our connected callback ran and all our stuff stamped out after the content. Okay, so already that looks broken. Probably not what we want, but it gets a little bit worse too. So the next tick react is gonna look at this and it's gonna be like, in my render function, you told me about the number, but you didn't tell me about this div thing here. Really, what is that? I don't know, you didn't tell me how to render any of that. So what's it gonna do? It's just gonna delete it and so the next phrase just throws away all the light DOM children and now we just have the number two inside of that element. Now I did some tests and I found that other frameworks may leave your light DOM children in place or they may not. There's really nothing to enforce that. It's just kind of a convention that they may or may not adopt and so what we learned from this is if you're authoring an element that creates children, you probably wanna put those children inside of a shadow route. That's because those children are part of your implementation and the rest of the page should not need to know about them. So after all of this thinking, going back to the original question, does your element need shadow DOM? I think it actually probably does and even though it can be a little frustrating or it can make you kind of cranky to work with it at times, shadow DOM is really important because without shadow DOM, you lose all guarantees of safety. You know, if you wanna put your element inside of another element or you wanna put your element inside of another framework where there's other JavaScript actors at play, shadow DOM kind of protects your implementation from the outside world. It's the little engine that makes the framework interoperability story go. Okay, so that takes care of shadow DOM, quick recap there.  Let's talk about attributes and properties. Basically, how does your element handle data and reflecting state to the outside world? This might seem like minutia, this might seem like a very boring topic to talk about but when it comes to framework interoperability bugs and issues, this area is actually where I found the most problems and the most differences across the board. And this is like a really contentious topic actually. So even the Chrome team and the people that work on specs and the people that work on Polymer have different ideas about how elements should handle attributes and properties. And I wanted to try and do my best to get to the bottom of this and just put out some semblance of best practices. So when we think about attributes and properties, it's like, what would we consider canonical behavior? It was like, okay, well, I mean, where would I even look to figure that out? Well, there's HTML, right? HTML has a spec and it actually, if you read the HTML spec, it explains how attributes and properties should work on elements. And so it's like, okay, cool. Well, I guess we'll read the HTML spec and we'll just do everything it says. I don't know how many of y'all spend much time reading the HTML spec and really dive in in there. It's actually pretty gnarly the deeper you go. If you dig down deep enough, you'll find inconsistencies, you'll find anachronisms, you'll find stuff that seems to kind of predate the current era of standardization, like older elements like input are just super weird. So it can make it kind of hard to distill out what one would consider like the best practices. But for all of its faults, it's also kind of the only model that we really have to follow. So if you can make a custom element that's mostly indistinguishable from the behavior that built-in native tags have, I think there's a really good chance that frameworks will be able to work well with your component. So here are some of the best practices that we came up with. The first is that for primitive data, so strings, numbers, booleans, you wanna always accept that as either attributes or properties, ideally both. So someone should be able to just walk up to your element and call like set attribute for a particular thing or set a property like a corresponding property and both of those should just work. And ideally, you want to reflect back and forth between your attribute and your property. So let me give you an example of that from a native element. So if we look at the native video tag, I want you to see this behavior because it's actually pretty interesting. So this element has a preload property. It also has a preload attribute, right, the correspond. I can go up to this element and I can actually query it and I can say, all right, what is your preload property value? I know it'll say by default it's auto. And I can set that property to none and you'll see it sprouts an attribute when I do that. And I can then read that property value again and it's actually reading it off of the attribute. And I was like, okay, cool, that's interesting. Can we mimic the behavior of built-in elements with our own elements? And so my understanding from talking to spec authors is that the way this behavior is implemented in native HTML is that there are getters and setters for all the properties and the getters and setters are actually like really dumb. The only thing they really do is just kind of reflect back and forth the attribute. So I'm gonna make a fake element here called custom video and in my getter, I'm just going to try and get the value from the attribute. If there is one, I'll return it. If there's not, I will return a default value, right? So this is that default auto string that we saw. So this is kind of interesting because you're co-locating the default value with the property, with the getter and setter. In the setter, all we do is we take the value that was passed in and we reflect that to the attribute. And because the getter is leveraging the attribute, we have now synced our properties and attributes. So you change one, it changes the other, right? And that's pretty interesting. We don't have to write any additional code. You don't have to have like a little underscored property that you're sort of like managing under the hood and all this private state. Instead, these two worlds are just in harmony now. So I thought that was really interesting. And so you can see this in action with this like custom video element that I created here. So you can go and you can look at it and basically the same behavior. So we can read the preload property, we get the default value out of that getter. We set it, we now sort of spring an attribute and then we read the property again, it's reading it off of that attribute. So for primitive data, I feel like this behavior actually works quite well. And it makes things very consistent. So someone can fiddle around with an element and still call get attribute on it and get the right data. There are exceptions to this rule. So you might not want to reflect properties that are like really high frequency. So for instance, the native video tag also has a current time property. And that is basically every millisecond it's updating the current time for the video. So reflecting something like that, probably don't wanna do. Again, in the HTML spec, there's inconsistencies and quirks and there's reasons to color outside the lines. But generally speaking, primitive attributes and properties reflecting seems like a good thing. And it can simplify your mental model as well, right? It can help you understand how to write your component if you just do this consistently. So that's good for primitive data. What about rich data, like objects and arrays? So I think this is really interesting because I think for rich data, you probably only wanna accept that as properties on your element. And there's reasons for this. Oh, also you probably don't wanna reflect rich data from properties back to attributes. And the reason is because one, it's expensive to reflect, right? So stringifying a big object that someone passed in as a property and reflecting that, that just doesn't seem very useful. Polymer actually used to do this, like Polymer is zero five, we reflected everything.   The other reason I think you should avoid this though is because a serialized object loses all of its identity. So this is something that my teammate Justin pointed out and it's pretty interesting. So if you take an object and that object has references to other objects and then you call JSON stringify on that, well you've just broken all of those references, they don't work anymore. So you pass that to some element and maybe the person is expecting mutating that object to mutate some of the original sub-properties and that just doesn't work, right? So if you just stick to properties, you kind of avoid all of this weird string bizarroness. So definitely recommend that. All right, so for attributes and properties, a quick recap, primitive data, you want it as either attribute or property. You ideally want both and you want them to reflect. And then for rich data, objects and arrays, I think your element should really just accept those as properties and that'll make your life a lot simpler. Last thing I'm gonna be quick about this is events. When should an element dispatch events? Now this seems like, I don't know, kind of a weird question to ask, but then when you really think about it, it's kind of interesting because if you look at native built-in elements, they do not seem to dispatch events in response to like a host setting property or anything like that. And I think there's a good reason for this. It's kind of superfluous, right? You set a property and suddenly your element dispatches event, like, well, you don't need to tell me the value, I just set it, right? So it's kind of weird to dispatch an event then. And if you're not careful, you might end up causing an infinite loop. So you tell the host, hey, this property changed and if the host is, you know, if you've got like a unidirectional app set up, like you're using React and Redux or something like that, the host is like, I don't care that the property changed, my model says it's this and it sets the property and the property says, hey, the property changed and the host is like, no, and then you end up in an infinite loop, right? So you gotta be careful about that. So for these reasons, I recommend not dispatching events in response to downward data flow. So when the host sets a property and this actually differs from how Polymer does things.  And this is actually what powers Polymer's data binding system. But because Polymer does the additional work to guard against firing an event, if you set the property equal to the same value twice and it's okay, you don't end up in an infinite loop. But if you're running just a vanilla custom element, then I don't think there's a ton of value in firing property change events. So then that leaves the next question, which is like, well, then when should I dispatch events from a custom element? And here I think what you wanna do is you only wanna dispatch events in response to internal element activity. So what is internal element activity? Well, this could be things like a user interacting with your control, an asynchronous task finishing, like something loading or an animation completing. Basically anytime the component knows something changed and the host does not and we need to clue the host in. We need to tell the rest of the app, hey, something new has happened. This is a good time to dispatch an event and this kind of mirrors what native built-in elements do. So last recap really quick on the events. Don't dispatch them in response to downward data flow. Do dispatch them when your component has special private knowledge the rest of the app does not have. I realize I went through all of these like super, super fast. And that's because we're short on time and this is by no means an exhaustive list. Many of these are things that Polymer actually does for you already. So if you're using Polymer, it's awesome, right? You don't even have to worry about this. But I still wanted to go through the process of documenting all of these things and just trying to figure out how stuff should work. So we've been collecting all of these best practices that we've learned while building the how-to components and we've actually created a new section on developers.google.com slash web all about building components. So this is available today now. It basically takes all of our existing material around web components and custom elements and it organizes it better so we've got API primers, checklist of custom element best practices and a few example how-to components are up there as well demonstrating how to actually implement those best practices. So you can check this out. Here's a direct link to it. And now that we've looked at custom elements I wanna switch gears now and this is kind of where I think the talk gets a little bit more fun because I wanna look at the other side of things and I wanna talk about how frameworks should then work with custom elements. And this is like a really tricky problem to solve because as you all know there are as many JavaScript frameworks as there are stars in the Milky Way galaxy. This is not anything I have to tell you this is science, it's a known fact, right? But I thought what we could do is we could take just like a subset of the most popular frameworks and we could write some automated tests for them and then we could publish those results to the web so we could track what does work and what doesn't work and hopefully learn from one another. And so I'm really excited to announce another project that I've been working on. This is a new site called Custom Elements Everywhere. Making sure frameworks and custom elements can be best friends forever. The URL for this is available at customelementseverywhere.com so you can play around with this and check it out. And but you gotta keep paying attention to this talk too. And I'm gonna just give you like a quick run through of how this works. So every framework on the site has a little section and in that section I indicate how many tests they're passing. There's a little write up to explain like any quirks or gotchas or anything weird like that. I've also gone through and tried to track down every web components related GitHub issue for all these different libraries so you can keep tabs on everything in one place. And of course you can go down and you can click this little button and you can view all of the tests for the framework. You can see, all right, what passes, what doesn't pass so you can have a better expectation of like if I'm gonna use this custom element in pre-act or Angular or wherever, this is what is and is not going to work. Oh yeah, this is where I wave my arms around and apologize. All right, if a framework is not represented here, it is not because I think that framework is unimportant or not awesome or anything. I think all of them are awesome. It's just really hard to write a webpack file for every framework. I don't know, have you all tried that? It is not fun, okay. So I have done my best here but I would love help from the community to add more libraries to this site. I really want everyone to feel like the tools that they use and that they enjoy, that they are fairly represented on here. The other thing that I wanna point out is there are some known unknowns to this process. Like have I rigorously tested every feature of every framework and every permutation of custom elements? No, not at all, okay. I don't even know all the features of all the frameworks but I did wanna start just like having the starting point, just to help some of these things shake out. So why don't we check out how we did? So I'm gonna go through these scores in alphabetical order starting with A for Angular and Angular actually got a 30 out of 30 in the test that I wrote. I actually was not able to write any tests that Angular failed. I'm talking about new Angular, not old Angular, new Angular, okay. And by the way, like I said, known unknowns, okay. So if some of you are using new Angular and you're running into issues, please like open a PR, open an issue on GitHub and help me track those down, write some tests. But the test that I've written so far, Angular passes all of them. Preact comes in at 24 out of 30, so pretty good, about 80%. React 16 out of 30, so 53% and we'll talk about why that is. And then finally view with a 30 out of 30 again. So they're getting 100. One thing that I think is important to point out is that so far I have not encountered any major issues related to shadow DOM so long as the custom element is kind of following the best practices that I talked about before. In the past, this has been an area where things like totally did not work, in particular with like polyfill. But these tests run in native shadow DOM and against the polyfill. And so far, I haven't had any shadow DOM issues. So fingers crossed, maybe we're in a better place today. That would be really exciting. Let me talk about the two areas where we did actually encounter issues though. And that was mainly around handling data, so attributes and properties and dealing with events. And the tests for attributes and properties, these mainly check that you can pass data to an element declaratively, so using a framework's binding syntax, I can get the data into my element like I need to. And I'm kind of generalizing here, but I think roughly speaking there's like two ways that you can think of doing this in framework land. There is what I'm calling the manual approach where the framework has explicit syntax that you can use to tell it, hey, either set a property on this element or set an attribute on this element, but it's sort of up to the developer to make that decision. And then there's the sort of more automated approach where there's really only one binding syntax and the framework has a heuristic that it uses at runtime to try and figure out how it should pass data to an element. So I'm gonna go through each of these and kind of like indicate which framework is which. So again, we'll start with Angular. This is the binding syntax for Angular. So this is how you pass data to any element or component. It doesn't matter if it's an Angular component or a custom element or whatever, this is what you use. And basically what these square brackets mean is it's telling Angular, set the foo property equal to bar where bar is like some value inside of your Angular component, okay? In other words, my element dot foo equals bar. So not only can you pass primitive data this way, but you can also pass rich data this way. So objects and arrays, right? And that's great. Like we talked about before in the best practices, that's how we want to pass rich data. So this works really well. If you need to explicitly set an attribute for any reason, you can do that as well. You can add this attribute modifier to your binding and this tells Angular to explicitly call like set attribute on the element, right? So you've got total options there. Angular falls into the manual bucket. You can kind of do whatever you want using their syntax. View, on the other hand, is similar but they sort of do the inverse of what Angular does. So for a component that View creates itself, like a component just written in View.js, I believe by default it will pass data as properties, but when it encounters a custom element, it will pass data as attributes. So that's like saying set attribute. But because View also falls into the manual bucket along with Angular, they have a dot prop modifier and you can use on their syntax and you can tell it explicitly pass a property to an element, which is good. Again, now we can pass objects and arrays to elements. Cool. React, on the other hand, falls into what I'm calling the automated bucket. So it has a heuristic that it uses to try to decide how to pass data to an element. Currently, when it encounters a custom element, it will always pass data as attributes. For primitive data, like a string or a number or Boolean, maybe this is fine. But when we get to rich data, this becomes a problem because when you call set attribute in React, you end up with something like this. And that's not very useful. I can't do anything with that. So in React, there is not a good declarative way to pass rich data to a custom element. You can work around this, so you can grab a reference to the element and in your render function, you can manually set that property on it. But because there's not a declarative way to do it, React kind of fails a few tests there. Again, this is more of a hiccup than like a total showstopper. You still can use custom elements with React. You just got to know about this, gotcha. What's interesting is the React team is actually discussing switching this behavior to always setting properties when they encounter a custom element. So this is an RFC for React 16. I think it would be awesome if they did this and you can check out this GitHub issue to kind of like follow the discussion. Finally, Preact. Now, Preact is interesting because Preact, like React, uses JSX. But it uses a different heuristic. So when it encounters a custom element, it will use the property on the custom element if it is defined, if it is available. Otherwise, it'll fall back to using an attribute. So the way this works in Preact goes like this. It just does like an in check. So it'll say, if foo in my element, use the property, and if it's not, okay, well, we'll fall back to the attribute then. We'll treat it like configuration. This is pretty cool, and it actually works pretty well. As a result, Preact passes all the properties and attributes tests that I've written so far. They also have a pull request that's open so that if the element that it's working with is not upgraded yet, and it's passing rich data, like an object or an array, it'll use a property then as well. Lastly, let's talk about events. So the test here, check that you can declaratively add an event listener to the DOM events dispatched by custom elements. So the way this works in Angular is anything that you put in the parentheses there, that is the event name that you are telling it to listen to. The value then is the handler to run. So this is like saying, my element, add event listener, foo changed on foo, okay? Now the cool thing is we can use basically any event name that we want inside of those parentheses. So we can use lowercase, we can use caps case, which is good for things like URL changed or like DOM ready, right? Think of like acronyms and things like that. That'll work.  Do not actually, no, no, no, no, no, no, no, no, no. Okay, view on the other hand is like basically the same behavior as Angular. So basically anything that you put after the V dash on directive, it doesn't matter what case it's in, it'll work in view. So view passes all the tests here. React is a little tricky, because React does not have declarative syntax for listening to DOM events. So React implements its own synthetic event system that kind of like sits on top of the DOM event system. For native elements, they have a white list of events that they know to listen for, but that doesn't really work for custom elements because we could dispatch infinite different event names, right? So unfortunately this looks really tempting, but it does not work, bummer. Again, like the attributes and properties thing before, we can work around this. You can just grab a reference to the element inside of your render callback, and then using like component did mount, you can just manually add event listener. So again, a hiccup, not a showstopper, but just something to be aware of. And they do have a GitHub issue to bypass their synthetic event system for custom elements. I think it would be really, really awesome if they did this, but this is still being discussed. Finally, we get to Preact. So the exciting thing about Preact is that it uses native DOM events. So this right here totally works. Mostly, it mostly works. There's like some gotchas. The only problem here is Preact will take everything after the word on and call to lowercase on it. So like if your event was actually named foo changed with those capital letters, it would lowercase it to foo changed, all lowercase, and maybe never hear your event, right? So I realize you're all now thinking the same thing, which is that it means it doesn't support asshole case. And I know, major WTF.  I think Jason prefers to call it mixed case events because he's like Canadian, very polite, but like we all know what he means. So with that, I think we're nearing the end, and I just wanna kinda like recap some of the things that we learned along the way. So regarding custom elements, I don't think there are really any like rules which dictate how you must write a custom element, but I do think there are best practices that we can start to follow, which will make it easier for us to write elements consistently, and easier for other developers to then consume those elements that we create. And when it comes to frameworks, the good news is that like most of what seems broken today, I think it's actually very easy to fix, and there's already issues open for most of it. And if we can generally agree on how custom elements should behave, and then in turn how frameworks should communicate with them based on those assumptions, then I think we're actually pretty close to this cool interop framework utopia land, right? Seeing that we now have libraries which get basically like perfect scores on the test that I've been able to write is really, really encouraging. I wanna thank all of these awesome folks. So the folks who worked on how to components with me, everybody who took the time to review the custom elements everywhere site and the test, and also just like hash out these best practices with me in docs and threads and everything. These are all very, very nice people who ar