 I'm beyond excited that we have Robin joining us at the foundation as our executive director. I'll gush to all of you about it separately. I won't use my stage time too much on it. But one more quick round of applause. In the back of the room you can see a bunch of people who are heads down on computers and there's a whole bunch of people back there you also can't see. But just a quick round of applause for all the people making this happen who you don't actually get to see. So we're gonna talk today about Universal JavaScript and a vision I personally have. And we'll just start with saying hello. Bonjour. This is a cat. I really like this. That's all. My name is Myles and I'm a developer advocate at Google focused on the Node.js ecosystem and Google Cloud platform. You know I always put this at the bottom of this slide just saying hey this is my own opinions so you know take it or leave it. But I'll take it a step further this time and say you know the opinions expressed in this talk may even be wrong. I don't know. But what I can promise you is the opinions in this talk are definitely opinions and that's about the level of commitment I'm willing to make on them. But see maybe asking the question of like what even is Universal JavaScript. It's a pretty broad term and so I cheated and I wrote a tweet and asked other people to answer it for me. And we got a wide variety of responses. This was what many of you may be thinking right now because without any context I'd say it's meaningless. Universal means different things to different people. You can get an idea of the positive response I'm getting here. Someone playing buzzword bingo. So that's always fun. 1998 called and wants its optimism back. And this actually came in two separate forms from two separate people. I think this is you could say the same thing in a different way. It was such a hype idea a decade ago too. I even got quotes tweeted by horse.js which made my whole week. I love it when that happens. But some people in my personal opinion just got it. They have that same vision. Code just works in the browser in Node and I don't have to think very hard. No build step necessary across both the web and Node. Not having to transpile code to multiple targets. Right once. Run everywhere. This is great. I'm hiring this person to do marketing for me. This is very succinct. Very to the point. And you may be asking yourself is this different than isomorphic JavaScript? And the answer is clearly yes. And this isn't a talk about isomorphic JavaScript. So I'm not going to get too much into it. But isomorphic JavaScript is a term that actually was created in 2011. So when people were saying oh you have the optimism of a decade ago, they're not exaggerating. And this blog post written by Charlie Robbins who is a board member of the OpenJS Foundation potentially somewhere in this room coined the term isomorphic JavaScript. And you can find this from the way back machine. If you're reading the small text which you probably can't, you'll notice that it does talk about the idea of running JavaScript both on the client and the server. But one of the things that was fundamentally different about the concept of isomorphic JavaScript, it was heavily, heavily tied to the concept of the view and model view controller and which patterns of designing single page applications could be run on the server for server side rendering. You know, nine years ago it was just as hard as today, maybe a little harder to serve a site that was primarily JavaScript and actually have any sort of machine like know what it's doing without running the code. And it also creates like a really slow time to first paint. And this talk is not about any of those things. And I would argue that universal JavaScript is, while it's similar to isomorphic JavaScript, is a fundamentally different thing. And we'll dig into that a bit. But universal JavaScript and its new tagline once run anywhere. And I bet all of you are now thinking universal JavaScript is great and you want me to actually tell you about it. So I'm going to. The first thing that's important about the concept of universal JavaScript and running everywhere is thinking about all the places you may want to actually run your code. So obviously we've got browsers and node. We've already mentioned that. But there's a lot of other places where you might be running JavaScript as well. Deno is a fantastic new platform that Ryan Dahl, the creator of node, has come up with, has some different concepts and different thoughts about how JavaScript would work, different APIs. We have Edge Workers, a great product from Cloudflare that is running JavaScript on the edge of a CDN. Its API is designed heavily after the service worker API. It has fetch. But it's kind of its own subset. It's its own runtime. It has its own opinions about how to run, execute, and debug JavaScript. Modable is a really cool one for embedded systems. It's a version of JavaScript that you can run on tiny chips and put anywhere. Modable implements their own APIs. They also implement the entire language itself. As far as I know, Modable actually already implements top-level await and is one of the most spec-compliant JavaScript engines out there. It's actually probably a good time to stop for a second and say that all of the ones above, aside from browsers, a lot of those are using v8, the JavaScript engine from Chrome. Modable is not. It's using its own JavaScript engine that they manage themselves. And we'll see, we see a lot of other places where JavaScript is showing up as well. Embedded inside of databases. You can also see it inside of productivity software. All sorts of ways of scripting things and automating things in ways you wouldn't have imagined. And JavaScript is showing up all over the place. And to me, this is one of the reasons why Universal JavaScript is so important. When we're writing our libraries or we're writing our productivity tools or we're moving between these different environments, we don't necessarily know where the code we're writing is going to end up. We don't even know who's going to use it. So kind of starting from this principle of a baseline that can be shared everywhere, make sure that your code's extensible. Make sure it can be shared in different places. All of these environments share parts. They're not these fundamentally different things. We have standards. We align along a baseline. And the core of all of that is ECMA 262, which is specified by TC39, the standards organization that specifies the JavaScript language. And within ECMA 262, if you look into the spec, there's a couple concepts that I won't get too much into right now of realms, intrinsics, and primordials. And this is like the soup that makes up the core of JavaScript. Realms are the context where your code runs. I'm glossing over it, but find me later for more details. Intrinsics are all the different built-ins that are available on the global object that you can change and you can use. And primordials are the ones that are necessary to even bootstrap the environment. So some examples of primordials would be like array and number and object and function. Without these instantiated in the environment, you can't even make the higher-level things like some of the namespace objects such as JSON and math and reflect. These APIs are all available in every single JavaScript runtime. These are all standardized by ECMA 262, but they serve slightly different purposes. Something like JSON or math or date are almost more like libraries within JavaScript, whereas things like object are core capabilities. One of the cool things about these, these are all intrinsics, Node has done some work recently in freezing all of these objects because you don't want some random module changing the way that Node does things internally. This is an example of a way that a platform can do small changes to the way it works above the baseline runtime without really causing major differences for people. But one of the things that TC39 specified, you know, in the recent future of five years ago was ES modules. And prior to ES modules, there was no common way to share code between all of these different environments. If you wanted to take one piece of code and link it to another piece of code, you were either literally concatenating the files together or running a tool such as Babel or rollup or webpack to pack everything together so you could run it. Node was one of the few environments that had a built-in module system, which was CommonJS, which is what a lot of other runtimes copied, but it was not standardized. And it wasn't, CommonJS itself wasn't built in a way that browsers could use as well. ES modules made some compromises, didn't make everyone happy, but was something that all of these different environments can share. And I would like to push it a step further and say that modules have been the missing piece to really enable universal JavaScript. Without modules as kind of this shared way of sharing code, we were destined to have to transpile. We had to do some sort of function on the code in order to use it in different places. But that's where things get kind of weird, because even though ES modules are specified in ECMA, the loader itself is not. The loader is implemented by the embedder. So in Node.js, we implement the loader. And the Chromium browser Blink implements the loader. And TC39 also leaves it up to the hosting environment to determine resolution. How do we take that string that you give that says, hey, I want this thing and find it? It's up to the runtime to turn a reference into a location, to fetch your resource from that location, to do this recursively and build a graph, and give the engine the entire graph to execute. This core piece of shared infrastructure, which is standardized, has this single place where every single runtime can make their own decisions and deviate. This single place where you're actually saying, hey, here's the code I'm sharing. This is one of the reasons that in the ESM implementation of Node, we're pushing towards removing some of the magic from CommonJS that won't be capable in the browsers. This is a potential place of platform divergence. And platform divergence is something that gives me existential dread. And a known side effect about existential dread is that it causes nihilistic transpilation. This is a term I coined myself recently. Nihilistic transpilation is when you have so given up on the concept of universal JavaScript, where you've so bought into the fact that we're always going to need to build, we're always going to need to transpile, that universal JavaScript doesn't even matter anymore. It's not a priority. It's not a thing that needs to be thought about. It's just not possible. We may as well just accept our transpilation gods and move forward. And it's built on this idea, my personal opinion, that JavaScript platforms are potentially fundamentally different. I would say that they're not fundamentally different, but they can have drastically different APIs, which is fine. Different platforms have different needs. That doesn't mean that the core language needs to be different. And people may ask that question, is the browser fundamentally different from Node.js? And yes, its APIs are going to be fundamentally different, but they do come from the same soup. They have the same primordials. They have the same base language. They have the ability to have this shared core. In fact, Node.js has adapted many of the APIs designed originally for browsers. So if you look at a standards organization like What Working Group, you may think to yourself, aren't What Working Group standards browser-specific? So they standardize HTML and they standardize DOM. And those aren't things that Node does, although with server-side rendering, maybe it does. I guess Node is a platform dozen. But we do have What Working Group standards APIs in both run-times. And I have an asterisk there because they differ a little bit, but we're trying. But something like console or URL or the encoder API, these are all things that are standardized at What Working Group that we have in Node. I think you'd be very hard pressed to find a JavaScript run-time that's easy to use that doesn't have console in it. That's how I debug. If you don't have console, you're kind of like, how do you even get started? And there's even other standards that aren't yet in Node.js that we're exploring. I know people say, stop trying to make fetch happen. I'm not going to stop trying to make fetch happen. I want fetch to happen. But this is a really great example of one of those APIs that, like, on the surface from an API perspective, most developers are like, that's great. I give a string to a function and it gives me a promise, and then that promise is going to give me the thing that I asked for. But under the hood, there's so many subtle differences between Node and the browser. The browser only really ever has one tenant. You're not worried about multiple people making requests. In Node, the same process may have requests from 10, 20, 100 different people. You can't share the state of the fetch object in the same way. It can create security concerns. But should those plumbing problems be something that means we don't have shared API surface? What working group streams is another great example here. Mateo Kalina, who I believe is in the audience somewhere, has been exploring getting what working group streams support in Node. Whether or not we get stream support in Node, I think that there is definitely a possibility of finding ways to have a communication layer between the two so that Node streams and what working group streams can talk. But these kinds of fundamental differences in the platform make it hard to see that future of universal JavaScript and makes it easy to fall into that pit of nihilistic transpilation. And I mentioned the interface versus plumbing. And I think that this is so important. As platform developers, as library developers and framework developers, when you are designing APIs, the plumbing matters and the plumbing is all you're working on and it's really easy to lose track of everything else. But to many people who are consuming what you're using, what they care about is the interface. How am I calling into that thing? Does it work the way that I'm expecting it to work? And I think for a world of universal JavaScript, we need to be thinking more about the interface than the plumbing. Platforms can worry about the plumbing as long as the behavior is similar enough. If developers have shared interfaces, we can get a lot done. And that starts to ask this question of where does the platform begin? We have those intrinsics and primordials at what point does it become the platform? Is console part of the platform? Is it part of the runtime? Where does the platform end? When does it start becoming the part that is frameworks? These are a lot of words and maybe it's a little too broad. But I think it's really important to think about these things. We're all using these tools. What part is the language? What part is the platform? What part of the frameworks? Why do I care about these things? And where is the code that I'm writing fitting into this picture? And I want to suppose that perhaps universal JavaScript is a platform concern. And a great example here is JSON modules. How many people here have ever required JSON before? In Node, you can just require JSON and it gives you an object and it's a really great experience. In the browser, if you want to get JSON right now, you have to fetch it, which all of a sudden introduces a promise and it complicates things. So inspired by Node.js, JSON modules were actually specified in the HTML spec by what working group. But it was rejected at TPAC for security concerns, TPAC being the conference of W3C. As a response to this, there's a proposal at TC39 working on module attributes to try to handle the security concerns that were raised by the W3C. The reason that I bring this all up is that universal needs to be a platform ethos. The idea that we could have JSON modules and have a shared interface for JSON modules across every single runtime requires all of these different partners in the web ecosystem to work together for, you know, shared good. And there are a lot of these standards happening at TC39. We're exploring built-in modules and standard libraries and module attributes. These are all things that will bring us closer to a future of universal JavaScript. At what working group, they're exploring JSON modules. At the W3C, they're exploring import maps, which will allow bear imports in the browser. And WASI, which would be a shared system interface that can be used across many runtimes with WebAssembly. But with all this work happening in different places, how do we find a shared vision? And this isn't a question that I have an answer to today. This is a question that I think we as a group need to be thinking about. Where do we collaborate when we have all of these disparate stakeholders? Where do we all come to collaborate together? In that question that we started with, our various JavaScript platforms fundamentally different, I would say that developers shouldn't have to know about that beyond an API. Developer skills should be portable. And to me, that's one of the most powerful things about the concept of universal. And I think it's one of the reasons why a platform like Node was so successful. Portable skills. And I would even go as far as to say universal needs to be a platform concern and not a development target. This needs to be something that fundamentally we are all working towards. Universal, it's a goal, not a technique. And I'll end on a pretty bold note that I think the future of JavaScript needs to be universal if JavaScript is to have a future. Thank you. I'm Miles and this is a Surfing Dog.