 to the first ever virtual EmberConf in very strange circumstances. I am here talking to a big empty room. So thank you for everyone for bearing with us. I also wanna thank the speakers for having done all the work to make this possible in the first place on very short notice and thank the community for coming out and making this event the thing at all. Also thank you, Leia, for scrambling last minute and doing an amazing job with the conference, as always. My son Jonas was born on January 13th, 2017. A few months later, Leia, the person who makes EmberConf so amazing every year, my life partner and Jonas' mother, and also the person who made Virtual EmberConf possible, carried a few month old Jonas onto this stage to give her announcements. I remember feeling very sure that this was the right thing to do and at the same time, I was nervously watching the audience. Just a few months earlier, we were living a life without children, totally unable to see what was coming around the bend. It was a snowy winter, Donald Trump had just been elected, but Barack Obama was still president. In a lot of ways, we were waiting for everything to change, but not sure what would come next. That period stretched on and on and on. Jonas was over a week late and we were living in a quiet period, just ready for everything to change in ways we knew we couldn't predict. One of the first things I clearly remember from the first week after Jonas was born was filling out a commemorative form to remember what was happening on the day he was born. There was a section for president I remember filling out Barack Obama and thinking a lot about it. I was in general not very good at the first child posed photo thing. There's not a lot of smile here, but I was trying really hard. Another engineer at Tilda was pregnant at the same time and we knew that as business owners, we could do better than the status quo. After reading about the ways in which modern society leaves parents and especially women totally alone to take care of their newborn children, we decided to follow the lead of the Babies in the Workplace Institute and establish a policy allowing parents to bring newborn infants to work. We might be running a technology company, but we had a strong conviction that software went beyond the code that we wrote or how we organized our computers to gain a bit of extra productivity. Software fundamentally is a human activity and activity that we do together as human beings and we do our best when we support each other. A few years later, we're now on our second group of infants. We've learned a lot, but most of all what we've learned is that there's more to software than the number of lines of code you write or the number of minutes you're sitting in your chair. I knew that the Ember community valued building together and that we all valued an environment that was focused on sustainability, personal growth, and sharing. As I looked into the audience that day, I was extremely relieved to see happy faces. People in our community wanted to see that there was more to what we did than cool technology and fights over which paradigm is better. What I did not fully expect was the outpouring of support lay it out from people who finally saw themselves in our community's leadership, who saw that mother and community leader not only didn't conflict, but that the two could go hand in hand because there's something inside of us that wants more from open source communities than technology. We want communities that welcome newcomers, communities that support each other, and communities where the members help each other to be our best selves. I will admit, by the way, that I wrote that whole section before the current situation and it feels all the more relevant right now. At the same time as all that was happening, the Ember community was recovering from a rocky transition to the glimmer rendering engine in Ember 1.13. 1.13 had a large number of deprecations and those deprecations were removed just one minor release later. It was technically 2.0. While that sequence technically followed semantic versioning, it fragmented the ecosystem and created a lot of chaos. I'll never forget a conversation I had with a community member who had bet everything on Ember 1.12, pitching Ember to his company on the grounds that it was a stable platform to build on. Then we created a flurry of deprecations and removals and he just felt embarrassed in front of his peers and frankly betrayed. What we learned from that story is that semantic versioning doesn't tell the whole story of ecosystem stability. We could see that we violated Ember's basic premise, which is everything we do, we do it together, even though we followed the rules of semantic versioning. For the next few years, we invested in strengthening what we could do together as a community. The first RFC that we used, so the RFC process is what we use to make decisions as a community and the first one that we merged was in 2014, but for a long time, we used RFCs only narrowly for features like block params or tweaks to computer property syntax or engines. RFCs gave us a way to make decisions as a community together and during the 2.x series, after that 1.13 debacle, we refined the RFC process and expanded its footprint to virtually every decision we could make as a framework. By the time Ember 3.0 rolled around, we had refined the RFC process so it could be used for every decision we needed to make. We also came to understand how decisions guided by RFCs are better decisions. First and foremost, RFCs are tools to help us make decisions. The final decision is always in the hands of the core team that is responsible for the area covered by the RFC. The primary rule is that decisions of a core team must be made entirely on the basis of comments made or summarized on the RFC thread. Once the conversation reaches a steady state and participants aren't bringing any new information to the table, the relevant core team is prepared to make a decision. They declare a final comment period, which is a last call for comments before they make a decision. Typically if new information comes up during the final comment period, the core team will continue the discussion instead of proceeding. In short, the ultimate and primary purpose of the RFC process is to aid members of the core teams in making decisions with the benefit of as many perspectives as possible. Second, RFCs help core teams collect constraints from the community. By building up a collection of constraints, the core teams can arrive at decisions that better satisfy a broader cross-section of the community. Third, RFCs help those involved in an RFC build relationships. Those relationships often last into the implementation phase of the process and often even longer. In fact, some of my favorite stories from Ember come from people who found each other through RFC threads. In some cases, small communities spring up around RFCs, which sometimes turn into strike teams that work on implementation. The ad hoc nature of these relationships is a strength of this structure. RFCs provide just enough structure to get a conversation going but don't have much to say about the work style of the participants. This really comes in handy as we press RFCs into service to do more, as I will talk about soon. Fourth, RFCs help drive a discussion to completion and then provides a structure for implementation. By the time an RFC is merged, the implementation is either already complete or a small community has sprung up around it to drive it to completion. Just as the RFC process is a tool to help core teams make decisions, is a tool to drive discussions to completion. An RFC process that allows never-ending discussion is failing at this goal. Fifth, RFCs record the rationale and constraints for decisions that the core team makes. Later, when people wonder why a decision was made, a complete record of the final rationale for this decision, as well as a record of the discussion is available for inspection. This really comes in handy when the original rationale for a decision is no longer applicable. For example, a design decision based on a quirk of IE8. If the IE8 is no longer around, that decision is free to be revisited. Finally, and perhaps the most important, RFCs give people in the community a chance to feel heard, and I really do mean perhaps the most important. We learned this lesson after 1.13. When community members don't feel heard, it usually means we're not really listening. This undermines the legitimacy of the process and it also undermines everything else we hope to achieve with RFCs. A core team may be able to technically make decisions when people don't feel heard, but it is unlikely to collect all the constraints. Community members who don't feel heard don't build relationships around an RFC. Community members who don't feel heard continue to fight during the implementation phase and are unlikely to provide their expertise and assistance to get the feature over the finish line. This imperils the project's completion and community members who don't feel heard won't consider the recorded history legitimate, reducing the force of the project's history. So fundamentally, a successful RFC will make community members feel heard even if they don't ultimately agree with the final decision of the core team. So we realized that RFCs were a general purpose decision making tool that could help us make decisions, build communities around those decisions and drive them to completion. And we started to ask ourselves, given that definition of RFCs, why shouldn't we use RFCs for more things? In 2018, our community was using Slack, but we were quickly outgrowing it. Slack's free plan, which we were using, capped archives at 10,000 messages and we had to manually manage users. The framework team thought that we should move to Discord, but we knew it would only work if we really gave the whole community a chance to flesh out the plan with us and really buy into it. When we thought about it, we realized that is exactly a job for RFCs. We had iterated a lot on the RFC template over the years so that it more closely matched the goals of fleshing out and mobilizing around a proposal and it worked really well. We even had a how do we teach this section. For this RFC, because it was the first time we used it for something like this, we were paying a lot of attention to the need to ultimately wind down the conversation and make a decision. There were 164 comments on the thread before we finally wrapped up the conversation and the conversation helped refine the RFC and helped refine the policy around which rooms would be limited to users with certain roles, for example. Precisely because of the need to make a decision that we could all support, it was imperative that participants in the conversation felt heard. I was so proud of the way our community handled this discussion. The final comment that approved this RFC was a comment by Tom and I think this comment by Tom really shows what it looks like when a spirited conversation has slowed down and is ready to start driving towards a conclusion. So for example, Tom says, after several long discussions based on the concerns raised above, we still think Discord is the right next step and intent to merge this RFC. We do this with the awareness that this is not the preferred outcome for many people. This was before a final comment period which would have made more sense for this statement. And I really like this sentiment from Tom. Ember is its community, not its code base. Preserving the health of this community is my number one priority. A sincere thank you to everyone who commented on this RFC for or against. Decisions like this are not easy but I believe this is the right thing to do for the long-term health of Ember. And then the real test. This was an incredibly hard stress test of the RFC process. It lasted about six months from the time it was open until the time it was merged and it got 164 comments. Ultimately, we believe that by doing the work to respect each other and sincerely hear each other out, we are creating a strong healthy community that can go farther together. And this comment says, this is not the decision I personally favor but I appreciate that someone has to make a decision. That is the best case scenario for everybody felt hurt even though we don't all agree. Now if you think that moving to Discord is a tricky RFC, this next one is even trickier. Ember's website is the home base for many of our developers and it hasn't changed in years. And we kept hearing over and over again that it's time for us to update the website. But as much as everyone felt strongly that it was time for a big update, members of the community had very strong opinions about how it should change. And having done a lot of design work in my day myself, there was no way in hell I wanted to subject a designer to the kind of back and forth asynchronous discussion that the RFC process uses to drive decisions. There's nothing wrong with that process. It's just not really the process that a designer is used to going through. So what we needed to do is create a small strike team of community members who would work directly with the designer and represent the designer's perspective to the community and vice versa. It was pretty tricky to navigate but it was an important test of our capacity to make decisions as a community without a corporation's management hierarchy calling the shots and without the need for a benevolent dictator for life. I don't wanna do that. The RFC contained designs and illustrations so it was a pretty different kind of RFC. As the RFC progressed, the designs were tweaked and refined. To try to get as much community perspective into the first draft as possible, we analyzed our annual community survey and identified the values that those who responded to the survey described. This is one piece of that analysis but they're attached to the RFC was a PDF with a very detailed analysis of what kind of values came through in the survey and people should check it out. Now, as soon as we released the RFC, the RFC revealed a glaring oversight. In our effort to streamline the visual design, we had taken away something that Ember developers felt was a core part of their identity. Looks great, the only thing I'm missing is not seeing a Thomster anywhere on that page, wink. This turned out to be a critical discussion. Leia was very careful not to overwhelm the designer and soon enough, the designer popped in to give us a status update. And when all was said and done, we found a way to keep around Ember's iconic illustrations while still refreshing the visual style of the website. Ultimately, because of the magnitude of this project, this RFC was co-owned by the Frame Report team, the Learning Team and the Steering Committee. It was approved by all three groups and its implementation was managed by the Learning Team. If you go to emberjs.com today, you can see the fruits of this labor. Just like the Discord RFC, because we were doing something like this for the first time, we were experimenting with using the RFC process to work together as a community to do something really outside the realm of Ember APIs. We paid close attention to the need to make final decisions, especially because we were working with a designer who was not directly involved with the RFC process itself. We were also very focused on making sure that the plan could be implemented by the Learning Team and a lot of the thread is about that and ultimately finished. And just like with the Discord RFC, we knew that making sure that everyone felt heard was critical to marshaling the kind of effort that we would need to implement the website at the end. It is also worth noting that in addition to the number of people who raised concerns about losing our iconic illustration style, the RFC process also unearthed another constraint, accessibility. The Learning Team was already waist deep in an effort to improve the overall accessibility of the website and this new homepage needed to continue to build on that effort. Now, the reason that most people wouldn't even consider updating the website through the RFC process is fear of the dreaded design by committee. I remember in my very first web development job being told to put a counter at the bottom of the page, I said, what's the point of that? Very few people actually go to this website. Wouldn't that be very embarrassing? To which I was told, don't be silly. Did you think we wanted you to put the real count of views there? That's what design by committee looks like and it's a disaster. In this case, we weren't using the design process to iterate granularly with the designer. We would never, ever use the RFC process to do something that looks like design by committee. Instead, we were using the RFC process to help the leadership of the project make decisions that were well informed, recorded, implementable and which made members of the community feel heard. We've also invested in giving people a path to join the core teams provided they are willing and able to do the work. This has always been an extremely important part of Embers community focus. Our goal and our yardstick is this. Our core teams should represent communities, companies big and small, big, medium and small, countries all over the world and people with many different perspectives and identities. The more diverse our leadership teams are, the more likely their decisions will reflect the wider community and the more likely it is that the wider community will reflect those decisions. We'll respect those decisions and the core teams have a place for people doing all kinds of different work. Designers, event planners, project managers and illustrators are all part of Embers community leadership team. With the completion of the Discord and website RFCs, our community process had proven itself. It had become a general purpose tool for helping us organize discussion, drive towards decisions and mobilize implementation. We didn't need a single corporation to make decisions for us through its management hierarchy and we didn't need to vest all decision-making authority in a single person to move faster, no matter how benevolent that person might be. We had learned to move together. These RFCs also proved that we can do the work together and still make progress. It reminds me of the adage, go slow to go fast. I found that if you try to blow past community descent and make command decisions, you're taking on community debt that will crop up randomly later on. Because at the end of the day, Embers core belief is that we're all in this together through ups and downs, through thick and thin, through coronavirus or whatever. We're all willing to work as hard for each other as we work for ourselves. And that means continuing to build the capacity to work together. But trouble was lurking. While we were investing our energy in bringing the community together, by 2017 the Ember framework felt like it was starting to fall behind. In Ember, moving as a community is our highest technical priority. At the beginning, that meant that our users had to wait for the community to design new high level features to make progress. This slows down enthusiastic early adopters in our community. It also deprives us of the feedback of experiments. So to get our community to experiment more, maybe we could announce features that are still just ideas. Then our community could help us flesh them out and help us figure out what the problems are. This is not a solution for Ember. It places too much of the onus of experimentation on the people who are just trying to ship new features and make progress with their apps and who are not excited about taking the time to experiment at work. What we realize is that for every nine people who are just going about their day, building features and making their customers happy, there's about one person who is excited about trying out new stuff, either because they really, really need it, or more likely that they're just a kind of person who likes tinkering with new stuff. This reminded me of a talk that Brandon Hayes gave called Surviving the Framework Wars. He said there are three kinds of people in a community and they correspond to three different stages of development in a community. He cited somebody, the link is on this slide. Pioneers are, so pioneers are responsible for the early vision of the project and for doing the experimental work that gets it off the ground, Brandon said. Settlers are responsible for long-term strategy and synthesis and town planners are responsible for tactics and execution. By the way, depending on the day, I personally might be a pioneer, like when I'm working on Glimmer VM features, a settler, when I'm working on Skylight, or a town planner when I'm attending framework meetings. I actually think it's very important to be able to conceive of people moving seamlessly across these roles. What we realized when we thought about it is that in our ideal community, the people who are excited to experiment with new features can play around and in that ideal community that wouldn't disrupt everybody else. And every so often, when this is going well, the excited experimenters share the love by creating add-ons that the rest of the community can use. We've seen this happen over and over with Fast Boot, Mirage, Ember Twiddle, Ember Observer, TypeScript Support, and so much more. Even without our direct support, the kinds of people who are excited about experimenting with new tools bring new stable features to the rest of the user base in the form of add-ons. On its own, the pioneers do an amazing job of fleshing out experimental ideas, finding problems, suggesting solutions, and creating add-ons for users. But what we realized around 2017 is that the core teams could make their job even easier by changing our process. Instead of the core teams fully designing high-level features, landing the whole feature by a feature flag and then stabilizing it over time, we could involve the pioneers directly. We could instead land and stabilize low-level features that we did not intend everyday users to use. And we could let the pioneers hammer on them to flesh out high-level APIs. The key is to make sure that Ember's settlers see all the activity, but understand that they're free to continue doing their everyday work while the pioneers chart the next course. There's a certain joy in embracing the idea that you're getting your work done, and you don't need to be a part of every little twist and turn of the effort of the pioneers. Starting in 2017, we started learning how to make a process out of shipping features as low-level primitives first and let the pioneers flesh out the high-level APIs. We fleshed out the idea in our 2017 keynote the same year that we announced Glimmer.js. Now, Glimmer.js was our first serious attempt to chart this course, and let's just say we learned from that experience. By 2018, we had become fluent in the idea. When we wrote the routing service RFC, we had the basics down. And by 2019, with the Modifier Manager API, we had become pretty confident that the approach was working. By then, we had years of experience shipping new features, first as low-level primitives and saw that Ember's settlers could keep humming along just fine. This quote is basically saying in the RFC, we're not very worried about fragmentation. We've done this a bunch of times and everything is humming along just fine. And in practice, let's look at how that worked. So the Visit API becomes fast boot, Component Manager becomes Glimmer Component, and Modifier Manager became Ember Modifiers. The key is that when we ship new APIs like Component Manager or Modifier Manager, we focus on unlocking experimentation and flexibility, and we use names that clearly communicate that application developers don't need to look at them now. They also need to tend to be designed with an eye towards evolution. These low-level APIs tend to be much more stable than higher-level APIs, which means that the experiments that people build in user space continue to work even when we eventually finalize something else in core. We give the pioneers the tools that they need to pioneer and leave the settlers alone to settle. Now, a totally valid alternative to this story is to announce new APIs while they're still being designed and encourage everyone in the community to participate in the process of fleshing them out. That gives the whole community, including the settlers, a QA role, and it probably uncovers more information, but it cuts against Ember's core value, placing too much of the onus of building new features on Ember's settlers. At first, this was a serious issue for us because our pioneers had nothing to do unless they were able to contribute directly to Ember's source code, but since 2017, we have focused on community innovations that would give Ember's pioneers a lot to do, improving how quickly we could build new features without creating the kind of fragmentation that cuts so deeply against our core value that everything we do, we do together. By 2019, we had gotten pretty good at this. Our pioneers were cranking out new add-ons left and right, and Ember's core teams were focused on building low-level primitives so they could work with the pioneers to build the next-generation high-level features. There was only one problem. Most Ember users had no idea when they should adopt any of these features. In some cases, the features had gone through the entire lifecycle, from primitive to pioneer to stability. In other cases, features were still going through the lifecycle. While this was moving Ember along technically, it was obvious that it wasn't the end of the story. We had one more lifecycle problem to solve, and for Ember, it's the whole ball game. How could we move our community to the new world that we were building together? So in last year's keynote, we announced the last piece of community innovation puzzle, last piece of the community innovation puzzle, additions. Ember Octane would be the first addition. An addition serves as a call to arms to the community's pioneers. It's time to turn a collection of features into a new world that we can migrate our entire community to. In the meantime, the settlers keep on working. They can see all the exciting work going on to get everyone ready to migrate to a new, better world, and some might even find it exciting enough to do some pioneering of their own. But most people continue to get their job done day in and day out and wait for the call to march together. Although Jen Weber couldn't be important in person this year, she created an Octane trailer for us to watch. Let's roll the tape. Today's presentation has a lot of information for and about our community, but it's also a time to share a message with the broader JavaScript community. Ember is a front-end framework that has something new to offer you, a new set of tools, and a new way of working on web apps. Our latest work is called Ember Octane, and it's a total overhaul of Ember's syntax, mental models, and learning journey. If you tried Ember before, this is pretty different. One of Ember's long-standing core strengths is that it includes the things you need to build a successful software product, tools that are built to work together. Now with Octane, it puts HTML first. It puts components front and center. Developers can learn by following thoroughly tested, free, brand new tutorials. And this past December, we shipped Octane in a minor stable release, building some of the best new features that the front-end has to offer on top of a solid dependable foundation. Ember developers didn't have to rewrite their apps in order to start using these features. Let me take you on a tour. With a few commands, I can generate my app, install and use almost any popular JavaScript package from NPM, and add some markup, interaction, and CSS. I can write some end-to-end tests, run them, run a production build, and deploy. I can do all of these things with zero config. Along the way, I learned some important things in a guided way. Out of the box, every new Ember app comes with linting that guides me to make good choices for following coding best practices and improving my app's accessibility. And when I work on other projects, I bring my knowledge and expertise about the web with me. Here, I'm copying and pasting some D3 code I found on the internet into my Ember app. In the end, I have more time for doing the things I enjoy as a developer. Whenever I have questions, it's especially helpful to be part of this community. I can get debugging help from other people without needing to explain my app's architecture first. The Ember community includes developers who work at companies that have thousands of engineers. They work at small startups with scrappy teams and the drive to build something new. They're hobbyists who choose Ember for their side project because it lets one person get a lot done. And anyone can participate in shaping Ember's future by making proposals for new features or providing feedback on the things that others have written. We're all using the same core tools and that opens new possibilities. If you need to move quickly to get your app into production or you want to learn what it takes to get there, we invite you to try Ember Octane. Let's build something together. We spent a lot of time talking about how Ember has improved its capacity to move together as a community and we just watched Jen quickly walk through Octane. But now I want to take a few minutes to rewind back to 2005 and talk about my own journey from print designer to programmer. When I started programming in 2005, I already knew HTML and CSS, sort of. At the time, I had five years of experience as editor-in-chief and main designer of two school newspapers. My designs had won some minor awards and I had learned enough HTML and CSS to lightly modify the CMS that my newspaper used to put its content on the internet. This is a not fully complete comp that I found in my email from back then. When I took my first job as a web designer, I assumed that my experience as a print designer would carry me forward as I found my digital footing. The person who hired me had the same assumption. Virtually all of my jobs before this one were low-paid, hourly work. This web designer job paid $37 an hour, but it was part-time 20 hours a week. Still was a living wage at a respected nonprofit. On my first day at the job, I was told that the company had cut ties with the digital agency that had been managing the websites of a dozen or so departments and expected me to take over the responsibilities effective immediately as a half-time employee. I was hanging on for dear life. For my first project, I updated the website for the nonprofit's annual dinner. It was a cold fusion website. Next, I built a brand new microsite for a basketball tournament fundraiser then a golf tournament microsite. In the meantime, demands from half a dozen departments were piling up. They had replaced a digital agency with a half-time employee whose only web experience was Microsoft front page. I was only supposed to work half-time, but my desk was piled high with requests to make changes to various parts of the organization's website, requests for brand new microsites, and requests for meetings to discuss and plan even more websites. I frequently worked 30 or even 40 hours a week just to keep up with the most urgent demands. I realized that my print design experience wasn't gonna get the job done. I needed to learn how to program and I needed to learn fast. I remember walking into Barnes & Noble, going into the programming section and feeling like the information I needed was somewhere inside the books on those shelves. I didn't have a ton of extra money at the time, but I picked up a PHP and MySQL book and I read it cover to cover. I felt a great sense of relief. This was gonna work. I already knew HTML and CSS and I was gonna be able to use PHP to speed up my work. I could stop spending hours keeping headers and footers up to date. I could give people in the organization a tiny form they could use to update frequently changing copy on the website. It made a huge difference. I was still copying and pasting PHP files from the last project into the new one when I created a new microsite, but the structure really helped. That didn't mean I suddenly had a lot of free time. I was still totally new to programming and the requests were coming in fast and furious. It's just that I was now getting things done and I wasn't totally embarrassed by the base. Then I learned about Rails. Instead of including the header and footer into every page, Rails had the concept of layouts. I remember thinking that layouts were so much better. I could take the HTML and CSS. I was writing in PHP files, move them into a Rails app and everything got better. Instead of ad hoc forms where people could edit tiny pieces of copy, I could finally build the CMS backend I always dreamed of, always for a few months. This is an image from about a year later when I turned it into a Rails plugin. To be honest, I was probably a little bit in over my head at the time, but I actually did build the CMS for the departments in the organization to use. Just a few months after realizing that I actually needed to be a programmer, not a designer. What made all that possible, and the reason I'm a programmer today, is that when I was in over my head, barely hanging on, I was able to build on the baseline knowledge of HTML and CSS a little bit at a time, never having to build, burn weeks of time at work on learning a whole new paradigm. Frankly, if I had tried to learn a new paradigm, I would have probably have been fired and looking for a new print design job before I could ever become a programmer. So this is very personal to me. I wouldn't be a programmer today if I hadn't found tools that took my HTML and CSS knowledge and helped me build on it. Here's what I'm talking about. There's basically three steps. You wanna get your portfolio, your marketing website, or your personal website online. Create a new app, you wanna take your HTML and CSS, and you wanna deploy it. And you want space to grow into a dynamic website with dynamic URLs as you learn more. And you don't want an easy bake oven. You don't want tools that only beginners use. You want tools that everybody uses. I'm talking about using tools that a community of professional web developers use to build large applications with hundreds of engineers. In 2005, what I needed was a way to incrementally supercharge my HTML and CSS skills. And this is something that has always weighed heavily on me. I personally built HTML tokenization, parsing and tree-building infrastructure into Glimmer VM. And we have worked extremely hard to support valid HTML, including SVG. Here's an example test if you don't believe me. You might not believe me because SVG is the bane of everyone's existence. Even though we cared a lot about this use case and kept pushing Ember towards being a great fit for people who already know HTML and CSS, there was already one major stumbling block. There was always one major stumbling block. Ember required users to configure the root element of every component using a weird JavaScript DSL. To be honest, even though we had done so much work to align Ember with HTML, I didn't feel like the Yehuda of 2005 would have been able to bootstrap a programming career with Ember. And yet, it wasn't like there were a lot of other options out there for that person. What's really incredible to me is that the Octane programming model has enough improvements that we could update the documentation to teach components HTML first. The picture on the right is an example that we first introduced in the first section, which is called templates or HTML and used throughout the guides. And this is the first place in the component guides where JavaScript comes up at all. In isolation, each feature of Octane might seem small, but in aggregate, they make enough of a difference to change the way we write Octane apps. And if we change the way we write Octane apps, of course, we need to do it together. And that's why we refresh the guides based on this new way of teaching and using Ember components before we were ready to call the whole community to migrate to the new world. And we could finally, and with enthusiasm, tell all of our users about the work that we had done to bake HTML so deeply into the Glimmer VM. Going back to the beginning, this means that if you know HTML and CSS, you can take your existing code, drop it into an Ember application, deploy quickly to production, and share it with your friends. This goes for Tom's World of Warcraft Guild website, which is the first website Tom made as a programmer. It goes from my basketball tournament website, and it goes for your portfolio or marketing website. And you can iterate on your skills, just like I did with PHP and Rails, to add interactivity to your website. Godfrey is gonna get into a lot more details about what it looks like technically, about what HTML first looks like technically, but this is the goal. And once you get your website on the internet, which is really the important thing, it's important that you have something on the internet that you can share with your friends or a potential boss or a potential person you're applying for a job at. There's room to grow. You could add interactivity using the component JavaScript API. You can add more pages to your app with the Ember router. You can add server-side rendering using Fastboot or even Empress to build on your Ember knowledge to build a Jamstack app, which there will be a talk about in this conference. And my personal favorite is you can use Airtable as a backend to add some dynamic data to your app. The coolest thing about Airtable is that after you design your tables, you get custom documentation that's localized for the exact table and columns that you created. You can just copy and paste it into your application. And if you're feeling really adventurous, you could try it in Broader, which brings automatic route-based code splitting to your app. It works today and a lot of real-world apps already work with Embrator, but not every add-on supports Embrator yet. Ember's pioneers are hard at work to bring Embrator to everyone, which means that all Ember apps will soon have route-based code splitting without any special annotations just by using Ember's router and components normally. If you fancy yourself a pioneer, try it out. That's really cool. Whether you're just starting out with an HTML and CSS in your pocket and dreams of becoming a web developer, or whether you're a pioneer looking to help chart the course to embroider for the rest of the community, Ember has a place for you. And if you're looking to become a part of Ember's leadership, there's a team to shoot for regardless of your skill or prior experience with framework code. If you have experience with infrastructure, writing, or web development, the learning team would love your help. If you love project management and want to put those skills to good use, reach out. You don't need to be a wizard at framework development or have an interest in becoming one to have a path to leadership in Ember. If you're interested, reach out to a member of the steering committee, framework team, or learning team, and one of us will try to help you figure out what your path might look like. Ultimately, what I have learned being a part of this amazing community is that there's much more to web frameworks than code. We strive together, we're ambitious together, we move together. And now, when the only way to stay safe is to distance ourselves from one another, we need each other more than ever. For posterity, I want to bring Jonas up on the stage one more time. Roll the tape. Look at me, I made an antibody with a header. You painted an antibody? That's great. What's your antibody gonna do? It's gonna go track down the small virus. Oh, what's it gonna do when it finds a virus? It's gonna track it down. And then what's it gonna do? It's gonna start. It's gonna stop it? That's great. And then you'll be healthy? Yeah. That's so good. What a great antibody. As they used to say when I was growing up, from your lips to God's ears, kid. Next up, Godfrey is gonna do a deeper dive into the technical details of octane. But first, let's watch Jen's trailer again because it's so cool. Today's presentation has a lot of information for and about our community, but it's also a time to share a message with the broader JavaScript community. Ember is a front-end framework that has something new to offer you, a new set of tools, and a new way of working on web apps. Our latest work is called Ember Octane, and it's a total overhaul of Ember syntax, mental models, and learning journey. If you tried Ember before, this is pretty different. One of Ember's longstanding core strengths is that it includes the things you need to build a successful software product, tools that are built to work together. Now with Octane, it puts HTML first, it puts components front and center, developers can learn by following thoroughly tested, free, brand new tutorials. And this past December, we shipped Octane in a minor stable release, building some of the best new features that the front-end has to offer on top of a solid dependable foundation. Ember developers didn't have to rewrite their apps in order to start using these features. Let me take you on a tour. With a few commands, I can generate my app, install and use almost any popular JavaScript package from NPM, and add some markup interaction in CSS. I can write some end-to-end tests, run them, run a production build, and deploy. I can do all of these things with zero config. Along the way, I learned some important things in a guided way. Out of the box, every new Ember app comes with linting that guides me to make good choices for following coding best practices and improving my app's accessibility. And when I work on other projects, I bring my knowledge and expertise about the web with me. Here, I'm copying and pasting some D3 code I found on the internet into my Ember app. In the end, I have more time for doing the things I enjoy as a developer. Whenever I have questions, it's especially helpful to be part of this community. I can get debugging help from other people without needing to explain my app's architecture first. The Ember community includes developers who work at companies that have thousands of engineers. They work at small startups with scrappy teams and the drive to build something new. They're hobbyists who choose Ember for their side project because it lets one person get a lot done. And anyone can participate in shaping Ember's future by making proposals for new features or providing feedback on the things that others have written. We're all using the same core tools and that opens new possibilities. If you need to move quickly to get your app into production or you want to learn what it takes to get there, we invite you to try Ember Octane. Let's build something together. Thank you, Jen and Yehuda and hello everyone. Thank you for tuning in to Virtual EmberCon 2020. I'm Gottry from the Ember team and I'm here to give you an update on all the exciting things that happened this year in the Ember world. Of course, as you probably noticed at this point, the most important news of all is that we shipped Octane, a new edition of Ember. But what exactly is Octane? As you saw in Jen's trailer, Octane is a lot of things. It's a major update to the framework. It's a set of new features. It's new program model. It's new defaults when generating apps. It's a new set of recommendations and linting rules as new website update, documentation, blah, blah. Sure, it's all of those individual things but above all, Octane is really an opportunity for us to present Ember to developers outside of our community. It's a chance for us to say, hey, we have made a lot of improvements to Ember and we think you really like it. Based on the feedback we've received so far, I think it's probably safe to say we deliver on that. Believe it or not, we actually got an entire page of positive reviews and heck of news that you didn't see that coming. For a lot of us existing Ember users though, things might feel a little bit different. Sure, we hear a lot of things about Octane on internet. There are a lot of new things but hey, we have an app to maintain the work and it's not like we're going to rewrite everything overnight. That's the whole point of using Ember after all. It's about the stability, right? Well, we totally get that and that's why we focus a lot on incrementalism and backwards compatibility. We ship and stabilize these features incrementally whenever they're ready. There's no breaking changes. We also make sure there's a good interrupt story between a new and old paradigms. We think this is a pretty good time to upgrade overall but if you want to do that, we have written code mods and other migration tools to help with that but ultimately the choice is yours and your existing code is not going to suddenly stop working any time soon. That's all great but because things are so incremental and so backwards compatible, for a lot of us long time Ember users we're mostly focused on the mechanics. Like what switches do I have to flip to upgrade my app? What is the transition path from A to B? Things like that. These things are of course very important but they can also cause you to miss the forest for the trees. When you're so focused on the mechanics you might miss the bigger picture and don't fully realize how different things really are. So for the purpose of this segment I want to invite you to go ahead and forget everything you know about Ember for now and let's try to give Ember a fresh look from the perspective of a new user. I'm going to highlight three major areas of Octane that I think are pretty representative and through these examples I hope to show you the many ways that we are now thinking about these features differently in the post-Octane era of Ember. So here we go. As you should have mentioned from the beginning Ember positioned itself as a framework for building ambitious web applications. At the core of the web platform there's HTML and there's CSS. So at the core of the Ember framework it's just HTML and CSS. We want to embrace the web platform and power web developers to build on top of these familiar foundation technologies and be able to do more with them rather than getting in your way and requiring you to learn something completely new and different. If you already know HTML and CSS you should really be able to dive right into the world of Ember and view right at home here. This has always been a goal of Ember and in fact this is the reason Ember was born in the first place as a fork of sprout core that focuses more on an HTML first approach. However, historically they have always been some accidental shall we say annoyances both big and small that kind of gets in the way and undermines our position here. A big part of Octane is to clean up these complexities. Let me show you some examples. When creating a new Octane app you can go straight into your index template plop down some HTML, some CSS and bam everything just works the way you expect. This means you can drop in any markup you find on the internet maybe from Stack Overflow or perhaps some markups that you receive from a designer without making any special modification or tweaks to use them in Ember. It even works with things like SVG and web components. You can keep your typical web development workflow such as using browsers built in DOM Inspector and there will no more strange Ember wrapper elements that messes with your CSS anymore. This may seem like a small change on its own but it's a good example of the kind of HTML and CSS first experience that we aspire to provide. As you will see Octane is all about making these steps that seem small by themselves but when taken together they add up to more than just the sum of the parts. Speak of CSS, you can look forward to tomorrow's session and Ember Devs guide to CSS Grid. By embracing HTML and CSS we can immediately take advantage of and benefit from the web platforms latest and greatest features such as CSS Grid without having to reinvent the wheel and like invent a new library or patterns to import these ideas into Ember world. Check that out tomorrow at 1.30 p.m. The time is subject to change so check the schedule for the latest time on these talks. Okay, so we have seen that HTML works exactly the same way that you would expect them to in Ember. That's cool but of course HTML and CSS alone is not sufficient to build an ambitious application. Otherwise Ember probably doesn't need to exist at all. Instead we don't want to fight or replace HTML. We want Ember to feel like a natural extension of HTML instead. With Octane I think we've got something that feels pretty great here. One of the limitations of HTML is that it doesn't give you a whole lot of tools to organize your code. Back to our example here, you can see that there are a lot of markup on this page but if you look at the render output it's pretty clear that there are some high level groupings that would be helpful to reflect in the source code. It would be great if you can look at the source code and the clients kind of know what the render page looks like or at least what are the important parts of the page are. In Octane this is pretty easy. All you have to do is create a new template file in the components directory, move over your section of markup and that's it. The output looks exactly the same as before but you have just created a component to encapsulate this whole navbar section of your markup. By separating out these logical units and giving them meaningful names your source code is now much more readable. That's not the end of the story though. As you can see at the bottom half of the page we have a couple of these cards each representing a different rental property on the site. So while they all have the same visual and markup structure the information they present is different. We could just copy and paste this markup every time we need it in one of these but as you have probably experienced this is going to become a maintenance nightmare very soon especially in an ambitious code base. Don't worry though we got you covered here too. Just like before we can extract the markup into a new component by moving them into a new file. However instead of hard coding the information we can replace them with placeholders using the curly braces and add syntax. These placeholders are called component arguments. When invoking the component we can use the same add syntax to pass these arguments into the component filling in the placeholders we defined earlier. Now you have created a parameterized component that can be reused in different parts of your app just by passing different arguments in different situations. You can think of this as giving you the ability to create abstractions in HTML. In a traditional programming language you're probably going to take for granted the ability to split things up into functions. They allow you to break up your code into small self-contained and reusable pieces that can be glued together to build something more complicated. Components in Octane give you the same ability to do the same thing with your markup. It doesn't stop here though. Octane gives you a complete suite of tools in order to become a productive ambitious markup developer. For example, we added support for component name spacing which allow you to group related components into folders and invoke them using the double colon syntax. The split attributes feature on the other hand allows you to pass arbitrary HTML attributes to your components which comes in handy when you need to titler the CSS classes or the ARIA attributes for a particular usage of that component. Likewise, you can also pass content around with blocks and yield keyword and soon you will even be able to pass multiple name blocks when invoking a component. Of course, we have always supported control flows like conditional, if, unless, and loops like each. And soon, there will be a built-in logical operator that you can use without needing to install a separate add-on. Speaking of which, of course, we shouldn't forget that Ember gives you access to a vast component library via add-ons maintained by the community as well as the ability to package up your own components to share with the world. All in all, Octane, in Octane, we have set out to create, to complete our vision of being HTML-first framework, creating a flavor of enhanced HTML that works for building ambitious web applications. And I think we did a pretty good job on that front. You may also have noticed that up until this point, we have not written or discussed any JavaScript just yet. This is not a coincidence. Historically, JavaScript is a pretty integral part to the Ember component model. In fact, it is probably fair to say that before Octane, Ember components were first and foremost JavaScript driven. There was always a JavaScript class associated with each component, and there is a wrapper element owned by the JavaScript class. The wrapper element was configured using a JavaScript DSL, and the JavaScript class itself was responsible for intercepting and handling user interactions with the component. To a lot of Ember developers, this JavaScript API is probably the first thing that comes into mind when thinking about components in Ember. In fact, some components don't even need to template in that old world because all customizations were done entirely using JavaScript. In Octane, we flipped it the other way around. Hopefully, I have convinced you that components in Octane are first and foremost driven by HTML and template. As we just saw, this is a pretty viable programming model, and in a lot of use cases, a template is all you need in Octane. Gone is the wrapper element, and what you see in your components template is what you'll get in the DOM. If you want to add a class or if you want to add an HTML attribute, all you need to do is add in a template, no more JavaScript DSL. We have refactored internals of the rendering engines to remove the need for a JavaScript class when rendering a component. In Octane, when rendering a template-only component, Ember no longer generates and will locate a component instance, and for the most part, this is a pretty subtle change that happens under the hood, but you may notice it from the improved performance and not having access to the special of this object in a template-only component. More importantly though, this is a significant Mandem-Water shift in how we think about components in Ember. Now, components are all about the template, and any JavaScript you add is secondary to that. To reflect this shift, we have moved the component templates in your app from the templates folder into the main component folder and adjusted the generator's default output accordingly. As I mentioned at the beginning, we're mostly focused on giving Ember a fresh look here. If you want to see more of the how the past compares to the present, you can look forward to Shoshita's talk later today. Okay, so even though templates get you pretty far in Octane, we still love JavaScript, and we're still a JavaScript framework after all, and you're still going to need plenty of it. It's just that JavaScript now plays a pretty different role and serve a different purpose in Octane. In Octane, the primary purpose of JavaScript has switched from managing the DOM to managing data. First, for general purpose computation that you plan to reuse across the app, you can use helpers for that. Nothing really changed here in Octane, except due to the increased utility of template-only components, I think you may find more places in your app where creating a helper feels like the right choice. It's also worth mentioning that helpers, and including class-based helpers, now participate in the auto-tracking system, which I'll go into a little bit more later. But what about integrating JavaScript into components? Well, I'm glad you asked. Let's look at an example. Here we have a share button component that allows the user to share the current page on Twitter. This component, this is the component with its markup, and for the most part, it's just a hyperlink. Twitter has this intent API that lets you prompt the user to compose a tweet just by linking them to a special URL, and you can customize the suggested tags and the hashtags using query parameters and stuff like that. While the functionality of the component is very simple, it's just a link after all, you will probably need to write some JavaScript code to build up this special URL, especially when you want to make these things customizable via past end component arguments, and you will need to also URL and code the query parameters. So you can probably accomplish this with a series of helpers, but it will probably feel pretty clumsy, and it's probably not super appropriate to add a bunch of specialized helpers globally just for a single component. So this is the perfect kind of use case for adding JavaScript class to a component, and with Octane, that's pretty easy too. You can accomplish this by creating a JavaScript file in the same place next to your template, and this is what the code looks like. Just as we spent a lot of attention making Octane templates feel like a natural extension of HTML, the same amount of effort went into making sure our JavaScript API leverages native JavaScript syntax, features, and idioms. Here we have a share button component class subclassing from glimmer component. In our component class, we have access to pass in arguments via this.archs, which we took advantage of in our share URL getter. Since we added a JavaScript file to our component, we now have access to the component instance via a special this object in the template. And since we made share URL a getter, it behaves just like any other property on the component instance, so accessing curly, curly, this.share URL just works in the template. All of these are done using native JavaScript features, and we didn't have to make any special annotations to make it work in Ember. I hope you agree with me that this feels totally in line with more JavaScript, and nothing about it jumps us as weird Emberism. When it comes to integrating JavaScript into the DOM, the challenge has always been about keeping the DOM output in sync with the JavaScript code, or the JavaScript state. While it may not be super surprising that you have access to this.share URL, the getter in the template, the surprising thing here is that whenever the pass in arguments changes, Ember will know to rerun your getter and automatically update the DOM output. So in this case, if this.arc.text changes, Ember is going to recompute your share URL getter and automatically update the href attribute in the DOM. We didn't have to write anything like ember.get or enumerate our dependencies anywhere. How does that work? All of this is thanks to the new state of the art, auto-tracking system. Whenever you reference component arguments in your template, Ember is now able to keep track of the dependencies automatically, so we know when to update the output. This works consistently whether you're referencing them directly in the template, or when you're referencing them in JavaScript, or when you reference them through a getter or a getter calling in a getter, getter calling out of functions, et cetera. As far as Ember can tell, all of this just works the same way and Ember is able to follow through the chain of dependencies without any issues. This capability is not unique to component arguments. Your own code can participate in the auto-tracking system too. All you have to do is add an attract annotation to any property you want to use in the template and you're good to go. Here, for example, we have a rental image component with is large property on it, indicating whether we're displaying the image in the extended format or not. When the value of this property changes for any reason, Ember would take note of that and re-render the template accordingly. Of course, just like with arguments, this works just as well when you reference them directly in the template or when you access them through a network of getters, external functions, et cetera. It works all the same way as far as Ember is concerned. So far, we've been focusing on components, but it doesn't stop here. As I mentioned earlier, helpers can also fully participate in the auto-tracking system as well. In fact, the auto-tracking system and track properties work consistently on any arbitrary JavaScript classes and you don't even have to subclass from any particular framework superclass like Ember Objects. So you can create your own model class and it will put a track property on it and it will work just fine. This allows you to implement your business logic in the own little self-contained model and utility classes and then you can just lightly glue them together in your component. More importantly, the auto-tracking system allows us to refactor existing push-based data flow based on observers and arguments dipping into on-demand pull-based computations. Refactoring existing code to fully take advantage of this new program model can probably be a talk on its own, which I don't have time for. But you can look forward to future blog posts on this topic and I suggest you to experiment that on your own as well and share what you've learned with the community. If you want to understand how the auto-tracking system works under the hood, you can look forward to Chris Gareth talk tomorrow in which he will show you the nitty-gritty of the system and how it compares the other framework. So check that out. Okay, so we have talked about templates. We talked about how to integrate JavaScript state into templates and so the last piece of puzzle here is how to work with the DOM. Of course, for the most part, managing the DOM is not something that you have to do explicitly. As you saw earlier, when using templates, Amber will take care of updating the DOM whenever your data changes in the JavaScript world. However, when it comes to user interaction, you'll often want to work with the DOM directly. So here is a couple of examples. Here we're back to the same expandable image example that we saw earlier. We have wire up that is large track property but we don't have any way for the end user to toggle its value at the moment. What we want to do is to call the toggle size method on the component instance whenever the user clicked on the button. In Octane, we've made this pretty straightforward. First, we'll import the action decorator and annotate the toggle size method as an action. This turns it into a callback that we can use in the template. Next, we will add the built-in on modifier to the elements that we're interested in. In this case, we specified that we want Amber to call the toggle size method on a component instance whenever either of the buttons are clicked. With that, the user can now click on the image to toggle its size. The thing that we added to the template here is called an element modifier or modifier in short. It looks like the placeholder syntax that we're used to but it's attached to a particular HTML element in the same position where attributes usually go. The built-in on modifier allows you to attach event handlers to HTML elements, but the concept of element modifiers is more general than that. In Octane, this is how you interact with the DOM. And just like helpers and components, you can write your own element modifier in your app. Let's look at an example for that. Here, we're back to the index page of our app and there's a search input box on the page. Perhaps you might want it to be automatically focused whenever this page is rendered. Knowing what you know about HTML, you might be tempted to put the autofocus attribute on the input element like that. Unfortunately, the autofocus attribute is really designed for server rendered static pages so it only works on the initial page load. Since we're rendering content with JavaScript, it doesn't do anything for us. No problem though, we can write a modifier for that. We created a file called autofocus.js inside the modifiers directory. Inside the file, we wrote a small class that inherits from the modifier class provided by the Ember modifier package. Here, we have access to the element. In this case, it will be our input element and whenever the autofocus modifier is attached to an element, Ember will call the focus method on the element to make it the active element on the page. We think Ember, we think element modifiers in Ember are a powerful and pretty intuitive way to work with the DOM. Just like components and helpers, they can be packaged up into reusable add-ons and we look forward to the community finding and sharing new innovative use cases for them with the wider ecosystem. And in fact, some of this is already happening. Let's look at two more examples. The first example uses the official render modifiers add-on and just like Jen showed us in the trailer, we want to integrate with the external D3 library in this case. The bulk of the code here comes from a D3 example that we found online and we're able to mostly just paste in the code verbatim. I don't expect you to read all the code here on the slide, but the important thing here is that the render modifier add-on provides a convenient way for us to run a callback function on a component whenever a particular element is rendered, which is exactly what we need in this case. And here we have another example. Here we have a video player component which consists of an HTML video element and a play button. What we want to do here is for the user to be able to click the play button and it should start playing the video. In order to do that, our play method need to have access to a video element, but how are we gonna do that? Well, this is where the Ember ref modifier add-on comes into play. It's a perfect use case for it. Here we'll add the ref modifier on the video element. This gives us access to the element in our component using the name we chose in this case. It will be this.video element. This allows us to finish implementing our play method and with that, our user can now click the play button and start playing our cat video. That concludes our brief journey into Ember Octane. I hope you agree with me that it is an incredibly intuitive and productive program model and if you have been using Ember for a long time, this feels pretty different from the framework that you once learned in the best possible way. I only had time for a few selected highlights, but most of these examples are taken directly from the official guides and tutorial. They've been completely rewritten for Octane and I think they're pretty good. I encourage you to give them a read and I think you'll be surprised. Before we wrap up, I wanna talk to you about what comes next. So here comes the part where I spill all the beans on the super secret things that we have been working on. Actually, there's no secrets. In fact, we have a roadmap RFC publicly on GitHub. It's been up for a couple of months at this point. The roadmap is set based on the results from last year's community survey and a public call for a blog post that you can participate in. The steering community then take all of these feedback and come up with a couple of general directions and you can read more about it in the roadmap RFC itself, but here is a quick summary. First, we're going to invest further into the foundation that we built with Octane. We'll keep simplifying things, removing conceptual complexity and introducing new functionality that complements the new programming model. We are also going to invest in developer tools like making TypeScript and IDE work better with Ember in general, but also with the new features in Octane. Second, we're going to invest in modernizing our build system. You might have heard of an effort called Embradia which is going to integrate Ember CLI with popular packages like Webpack and ROWUP. This doesn't mean you have to now change your query into a configuration architect. Rather, these systems will be used under the hood to give you access to modern optimizations like tree shaking and code splitting. On the other hand, it will still allow Ember to provide a zero conflict experience out of the box. So that's pretty nice. Third, we'll invest in Ember, making Ember work better with assistive technologies out of the box. We formed a new accessibility strike team to tackle these issues, and if this is something you're interested in helping, you can find them on Discord. Finally, with Octane Outdoor, this is a great time to share Ember with the outside community. This is something that you can help with by writing blog posts, videos, posting on social media, speaking at virtual conferences, or even just teaching Ember to your friends and colleagues. As I mentioned, one of the priorities on the roadmap is to invest in the Octane program model. And given that, I spent a lot of time in this session to tell you about how great templates are and why you don't need as much JavaScript anymore, the title of Matthew's talk might surprise you. I won't spoil everything for you, but stay tuned for this session later if you want a glimpse of the future. And since we're talking about the roadmap and talks, Edward is the main architect behind the Embroidery Project. He doesn't have a talk at the conference this time, but he spoke about it at Emberfest 2019 with a talk titled, Compiling Ember. It's available on YouTube, and if you want to learn more about Embroidery, this is definitely something you should add to your playlist to check out after the conference. Finally, I would like to talk about how you can get to be part of this effort. We are a community-driven open-source framework and we rely on the community members like you and me to help move us forward. So first, I recommend that you get involved with the community by subscribing to the Ember Times newsletter and joining out this court server if you haven't already done so. There, you can help answer questions, you can bounce ideas, you can ask questions, you can join strike teams, et cetera. Secondly, you can help by giving feedback. What do I mean by that? Well, there are a couple of ways you can do that. Maybe you can configure your CI server to run your tests against the beta and canary channel using Ember Try and report any issues as soon as you see them. The earlier we hear about breakages, the easier it would be for us to track them and fixing them. And of course, you can submit requests as well as writing and reviewing RFCs. Third, you can share common solutions you found with the wider community in the form of add-ons or you can help build better developer experience by contributing to tools like code mods and linters. If you're looking to get started here, check out the adopted Ember add-ons project on GitHub. And speaking of tooling, in case you missed it, both Ember Inspector and Ember Todo has been updated to work with Octane and the latest version of Ember. Those are great projects to contribute as well. Finally, you can help with teaching Ember to more people. As I mentioned before, your blog posts and conference talks are a great place to start, but you can also contribute it to the official guides and documentation that I mentioned earlier. With Octane, we have invested pretty heavily in the area of learning materials, including writing our own state-of-the-art tooling to go with the documentation. We now have, for example, a self-updating tutorial that runs itself against the latest changes every day, which is great for keeping it up-to-date and fresh, but it also serves as a good way for us to detect breakages across the ecosystem. If this is something that you would like to help with, we would love to keep the Octane momentum going, so definitely get in touch with Discord on the Dev Learning channel. And finally, if you want to hear more ideas about contributing, you can look forward to this session tomorrow. And finally, if you haven't seen the Ember documentary yet, I highly recommend watching it. It's really well done and it's available for free on YouTube. There are many highlights, but one of the things that really jumped up to me is this quote from Melanie when interviewed about the core values of Ember. I think this is a great way to sum everything up, so I'm just gonna leave that with you. We are Ember, the Together Framework. Let's get the message out there. Thank you very much.