 Where are we working? There we go. All right, hello everybody. My name is Ethan Arawood. I'm a software engineer at Vercel and today I'll be presenting the Empowering the Future of the Web, Advancing Web Runtime Interoperability with WinterCG. The WinterCG is a new community group, a W3C community group that stands for Web Interoperable Runtimes Community Group. We play on the abbreviation here, but WinterCG was easy enough to come up with as well as easy enough to brand. So we like using this little snowflake as sort of the sort of default logo for the group and you'll see it come up on different, different some of our proposals. Like other community groups or as we've heard from like the Standards Working Group from OpenJS or the W3C, WhatWake, this is a group of companies that are all working together or developers from companies working together to push something forward, to solve some sort of problem. These are all of the existing members of WinterCG, some more active than others, some who just were kind of around for the inception of the group and some who are actively participating in it. And the reason like why did WinterCG get formed? From hobbyists to enterprises, interoperable applications are highly desired but the support is lacking. If any of you have heard of my previous talks about landing fetch in Node.js, you will probably remember the interoperable story. There is this figurative JavaScript developer who learned how to write JavaScript on the web and they learned how to use the fetch API building a front end website and then they came to Node.js and they were like, wait, I have to use the request module but then this thing tells me to use Axios and this thing has a node fetch but it doesn't really work the same way as the fetch in my browser does. And so there's this interoperable story that we're trying to improve over the world of JavaScript. And so the goal of the WinterCG is to promote a comprehensive unified API across all JavaScript environments. Over the past two years, we've seen the rise of many very exciting new runtimes. This includes Deno, Cloudflare's WorkerD, even folks like Vercel and Netlify have started branching into this edge runtime serverless function space. And so Node was the dinosaur but not the Deno of all of them and they've set a lot of really great precedences but as everyone knows, there's no Node.js standard. There's no specification for Node just like there is for ECMAScript. And so that's kind of what the WinterCG wants to start moving towards how can we, in a standards body sort of way, try to create this similarity, this interoperability between all of these new JavaScript environments or runtimes. Before we continue, some of our like non-goals though is we don't want to be creating new APIs, we don't want to be creating competing APIs and we also want to keep our focus from shifting too much. What this kind of means is the WinterCG is not here to be like we're gonna invent the way to make a JavaScript runtime and if you don't like do it this way you're getting left behind. What we do want to do is try to merge some of the gaps or mend some of the gaps between all of them and find some ways that they can be similar and effective together. That way developers when they're coming from one to another or approaching the problem space of which one do I use, you can take away some of the concern of, well, Deno lets you import things this way and Node.js lets you require things that way and so we're not gonna try to influence these frameworks too much in the sense of like you must do things the way we say so but we wanna provide some baseline that they all can be like, well if I write WinterCG Compatible Code I can expect it to work in Node, I can expect it to work in Deno and so on and so forth. The process at which this community group operates starts with collaboration. We've created space for the vendors and implementers to discuss these new or existing web platform APIs and we've provided the organizational structure for members to contribute effectively. I like the wording that me and the WinterCG have come up with here because we don't want to get too bogged down with the processing of running a group like this. We want it to be more fluid and easier for folks to be involved with and that's because if we make it too difficult to collaborate then what's the point of this community group because we're gonna be wasting all of our time trying to just do the first step. So the second part in the process is the proposal step. This is where we will analyze the existing web platform APIs and we will propose improvements to the existing specifications. I like picking on fetch. It's defined by the WhatWig group instead of the W3C or instead of WinterCG and rather than us trying to make a new fetch we have spent a lot of time trying to contribute back to the existing fetch and promoting that all of these other runtimes node, deno, cloud flares, bun, we're like, hey, everyone should use fetch but let's also make sure that we're improving fetch together so that it's effective for all of us, including the web still. And that leads us to implementation. We're also not trying to just be a leech on these existing standards bodies. We're getting involved in a way and we're helping actually improve the specs. We're contributing directly to the fetch standards. We're contributing directly to the web platforms themselves as well. One of the original members is Agalia who is well, well known for actually implementing changes to web platforms. And so we work in this sort of like trifecta magic of, okay, we want to add something to the WhatWig fetch spec. Agalia is prepared to actually implement that change in places like Google Chrome. And now the fetch spec gets updated for the benefit of server runtimes and we've done the work as well. So we're trying to be as good community members as we can through the Winter CG. And this leads us to some deeper dives on the steps of the process. So in the collaboration step, our main channel, which I'll share links to at the end of the presentation, we use a lot of async communication on a tool called Matrix. And this chat channel is open for anyone to join and it's really effective. It has threading capabilities, very similar to tools like Discord or Slack. We hold now monthly meetings. They used to be a little higher frequency but we have tried to decrease the amount of meetings we're having and shifting more towards that optimistic async workflow. And then finally, we are a true W3C community group. So we do have a charter and within that charter, we actually do have a consensus protocol where if a disagreement was to occur and we needed to fall back on some process, that group has that. We have the things in place to keep ourselves effective even in the times of unfortunate conflict. For the proposal step of our process, we have the classic specification process. We follow the W3C templates and standards for creating what are called drafts. And we also will still, I mentioned before, we're not trying to create new APIs but we will utilize the tools like simply forking a repo in order to continue to iterate on our own while simultaneously contributing as much upstream as we can. There are things in Fetch that might never actually land in the WhatWig proposal or in the WhatWig standard but we can try to limit, we don't need to create a new Fetch. We can simply fork it and call it winter CG Fetch and say, okay, if you're gonna try to abide by this standard instead of that one, here are the minor differences. And then finally in this last blow point, the runtime keys, this is a draft that I'm gonna kind of pick on because I wrote it myself. And the idea is it's not a real proposal or standard in the sense of this is not something anyone must implement. It's also not something that a lot of people have had to like process and get lawyers involved with. It all it is is simply a draft. You can or can't listen to it, you can or can't use it and a lot of the members in winter CG are in fact using it. We all agreed upon it when we published it but the thing is it's always gonna be considered a draft unless the winter CG was to sort of level up, so to speak. And with that, it means that some of our work is a little bit less, I used the word earlier, that's like it's less, I'm forgetting it now, it doesn't have as much like onus or as much permanence as like the ECMA standard might. Where something lands in the ECMA standard, you are cementing that into time forever. With the winter CG, we're still operating in a world of like we can get things wrong sort of. We definitely don't want to be breaking the web by saying one thing and then a month later deleting it. But we do have the ability to be like, let's be here to iterate and let's iterate quickly. There's not as much process to get in our way when we're trying to build these things over time. And then finally the implementation step, I mentioned already we're contributing back to existing standards, the Fetch one in particular. Here's an example of Luca from the Deno team contributing a new way to handle set cookie for headers in the Fetch spec. And this landed directly in the what we expect. This never even had to hit our fork of Fetch. And we have another example of this coming up where the other example did kind of start on our end but there are efforts made here by our members in order to again promote that the web first standards versus creating something new. So some notable achievements that I've already mentioned a few times include Fetch, the minimum common API and runtime keys. I'll dive into the runtime keys in a little bit later but the minimum common API is one of the first things that WinterCG ever proposed. And it is essentially a collection of other web platform APIs. Think readable streams, web crypto, Fetch. And we say you as a WinterCG runtime or WinterCG compatible runtime should implement these standards and you should be expected to be compatible with them. We haven't done too much else with it just yet but we do have some exciting plans that I'm gonna get too soon. But first let's dive into another achievement of ours. This is the response.json static method that we added to the Fetch specification. And again this is something that in Luca's original post he described how this is something very valuable for servers but not necessarily browsers. Yet it does fit into the model that the browsers already support for the Fetch API. And so he created an issue and not soon later it landed into the official Fetch spec. And Luca did the work of adding it to the specification. He implemented it in his runtime. It's been implemented in other Fetch implementations. I believe it already is in Indici and if it's not it will be there very soon. And some of the browsers have already started landing this as well. Some other pieces that work in progress for the Fetch spec is the forbidden headers list. This is something that I wanted to highlight in particular because this is where having our fork of Fetch might be really important. Headers on the front end are very important parts of your networking interfaces. Getting them right and controlling what can and can't be managed by the clients themselves is a huge, huge security effort. That will not change. That will not be something that will be easy to modify for these browsers. But yet on the server where you are sometimes the thing creating the responses you do need to modify these headers. And that is where relaxing some of the restrictions that browsers have put in place for their networking interface is useful. Where we can still have an interoperable Fetch API just in one context you are able to modify some of these headers and in others you aren't. And so this is one of those examples of Andrew from Agalia I believe working on trying to propose that modification to our fork of Fetch in order to make the header restrictions a little more relaxed. Some other work in progress things that the WinterCG is working on is changes to the performance API or a standardization of the performance API. Node.js developers may be fairly familiar with this with the performance object that you can do like I think it works with the HR time and it's used for primitive timings of how things are operating. And then the web crypto streams, this one's really cool. It seems to be mainly driven by Cloudflare and Deno but the idea is we have web crypto and we have streaming, what if we merge the two together where you could decrypt and encrypt using the powers of web crypto but in a streaming format. And that way you don't have to encrypt and decrypt the data all at once necessarily. Both of these are still highly in progress and there wasn't much else to share except the little high level things. But one exciting piece that we can actually dive into together is called async context. This is actually being driven to TC39 by members of WinterCG yet another group that we are contributing directly to rather than trying to create our own new things. And the motivation of async context is best described by kind of working through some code. So I wanna direct our attention to either one of the two but I will work on the left one with us. And so you'll see at the top level here there is a function called program. Don't worry what's inside of it just yet. Just realize that it's a synchronous function. There's no async keyword or at least sorry, it's not necessarily a synchronous function but it's not an async function. And then we have the let's shared sort of global variable and then below that there is the implicit async function. At the very bottom of the file we execute program. If we go into now go into program you'll see that we've defined a value object and then there's a try finally block. Within that try block the first line is shared equals value. We are assigning that variable value which is inside of the program closure to the global variable shared. Then we call implicit. Notice how we're not using the await keyword for this async function implicit. Now let's look inside of implicit. Implicit first starts by asserting that the shared.key property is one, two, three. Shared is undefined by default in this function. So if you were to just call implicit on its own that first assertion should fail. But since value is being assigned to shared first then that is called, then the variable is assigned. But then we have the await one. One of the niche parts of how async code works in JavaScript is that the call stack gets cleared every, I think like trip around the queue the microtask queue. And so when we call await one the shared variable loses its assignment from the program function. So now in the next lines you see the assert throws assert equal shared.key that block actually the shared variable loses its assignment and becomes undefined. This is a very simplified example of a much more difficult problem. But the async context will fix this. Async context is proposed as a new API that can be, that can solve this problem where variables lose their value over the course of async execution. On the right side there is this example of a tracer and this fetch request where we want to be able to time how long this fetch request is running. And by using the async context we can set the start time, the trace ID, the span ID, think like basic telemetry tool building. And now your fetch request can get timed and we can keep a hold of all this implicit data without losing it over the execution time. I wish I could spend an hour drilling into the async context problem but this is a really key example of what the WinterCG is trying to do for the web as a whole. This is a problem that exists not just for server runtimes but for all JavaScript environments, your browser included. And so by pushing this change forward in the TC39 and then hopefully landing it in all of the other runtimes we can solve the problem for everybody rather than just one group. And that kind of extends, I don't think I included it here in the slides but Node.js has already partially solved this problem with async local storage. So if you're familiar with the async local storage API there's a lot of similarities between that and async context. And the idea is Deno might have its own solution and Bun might have its own solution but none of them are the same. And this is a problem that we might need to be more consistent across all of these different runtimes and thus the WinterCG effort of async context was created. So diving into another work in progress this is something that I'm driving called the WinterCG common key. I mentioned the runtime keys proposal earlier and what that looks like at a top level is if you're familiar with using package JSON to define different exports or engines for your project usually you'll call it like Node or the require export or the like ESM or CJS export. And the idea is what happens if you're building a project that runs in Node and Deno? How do you tell these different packages which to use? Interestingly enough a lot of existing runtimes will look at things like oh if I'm Deno I think optimistically the ESM exports are the ones that I want. So they'll reach for that as their priority. But then Node.js actually already does specify in their document that you can use the Node key to specify the Node.js export. And that is considered within the stack of priority for what file will be executed. As we evolve into this world where there's multiple runtimes and people are building libraries or packages that need to be able to run everywhere it was thought though why don't we create a list of keys that developers can use to signal what runtime should be associated with what thing? We're very loose on the terminology here because the idea is this is just a registry of keys. The spec is very simplistic. It is just a list. And the list explains okay here's the key, here's the runtime it's associated with, here's the documentation for the runtime and here may be like the marketing branding tagline for it and that's it. The specification does not state that you must use these keys in your package JSON file. We provide this example as a way to say here is how you may use it. Here is how if you're the author of the next new web bundler, you may want to read and process these keys. But the specification does not state how they're meant to be used just that they exist and how they could be used. And so now what do we do for interoperable libraries and applications? If there are 17 different runtimes and I need to then specify 17 different exports, what is my minimum common denominator? And that is where we were gonna combine the minimum common API, which is what the WinterCG treats as it's like this is your WinterCG compatible runtime specification and the runtime keys proposal. We'll create the WinterCG common key. We'll work on some kind of versioning system either Semver or an annual versioning system. You can think of this like the ECMA script. You have ECMA 2023 and then 2024 or I think it's ES 2023 or ES 2024. And we can do an annual release cycle where next keyword could always point to the following year if people want to be bleeding edge. Or we can do some kind of Semver versioning where we use major and minor impatches to relate to major and minor breaking changes. And then finally, we can add a level of conformance testing to this versioning system. We could leverage the existing web platform tests and build a similar tool to can I use, which is what the browsers use to say, oh, is this feature available in Firefox and Chrome and Internet Explorer and Safari? We can do the same thing, but for all the web runtimes. Is this feature conformant in node and Deno and bun and et cetera. And then better yet, if you are winter CG, you have access, you know, winter CG will have the green light for half the properties. And then maybe the ones that differentiate will be the other ones where all the different platforms might differentiate. And then finally, you can use this key inside of your project configuration files just like the other runtime keys to say, here's my default export for anything that is compatible with their CG. I don't care if you're using node or bun, you can run it here. And better yet, here's the engine specification as well, which is a commonly used field in the package JSON to specify what major version of node JS your project supports. In this case, I'm using the annual versioning example where you could say greater than or equal to 2023. So my package will run in any system, any runtime that is compliant with winter CG version 2023 or above. So get involved. If anything you saw here today sparked an interest in you, you don't have to be a company to join us. Please jump on into our, go to the website, we have all the links there. The WC three community org is available for anyone to join company or otherwise. And our GitHub is where we do a lot of our work. I've said this to some folks who have asked really the best way to get involved with the winter CG is to kind of throw yourself in. We are a very, I think we use the word scrappy kind of a community group where if you're willing to do the work, do it. We don't have, there's purposefully not a lot of barriers in the way for you to do something. For example, just yesterday at the collaborator summit, we talked about maybe the idea of standardizing package JSON. We're not sure we want to do that yet, but we were pretty confident that winter CG is a pretty good place to start that conversation. So in a couple of minutes, I created a package JSON specification repo. I started the thread in the matrix channel and people are already going back and forth on an issue who weren't even at the conference getting involved. And this is the element of, there's something that you think fits into this picture. Just jump in. We are a bit more than willing to enable that, help you create those repos, create those issue threads and get started creating the future of the web. So thank you. Again, my name is Ethan Erwood. You can follow me on GitHub or Twitter, and you can reach out to me on either one of these email addresses. Thank you so much. Say, if there's any questions anyone has, we can ask them now or we can ask them privately. So thank you. So I think, yeah, so we haven't talked directly about like what is coming next for winter CG in the sense of what would it take to be more than that at the moment? I think we've effectively been contributing upstream. Fetch is the biggest example of like most of our work there has landed in the existing fetch spec. So there's not really a need for us at the moment to be more than we already are since our major goal for a lot of these specifications is to find a other home for them. Find something that already does exist to land it in. And like trick, what's the trick is for runtime keys for the minimum common API, potentially for the package JSON work, there really might not be something else. And those might just exist as drafts until we get to that point of now it's time for the winter CG to evolve into something else. I will think that we will lose some of our current autonomy if we do kind of go to that next step, which has its own pros and cons. I think it's a bit premature to have done the package JSON specification given that no package manager is a part of the winter CG group. And I think that maybe you should start with bringing those folks to that table first. And they might, I see a lot of commonalities with like work and cloud spaces that are happening in OpenJS that are happening in winter CG. And I just wanna make sure that you're getting the right people in that form. And it's great to like put energy towards standardization and it's just like, I know there's different people in winter CG that might not be here in cloud spaces and vice versa. And it'd be great to see more of the folks that are probably doing some of that work that have the energy from winter CG come to these spaces like yourself. But yeah, just wanna highlight that some of the initiatives that I'm sure around standardization and runtime interop feels like maybe some folks' hands were forced into winter CG. Yeah. There's not what I know about back channel conversations that were had, but yeah. Definitely. There's a level of idealistically, the winter CG, because of its scrappiness is there seems to at least have been more momentum building opportunity there than there has in other spaces. And I think it's the natural like, if we're always hitting a wall here or in the sense of like, why hasn't things happened one place? Well, maybe if we try from the other angle and then we bring everyone along with us, like you're saying, why don't we get more people, the right people into these conversations? That's how we make these big improvements to the whole web. In particular, I will be joining the, I mean, I only found out about the OpenJS standards working group being here this week. It's existed for a while. Maybe I've seen it come up. Maybe it's my own fault for not digging into what it is, but there's that balance of like, we're crossing these streams as much as we can to be like, oh, let's go get involved there and see what partnership needs to be created. I know one of the creators of winter CG spoke at the standards group, but similarly didn't do a good enough job of bringing it back to the winter CG that they went and did that talk. And so now we're like, oh, there is a communication channel there. Let's use that. Similarly with TC39, there are delegates on the TC39 who participate in winter CG. So now it's like, awesome, how can we use that to land a same context? And et cetera, et cetera, for what way groups, for W3C groups, how can we leverage as much as possible to improve the web? That's a great, great comment. Awesome. Any other questions? Wonderful. Well, thanks again, everybody.