skip to content
Video cover art for Marko Run with Ryan Turnquist
Video

Marko Run with Ryan Turnquist

Ryan Turnquist introduces Marko Run, the new meta framework for Marko.js, covering its routing, middleware, and deployment capabilities.

Open .md

Episode Description

Ryan Turnquist introduces Marko Run, the new meta framework for Marko.js, covering its routing, middleware, and deployment capabilities.

Episode Summary

In this episode of JavaScript Jam, Anthony Campolo and Scott Steinlage interview Ryan Turnquist, a core member of both the Marko and Solid teams working at eBay. The conversation begins with Marko's origins as a performance-focused, multi-page architecture framework built around 2012 to meet eBay's e-commerce needs, particularly fast initial page loads and strong SEO. Anthony draws comparisons between Marko and React, noting that both emerged around the same time but took very different paths, with React dominating while Marko quietly pioneered concepts like resumability that frameworks such as Qwik are now rediscovering. The discussion then shifts to Marko Run, the new meta framework Ryan has been building to make Marko more accessible outside of eBay. Ryan walks through its file-based routing, layouts, handlers, and middleware system, demonstrating each feature through a live coding session. The team also touches on the upcoming Marko 6 Tags API, which replaces the class-based component model with composable, fine-grained primitives. The episode wraps with a deployment demo to Edgio and a call for community contributions, particularly around documentation and building new deployment adapters.

Chapters

00:00:00 - Introduction and Marko's History

Anthony introduces the show and guest Ryan Turnquist, who works on the Marko core team at eBay and also contributes to Solid.js. Ryan explains how his involvement with Solid led directly to his role on Marko, and the hosts discuss how Solid serves as a talent pipeline for other open source projects in the ecosystem.

The conversation moves into Marko's background as a JavaScript framework dating back to 2012, built specifically to meet eBay's performance requirements for e-commerce. Anthony and Scott break down the difference between single-page and multi-page architectures, explaining why eBay chose a multi-page approach to optimize for first page load speed and SEO rather than the SPA model that React popularized.

00:05:53 - Marko vs React and Parallel Discovery

Anthony highlights the remarkable timing of Marko and React both emerging around 2012, with React quickly becoming dominant while Marko remained relatively unknown outside eBay. The discussion explores how many of the solutions now being retrofitted into React, such as partial hydration and streaming, were concepts Marko addressed from the start.

Ryan notes that Marko had a form of resumability as early as Marko 3, predating Qwik's popularization of the term. Anthony introduces the concept of "parallel discovery," where independent teams arrive at the same innovation without influencing each other, drawing a comparison between Misko Hevery's work on Qwik (inspired by Wiz) and Marko's earlier implementation.

00:08:40 - Introducing Marko Run

Ryan explains that Marko Run is the new meta framework he has been building over recent months to simplify getting started with Marko. Its dual goals are making Marko approachable for external developers and being usable internally at eBay, ensuring it receives ongoing development resources.

The hosts discuss what a meta framework typically provides. Ryan explains that Marko already includes most necessary features, so Marko Run primarily adds file-system-based routing, project structure conventions, and improved developer experience. The team then transitions into a live coding walkthrough, starting with the project template and its file structure.

00:13:13 - Project Structure and Components

The live demo begins with the starter template's homepage and project structure. Ryan explains conventions like underscore-prefixed folders for pathless directories and walks through the mouse mask component, which uses Marko's class-based API with an onCreate lifecycle method and mouse move event handler to create an interactive visual effect using CSS variables.

Anthony and Ryan discuss Marko's automatic tag discovery system, where components are found by convention without explicit imports. They touch on the implications of file naming conventions for framework-level component resolution and the kinds of edge cases that can arise, particularly across different operating systems.

00:18:20 - Layouts, Pages, and Routing

Ryan explains Marko Run's layout system, which takes inspiration from SvelteKit's naming conventions using plus-prefixed files like +page.marko and +layout.marko. Layouts nest from the outside in, with the page component serving as the innermost UI element, and the render body mechanism acts as Marko's equivalent of React's props.children.

The team demonstrates creating a new about page by adding a folder with the appropriate files, showing how file-system routing works in practice. They also cover the metadata system using +meta.json files for static page information like titles, and add navigation links between pages through the layout component.

00:22:28 - Handlers, Middleware, and Request Flow

Ryan demonstrates Marko Run's handler system, which supports exporting HTTP verb functions for both API routes and pre-page server-side logic. The handler's next function controls whether the page renders or an alternative response is returned, giving developers flexibility in how requests are processed.

The middleware system is explained as analogous to layouts but for server-side logic, running from root to deepest matching route before handlers execute. Ryan walks through a detailed diagram showing the full request lifecycle, and the demo logs timing information to illustrate how middleware wraps around handlers, allowing code to execute both before and after the response is generated.

00:31:39 - Tags API and Marko 6 Preview

The conversation shifts to the Tags API, the new component authoring model coming in Marko 6 that replaces the class-based approach used in Marko 5. Ryan demonstrates a counter component using the let tag for mutable state and explains the composable nature of tags, where developers can build custom tags from fundamental primitives like let and const.

Anthony notes that documentation for the Tags API is still limited, with Ryan Carniato's blog posts serving as the most accessible resource currently. The hosts encourage the team to formalize these docs, and Ryan acknowledges that documentation is a priority on their roadmap as the API moves from preview toward release.

00:35:25 - Adapters and Deployment

Ryan explains Marko Run's adapter system, which currently includes Node, Netlify, and static adapters. The Node adapter serves as the default, converting between Node's HTTP primitives and web-standard request/response types, and adapters can hook into the build process and provide custom server entry points for full control.

Anthony demonstrates deploying the project to Edgio using a custom adapter configuration, showing the production build output that includes a route table with client-side JavaScript bundle sizes. The team briefly discusses the ongoing debate about zero-JavaScript as a baseline goal, and the deployed site is shown live with all routes functioning correctly.

00:41:51 - Community Resources and Contributing

The hosts explore Marko's online resources including the component playground at markojs.com, the Discord community, and relevant Twitter discussions. Anthony draws a colorful analogy comparing Marko to Nikola Tesla, a pioneer whose contributions were overshadowed by more prominent contemporaries in the frontend world.

Ryan encourages listeners to try Marko Run and suggests that building new deployment adapters would be a valuable and feasible contribution for newcomers. Anthony adds that documentation and tutorials are also high-impact areas, mentioning his own in-progress tutorial. The episode closes with the team expressing excitement about Marko's future and its growing accessibility through Marko Run.

Transcript

00:00:04 - Anthony Campolo

All right. Hello, everyone. Welcome to the JavaScript Jam podcast. Here's my co host, Scott, and we are interviewing Ryan today. Ryan Turnquist, right?

00:00:16 - Ryan Turnquist

Yep.

00:00:18 - Anthony Campolo

Awesome. Why don't you go ahead and introduce yourself for our audience, let them know who you are and what you do.

00:00:24 - Ryan Turnquist

Yeah, like Anthony said, my name is Ryan Turnquist. I'm a core member of the Marko team working for eBay. Yeah, I guess that's what I primarily do. I'm also a member of the Solid core team working on SolidJS.

00:00:46 - Anthony Campolo

That's awesome. Yeah. So were you already involved in Solid before you got involved in Marko? Is there any kind of connection there?

00:00:52 - Ryan Turnquist

Yeah, no, totally. The Solid stuff led directly to me getting involved with Marko and ultimately getting hired by eBay. That's funny you say that because Ryan was working at eBay on Marko, and then he left to go to Netlify and then.

00:01:09 - Anthony Campolo

Yeah. And Ryan being the creator of Solid, for anyone who doesn't know. So that's why there's a tight connection there between. Between the two projects and teams. And I've noticed that with Solid and Astro as well, Solid seems to be a really good, like, feeding ground to all these other projects because it's just a great community and they do great work and people seem to get experience there.

00:01:29 - Ryan Turnquist

Yeah, Yeah. I mean, yeah, Ryan Carniato is like, super great at, you know, getting, like, including people in the open source conversation.

00:01:38 - Anthony Campolo

So, yeah, if I could imagine any of the mentors I would most like to be like, I'd want to take half a Bdougie and half of Ryan Carniato and just combine them.

00:01:46 - Ryan Turnquist

That's.

00:01:47 - Anthony Campolo

That's who I'd want to be. Great. So why don't we talk a little bit about what Marko is and how it fits into the whole eBay mission? I think it's a technically very interesting project. It's not very well known. It's kind of become more well known recently, but it's very old, actually. So I don't know if you're a super expert on the history of Marko. Maybe just talk a little bit about where it came from as well.

00:02:12 - Ryan Turnquist

Yeah, yeah. I'm not a great historian of Marko or anything, but it's been around since, like, 2012. It's a JavaScript framework for building web apps and web pages. Marko is interesting. It's a little bit different since it's a multi-page-architecture-first framework, and it was basically designed to fit eBay's e-commerce needs, where the primary thing was initial page performance. So getting you from a Google search results page to a product page quickly, to prevent people from bouncing or whatever.

00:03:05 - Anthony Campolo

Please hone in on that actually, real quick. I think this is an important thing to really emphasize: the single-page versus multi-page split, and let's define those terms. And Scott, this is going to be very relevant to the thing we're building with the new JavaScript Jam website. We're using Astro and we're building it in more of a multi-page architecture. So when you hear the term multi-page architecture, you shouldn't actually be too confused. It's just like a regular website, right? So have you heard the term single-page application before, Scott?

00:03:38 - Scott Steinlage

Absolutely, yeah. SPA. Yeah. So basically, if you go in there and it doesn't reload as you're changing through things, it's basically a SPA. If it's reloading, you probably have multi-page.

00:03:49 - Anthony Campolo

But yeah, totally. There are issues with SPAs, which is kind of the reason why we're now seeing this return to the multi-page application. Even though you get nice navigation and quick page changes and a more app-like feel from a single-page app, there are performance costs, SEO costs, and technical debt costs because of how complicated these JavaScript frameworks are. And the thing with eBay, to wrap back into the history, is that they wanted to optimize for first page load and SEO, and basically have a single link that can take you to a product page and have it load instantly and be as performant as possible. So that's why Marko was always a multi-page application. Is that kind of right, Ryan?

00:04:41 - Ryan Turnquist

Yeah, that's totally right. I mean, it all came out of, originally, I think eBay was written in Perl, and then they moved to C. Obviously for the back end, they moved to C and then Java, and then eventually they had this whole initiative of letting developers choose their stack. So there was obviously a lot of interest in Node.

00:05:07 - Anthony Campolo

I'm sure it went perfectly fine and nothing went wrong.

00:05:10 - Ryan Turnquist

Yeah, it was kind of like, hey, choose your stack, but you have to prove it's going to be viable. So there were all these performance metrics where you had to be as fast as the thing you're replacing, or better. And then, obviously, add developer experience and stuff like that. So that's kind of where Marko came out of. Yeah, and I think React was probably around at that time, and it just wasn't really going to work for meeting those performance goals.

00:05:53 - Anthony Campolo

Yeah, the fact that they both came out around the same time is really interesting. So Marko and React are both close to, like, 10 years old. And basically React instantly became a big thing, became very popular, and now it's just the dominant web framework. And it's taken 10 years for people to realize the issues with it and arrive back at things Marko did in the first place. Because now all the problems people find with React are things that need to be kind of hacked into React now, like partial hydration and streaming. And we also have things like Qwik that are doing resumability. But I've been having this conversation on Twitter recently that resumability, a term that was kind of invented by Qwik, is actually implementing an architecture that Marko was already able to do.

00:06:40 - Ryan Turnquist

Yeah, I think. Yeah. I was talking with Michael, who's one of the other core members on the, on the Marko team, and he was like, yeah, I think we had resumability in like Marko 3. Obviously it wasn't kind of like as like developer friendly or good as what we're going for in Marko 6 and what Qwik has. But yeah, it's kind of like pretty interesting that we're like rediscovering these things that we, you know, we had 10 years ago or whatever.

00:07:10 - Anthony Campolo

Yeah, I'm a huge history nerd when it comes to stuff like this. And some people will be like, oh yeah, Marko did it first, but no one really uses Marko, so why should I care? And it's like, well, one, it helps you better understand why these things are the way they are and how we got to where we are. But also, studying history can give you tips about the future. Like if you were somewhere in the middle of this journey, around 2020, and you discovered Marko, you would have seen where things were going to go in 2022 by looking into the past. It's so valuable to learn these things because you can start to see longer-term patterns and how different things are influencing each other and where ideas are coming from first. And with Qwik and Marko, there's a term called parallel discovery that I think is really interesting, where individual groups or people get some innovation or discovery within a field, and they both arrive at the same thing without being influenced by each other, in complete isolation.

00:08:13 - Anthony Campolo

As far as I know, Misko was influenced by something called Wiz, and that's kind of where he got the idea for resumability from. And obviously Marko couldn't have gotten it from Qwik because Qwik didn't exist at the time. So yeah, it's just super interesting stuff. But I want to get into Marko Run because that's what you've been working on, and this is something that's really going to make Marko more usable for people outside of eBay. That's at least how I see the point of it, and to make kind of like a Marko meta-framework, right?

00:08:40 - Ryan Turnquist

Yeah, yeah. So yeah, Marko Run is what I've been working on the last few months. And yeah, like you said, it's basically our meta framework for Marko and you're spot on. The whole goal of it was to try to make, you know, getting started with Marko like as simple as possible. And then there was a. There's basically another goal which was we want to actually be able to use Marko Run within eBay for eBay apps. That way it actually gets, you know, it gets the development resources and all that that comes with like actually using it ourselves.

00:09:19 - Anthony Campolo

So when you think of a meta framework, where are the features that kind of come along with that?

00:09:24 - Ryan Turnquist

Yeah, so I mean the big ones obviously like routing, providing like a solution for routing. And really Marko actually has most of the other features kind of like already built into it. So like, Marko Run actually doesn't really provide all that much. It's mostly just providing a sort of like opinion on how to do routing. And so we're using file system routing and opinions on how to sort of structure things and just tying it all together, making the developer experience as good as we can.

00:10:04 - Anthony Campolo

Awesome. Yeah, I think we're probably good then to start getting into the code. Unless you had any questions, Scott?

00:10:11 - Scott Steinlage

No, I'm ready.

00:10:11 - Ryan Turnquist

Let's do it.

00:10:14 - Anthony Campolo

Sweet. So I'm going to go ahead and share My screen. Okay. And you're able to add that to the stream, right, Scott?

00:10:29 - Scott Steinlage

Yeah, we're in.

00:10:30 - Anthony Campolo

All right, cool, cool. Okay, so I've got a little gist set up here, which is some steps what we're going to do. I'm going to be using your kind of a. Net BASIC template for Marko Run. And let's first, let's just show what Marko Run is. If we go here, this is the repo. I like this little logo. You've got get your app up and running with Marko.

00:11:02 - Ryan Turnquist

Pretty clever.

00:11:04 - Anthony Campolo

We got some of the things that we've talked about here, things like the routing. You have layouts, middleware. We're going to show all of these things in the example. And it's blazingly fast, so you know it's safe to use. If it wasn't blazingly fast and you couldn't use it.

00:11:19 - Ryan Turnquist

Yeah, you have to have that requirement.

00:11:23 - Anthony Campolo

Yeah. And then this is a pretty long readme. This actually includes kind of all the docs of what's going on here. I would recommend getting that into the actual Marko site proper sooner rather than later. But we'll go ahead and just get into our tutorial here and I will

00:11:44 - Ryan Turnquist

say that we do have a TypeScript starter now that Marko has TypeScript support. So if you want.

00:11:50 - Anthony Campolo

I'm purposely avoiding TypeScript in this demo for my own sanity and because just a lot of things already were complicated and breaking. So when I'm in that situation, removing TypeScript usually simplifies it. I know people might disagree, agree with that, but I'm talking about like build complexity specifically. So that's pretty, I think, undeniable in that sense. But are those, are those issues you're

00:12:13 - Ryan Turnquist

seeing with like, with Marko Run or.

00:12:16 - Anthony Campolo

No, no, just how it all interfaces together once you add in deployment steps, different versions of Node, ESM versus CJS. It adds so much complexity that requires being figured out before you can even get any benefits from types. Most people who work on projects that don't require going through all those steps don't realize this, but yeah, it's a whole thing. It's got nothing to do with Marko Run.

00:12:42 - Ryan Turnquist

Okay. Yeah, it might, it just might be interesting to show like Marko Run does some like, code some like types generation that will like type your routable file. So it might be interesting to like show that off at some point.

00:12:54 - Anthony Campolo

Okay, cool, cool.

00:12:55 - Ryan Turnquist

But yeah, we can, we can just go with the JavaScript for now and

00:13:00 - Anthony Campolo

Marko, because Marko was actually created before TypeScript even existed, you had to go through a lot of work to, to get it there. So I sympathize with you wanting to show it off because I know you put a lot of work into it.

00:13:11 - Ryan Turnquist

I didn't, Dylan did.

00:13:13 - Anthony Campolo

Yeah, sorry Dylan. Here's our homepage. And start. This is cool. We got a little mouse move effect here that's really nice. And our project structure we've got as you said, file based routing. So what's with the underscore index?

00:13:32 - Ryan Turnquist

Yeah, so underscore is basically a folder starting with an underscore is not included in the route. So it's like a pathless directory. So yeah, so we just. There's like a history in Marko where you like put all, you might put all your files into a single folder so you might have your Marko file and you know like tests and styles and all that kind of stuff. So yeah, we just by default we stuck that in the underscore index. It was that or just underscore or you know just stick it all in the root or in the root of the routes folder.

00:14:17 - Anthony Campolo

Alrighty, so what is doing this kind of effect? Here is our mouse mask component and this is where we get into the more component stuff. And this is class based right now. Later in the demo we'll show some of the tags API. But if you want to explain what's going on in this file right now.

00:14:39 - Ryan Turnquist

Yeah, so basically Marko files are sort of a single-file-component type thing. At the top, we have our markup, and you'll see there's this for, which is kind of a funny way of doing this. But yeah, we have this for tag here that's looping over a range from one to two, basically generating two copies of this div, and then the div has all that stuff. Then we have this class, and once the component has a class, that basically makes it a client-side component. So by default, components that aren't for the client won't get shipped to the client. So anyways, this one has this class here, and there's this onCreate method, which does about what you'd expect. It sets some stuff up when the component's created, and then there's this event handler move, which is tied into onMouseMove.

00:15:45 - Anthony Campolo

Yeah, what you're doing here is really clever. This is actually when I was first learning to code, I was first learning JavaScript. I found a tutorial that showed me how to do this, and it totally blew my mind, because what's happening is that you're taking the actual mouse itself and tracking where it is on the page using XY coordinates and then mapping those to basically change as you move the mouse around the page.

00:16:09 - Scott Steinlage

I literally just read something on Twitter about the person who created the mouse in 1969, I think it was, and how they were using XY components to show where it was on the screen, and then therefore using it on a GUI, which is pretty cool. So anyway.

00:16:31 - Anthony Campolo

Yeah, yeah, yeah, yeah, totally. All right. So that is.

00:16:37 - Ryan Turnquist

Yeah, basically this whole. Whole effect here is driven. Yeah. Like you said, by these XY coordinates. And then we were just sticking those in a CSS variable, this, like, mousex and mouse Y CSS variable. And then you can see there's the styles down below that are getting applied. Yep.

00:16:56 - Anthony Campolo

Awesome. So, and then how does it actually get applied, then to this component? So we have this thing happening here.

00:17:06 - Ryan Turnquist

Yeah, so, yeah, one thing that Marko does is we have, like, automatic, like, discovery of tags. So, like, this mouse move tag that you're using here, you know, you can see it's not being, like, imported. You could import it if you wanted to, but we just have, like, a convention where it looks in certain places for these, you know, for Marko files.

00:17:29 - Anthony Campolo

Does that mean you need to be very careful about how you name your components?

00:17:33 - Ryan Turnquist

I mean, you just need to name them, like, whatever you want them to be discovered as.

00:17:40 - Anthony Campolo

And don't put spaces.

00:17:41 - Ryan Turnquist

Yeah, you could.

00:17:42 - Anthony Campolo

Stuff like that.

00:17:42 - Ryan Turnquist

You could import it directly. What's that?

00:17:44 - Anthony Campolo

And don't put, like, spaces in the file name and stuff like that. I would assume it wouldn't work, but who knows? Yeah, don't do that. Yeah, it's just. Yeah, that's something that I kind of think about sometimes is, like, just the conventions of how we name our files. Because if you're trying. If your framework has to take a thing from one file to another, it ultimately is having to find that file, and that requires some sort of, like, searching for a file name. And I just know this from, like, Redwood. There's, like, lots of ways in which that can go wrong that people don't really think about.

00:18:17 - Ryan Turnquist

Yeah, they throw Windows in the mix.

00:18:20 - Anthony Campolo

Yeah, totally. Oh, my God. And then here we got the layout. So what's happening with this layout component?

00:18:28 - Ryan Turnquist

Yeah, so this is this component. You can see it has the sort of document root in it. The way Marko Run works, we have these layouts. We took inspiration from Svelte, so we have +layout and then +page. We did that because we wanted people to opt into the files that were going to become part of their routes. So if you have some other Marko files next to your page or whatever, you don't want those accidentally included as routes. That's why we use directories as the paths and then these well-known names for the routable files. Anyways, the layouts all wrap around each other from the outside, and then the page is the innermost piece of your UI.

00:19:44 - Anthony Campolo

Yeah, Redwood does a similar thing. We have a layout kind of thing like this. I think at this point pretty much all frameworks do. And there are two things you want to hone in on here. This is what you're saying, where we're actually taking the page. So input.renderBody is importing this thing, and then the global meta page title, that's this, which we haven't looked at yet. This is our meta information, and that's why if we look here at the top it says "welcome to Marko." If we change that, we'll see that change up here.

00:20:23 - Ryan Turnquist

Yeah, so yeah, you're right. So yeah, the input render body, that's basically like our, that's Marko's like props children. Essentially the naming has like some history. So it's not the like most obvious name. But yeah, so that's how you render like the inner. You know, if this layout, this layout is going to render like whatever's underneath it. So you stick that there and then like the next layout would render.

00:20:52 - Anthony Campolo

I would argue this could be a good name because you're rendering the bodies in the body tags.

00:20:56 - Ryan Turnquist

Yeah. And then yeah, like I said, there's the. We also have that like meta and that could be like a JSON file or JavaScript file. And that's where you can put some like, you know, basically static, statically known like metadata. So in this case, yeah, we're using it for the page title since we don't have access to like, you know, since this layout file doesn't have access to like the page Marko component. Yeah, we, we stick it in the metadata.

00:21:32 - Anthony Campolo

Okay.

00:21:32 - Ryan Turnquist

So every, every like page can have a metadata metafile.

00:21:39 - Anthony Campolo

Yeah, and that's one of the things with your naming convention here. This is what we're going to see with what we create next. We're going to create an about page. So first we create an about folder, and we're going to do the same thing our index folder has and create a +page.marko and a +meta.json. Then we'll put HTML there and JSON there, and over here we'll just go to /about, and then we'll see our about page. Yep, that's all pretty straightforward. Now we've got these handler functions. This is interesting. What's going on with these handlers?

00:22:28 - Ryan Turnquist

Yeah, so this is how you can define basically like API routes or basically, you know, if you need to do some, some like dynamic thing for a request, like, this is where you can, where you can do that. So once again, taking inspiration from Svelte, and I think probably a lot of other frameworks are doing this now, but you just export these, the HTTP verbs.

00:22:58 - Anthony Campolo

Is this like an API route in [unclear]?

00:23:01 - Ryan Turnquist

It's both. It's an API route, but this handler actually gets called before the page if there's a page associated with it. So yeah, this is in the index route, the slash route. This handler will get called before the page is rendered, and essentially the rendering of the page will be this next function that you see here on line 5. You do your server-side work, and then you render your page. This handler could return some other response instead of returning the page. Obviously that would be for the GET request, and then for POST you could do whatever you want there.

00:23:47 - Anthony Campolo

Okay, in a second we're going to put in some middleware as well that this will involve. But first, if we see we can. So this is just in our index. If we look at our localhost 3000, if we curl it and send a post request, we should expect to get back this for it to say, posted and then give us a 200 status. If we test that over here, that's exactly what we see. All right, now we have an about page, which means we need an about link. So I'm just going to edit our layout here to add a couple links there. And now we can see we can go to our about page, our homepage, and then we're going to add in some 404 handling, because you actually have a convention for that. So Right now this is happening, but we can actually get a nicer example with a 404. Oh, actually, sorry, that's going to be after the middleware step. Getting ahead of myself. So, middleware, explain middleware. Middleware took me a long time to understand just, like, as a concept.

00:25:02 - Ryan Turnquist

Yeah. So I think middleware is kind of analogous to, like, layouts for pages. So, like, the handler is sort of the endpoint, and then the middleware is just some. Some code that's going to get called before that, that handler or that page. And so this one just has a default function because we run these for all verb types. And. Yeah, so basically we'll run your middleware and then, you know, for some. For some route, you know, we'll run the middlewares in order of. From, like, the root to the deepest. Most middleware in that you have a diagram. Yeah, maybe bring up that diagram. Might be.

00:25:47 - Anthony Campolo

Yeah, this is a comprehensive diagram. Hold on. There we go. That's what I want to do. So what the heck is happening here?

00:26:00 - Ryan Turnquist

Yeah, so you can see there's like, ultimately, the page we're rendering is like, route, slash, about. And so first we run your middleware, and then that middleware calls the next middleware. So first we run, like, the middleware defined at slash, and then we run the middleware at slash, about. And then we run your handler, and then the handler basically executes, like, the page. So, like the layouts, the two layouts that are defined plus the page, they all get combined into, ultimately the page that's rendered. And then you kind of, like back. Back out. Right. And that lets you. So your handlers or your middleware can basically, like, be involved with the beginning and the end of, like, the request.

00:26:51 - Anthony Campolo

I'm so glad I had you here to explain this to me because I first saw this diagram. I'm like, I think I get it. But having you walk me through it and actually, like, looking at piece by piece, I now actually get what's going on here. That's really clever. If that doesn't make any sense to people who are watching right now. Check this out. Let's run this again. What's going to happen is we're going to console log. Some stuff here is when the page gets loaded, this runs and actually logs out the time it takes to. Is this the time it takes from, like, the request being made to getting it back?

00:27:30 - Ryan Turnquist

Yeah, that's the time it's taking to generate the response, which does not include streaming time. Since the Marko page is streamed down to the client, it doesn't include that streaming time, obviously. It's just the request processing time.

00:27:48 - Anthony Campolo

So it gives us the request, which is get localhost3000, then completed in. And then if it's successful, it'll say successfully and give us a performance. And if not, it will give you an error. And if we look back to the handler here, we then see this is being console logged as well, right here.

00:28:10 - Ryan Turnquist

Yep. Yeah. And so, yeah, basically the. The. The handlers and the middlewares both have the same function signature, and it's. It's this context object which contains everything about the request. So the parameters, the request itself, metadata, all that kind of stuff for that route. And then there's this next function. The next function. Basically, you call it, and it just does. It returns a response that's being generated by the next step. So, like, each. Each middleware typically is like, you call the next thing and then return that response. It's optional to call the next function. So, like, if you don't. If you just don't do anything, if you return undefined from your. From your middleware or your handler, like we call it. We call next for you just because it's like, just convenient. But if you wanted to do something, if you wanted to augment the request that you. Or the response that you got back from, like, the next middleware, the page, or whatever, you can then await it. And then now you have that response and you can do something with it.

00:29:22 - Scott Steinlage

In this instance was the handler. I mean, obviously, like, the console log showed handler first, and then it showed the middle.

00:29:34 - Anthony Campolo

Where am I wrong?

00:29:37 - Ryan Turnquist

Or was that. Yeah, so you can see it. Well, you can see it, like, logs the.

00:29:43 - Scott Steinlage

When it logged out.

00:29:43 - Ryan Turnquist

Started. What's that?

00:29:46 - Scott Steinlage

When it logged out.

00:29:47 - Anthony Campolo

Yeah, so it logs this, which is this part.

00:29:50 - Scott Steinlage

Oh, there it is. Okay.

00:29:51 - Anthony Campolo

And then it logs this, and it has the handler.

00:29:53 - Scott Steinlage

Okay.

00:29:54 - Anthony Campolo

And then the last, which is this part.

00:29:58 - Scott Steinlage

Got it. Okay.

00:30:00 - Anthony Campolo

Yeah, got it.

00:30:01 - Scott Steinlage

So that's the completion of everything.

00:30:03 - Anthony Campolo

Yeah, got it. Okay. This is a great demo about whoever wrote this code to demonstrate what's happening here. It's like very, very, very clear.

00:30:12 - Ryan Turnquist

Thanks. Yeah, I wrote it. So that's great to hear.

00:30:15 - Anthony Campolo

Good job, man. Yeah, no, this is. This is great. This is, like, really exciting stuff because I learned Marko by itself around sometime last year. And, like, all the components, syntax took a little while to understand and just like the general project structure. And then once I got there, I'm like, Cool. Now, how can I do all this other stuff? All these other frameworks do. And it like, wasn't there yet. And this is where Marko Run comes in.

00:30:43 - Ryan Turnquist

Yeah, no, I'm super excited to. Yeah. For this project. And yeah, I think, I think it's just going to make it, like, make Marko, like, way more approachable. And plus we're. We're planning on using it in eBay. So I'm like, yeah, I think we're going to.

00:30:56 - Anthony Campolo

That's where, you know, it's going to get really good. Yeah.

00:31:01 - Ryan Turnquist

Yeah.

00:31:02 - Anthony Campolo

And then this is just one more kind of nice convention here. You can create some automatic 404s and 500 messages. And then if you go to a route that does not exist, then we get this custom not found page.

00:31:19 - Ryan Turnquist

Yep. Yeah. So you can define a top level 404 and top level, like error handling page, 500 page. And they get the. If you have a layout at the top level, they have access to that layout, as you can see in the 404 page.

00:31:35 - Anthony Campolo

Yeah, that's right.

00:31:38 - Ryan Turnquist

And.

00:31:39 - Anthony Campolo

All right, cool. Actually, skip that step. Skip that step. All right, Marko 6 Tags API. This is new. This is not even technically released yet. This is a preview. It's beta. Technically, Marko Run is also beta, I think. But what is the Tags API?

00:32:01 - Ryan Turnquist

Yeah, so the Tags API is the new API that we're using in Marko 6, and it replaces our current class API that we have in Marko 5. So when we were looking at that mouse mask component, we had that class where you defined your state and your event handlers and all that.

00:32:24 - Anthony Campolo

We're going to click the counter. It counted. All right, good job. All right, so this is a counter. Now, if this wasn't a counter, this wouldn't technically be a real component, because a component has to be a counter. Right. If every tutorial I've used is correct, a component means a counter.

00:32:42 - Ryan Turnquist

Right? Yeah, it's the best. The best demo.

00:32:48 - Anthony Campolo

It's good, actually. I'm glad that we've all kind of standardized on the counter as an example, because it lets someone who has built a counter before be able to figure out your component syntax extremely quickly. You have a count, starts at zero. When you click, it bumps the count up and then you show the count somewhere. Yep, that's the whole thing. Yeah.

00:33:09 - Ryan Turnquist

So really the. The Tags API here is like the let. And the sort of controversial forward slash which separates the tag name from the thing that it returns, essentially.

00:33:27 - Anthony Campolo

So what other words would be here, aside from let? Or is it always let?

00:33:31 - Ryan Turnquist

Yeah, no, so let is just a tag. let is the let tag, which is part of the Tags API, and it's going to be part of Marko 6, and that's essentially state. We also have, yeah, there's a [unclear] right now written here by [unclear].

00:33:50 - Anthony Campolo

Yeah, there's Ryan's got a couple articles and that's exactly what we're looking at right here. There's not really docs yet for the tags API though, I don't think. Except maybe that's. This git repo is going to be the main thing and. Yeah, so you have this example again and that's pretty much it. So do you have examples of other tags anywhere?

00:34:13 - Ryan Turnquist

Well, if you go back to that article that Ryan wrote, I think you

00:34:17 - Anthony Campolo

put all the ones that were the docs right now it's probably the most accessible right now.

00:34:24 - Ryan Turnquist

So yeah, we have let is like mutable state essentially. Then we have const, which is like use reducer.

00:34:34 - Anthony Campolo

Okay.

00:34:35 - Ryan Turnquist

But the, the. The main thing with the tags is like they're completely composable. So like you can just create whatever tag you want using using the sort of like fundamental tags.

00:34:47 - Anthony Campolo

Yeah, someone's really gotta at least take these screenshots, write them into code, and stick them in your Tags API docs. If this is the only thing available for the Tags API right now, it's a...

00:34:58 - Ryan Turnquist

Not super great, it's a preview. So yeah, docs are definitely on the to-do.

00:35:04 - Anthony Campolo

Yeah, all good. Yeah, that's part of my job is letting people know where they can improve their docs. So not putting you on blast. Just let you know what your next step should be. Cool. So that's pretty much the whole project. Are there other things that you want to at least call out that we didn't show in this before we go to the deploy step?

00:35:25 - Ryan Turnquist

I guess we could like, we could talk about adapters. We could talk about like configuration.

00:35:34 - Anthony Campolo

Yeah.

00:35:35 - Ryan Turnquist

So for adapters, I guess there isn't a whole lot of configuration to show, but yeah.

00:35:43 - Anthony Campolo

So for your adapters, you have a similar convention where you're using just Vite configs. This is also why Vite is so great, because Vite allows a lot of these frameworks to standardize on stuff. You're using the Netlify adapter, which is not surprising. And you also have a Node adapter and a static adapter. The way that I'm going to end up doing it with Edgio is going to be using the Node adapter. And this is the one that's going to be really useful for people who want to deploy this on something that doesn't already have an adapter created for it, because it's basically just letting you run it wherever you can run Node. Is that correct?

00:36:26 - Ryan Turnquist

Yeah, yeah. So the Node adapter is the default adapter if you don't specify any other adapter. It lets you run easily on Node, and it's essentially converting the HTTP incoming request or incoming message into a WHATWG-style request, and similarly converting the WHATWG response into a Node server response. So yeah, adapters do a couple different things. They let you do stuff during the build, and they let the adapter specify a default entry for the server part that's going to handle request/response conversion for you.

00:37:34 - Anthony Campolo

Is that this. So like you're. When you're talking about being able to kind of insert things with the server.

00:37:43 - Ryan Turnquist

So I mean, this is like a. Yeah, so this is, you know, like the entry point.

00:37:46 - Anthony Campolo

I mean, because we look something like this, there's no entry point in this configuration, right?

00:37:50 - Ryan Turnquist

Yeah, so like by default, like we, we provide an entry point for you which is essentially your server. So like, the adapter can provide. It's like, at least for node, like the, the adapter provides a node server for you, but you could write.

00:38:05 - Anthony Campolo

So this could be index ts instead of my dash app dash server. And this is basically your entry point.

00:38:11 - Ryan Turnquist

Like this could be like. So you could write your own server here and then use that as the entry point instead of like, instead of like relying on the default one.

00:38:20 - Anthony Campolo

So something like this. Bam.

00:38:23 - Ryan Turnquist

Yeah.

00:38:24 - Anthony Campolo

Yeah.

00:38:25 - Ryan Turnquist

So now you have like full control over, over how your server works. And then, you know, you're just importing this like router middleware from the node adapter and that provides you all the routing stuff

00:38:40 - Anthony Campolo

Going back to this, this is my Edgio project that we're going to deploy. I jumped ahead a couple of steps because I didn't want to walk through all these things. This is the part where you have to write a whole bunch of Edgio-specific code that's going to be hidden behind a connector eventually. Explaining all this code is completely irrelevant, so we're just going to ignore it and pretend it's not there. Then we have this edge config which tells us that we're using the Edgio connector, and we have an entry point which links us into here. But as I said, that's Edgio-specific guts stuff. Whereas this is the thing that's actually relevant to Marko. Once you got all that set up, then we can do edgio deploy. That's going to do its thing. I'll take a quick second here. It's showing us we're getting an about page, our index page which hits a handler. We also have a POST handler that we showed earlier, and we have our 404 and our 500.

00:39:48 - Ryan Turnquist

Nice, Marko Run. When you build the production version, it'll generate this table for you so you can get an idea of what routes it knows about.

00:40:00 - Anthony Campolo

And I like how it even shows you the sizes. So is this zero kilobytes? Because there's no JavaScript on this page.

00:40:06 - Ryan Turnquist

Yes, that's the client side. Yeah. So that'll show. It'll be zero if you don't have any.

00:40:10 - Anthony Campolo

So we're at zero JavaScript class components. So yeah, you've been seeing this in this Twitter argument about whether 0 JavaScript is like a good goal or whether it should be. Should be thought of as a goal as a baseline or not thought about at all.

00:40:24 - Ryan Turnquist

Yeah, definitely seen that.

00:40:27 - Anthony Campolo

Great. Here we go.

00:40:29 - Ryan Turnquist

I don't think it's the goal.

00:40:31 - Anthony Campolo

Yeah. If you want a site that does something.

00:40:38 - Ryan Turnquist

So this is deployed out.

00:40:39 - Anthony Campolo

Yep, this is it. This is live. So here's our link. HAC Web Dev Marko run Edgeo Default Layer 0, Limelight. Fun stuff. These are two previous companies names before we are Edge IO Layer 0 and Limelight combined into Edgeo. You can see the history of our tech debt within this link.

00:41:00 - Ryan Turnquist

Nice. That's awesome.

00:41:03 - Anthony Campolo

Great. Cool. That's the whole demo. I think we already showed people where most of the relevant links are in terms of Marko Run and the Tags API. All these links will be in the show notes in the description as well. And you've got just regular old markojs.com for your home page, which is nice and retro looking. And then we got docs and "try it online," which I'm assuming is going to kick us into one of these. That's pretty nice. Yeah. And this is actually... Ooh, let's talk about this. This is the component library, right? You have a lot of components here, so yeah, go ahead.

00:41:51 - Ryan Turnquist

Looks like. It looks like there's an issue.

00:41:56 - Anthony Campolo

Yeah. So this is kind of letting you just walk through a lot of different custom components you've got, which is really nice because you can give people like hello worlds and all that kind of stuff, but it's nice to actually have more kind of full built out components. And you can't scroll in this by the way.

00:42:18 - Ryan Turnquist

Yeah, so... and add this to the bug list.

00:42:22 - Anthony Campolo

Yeah. Right. Fun stuff. And yeah, are there any other... Oh hey, there's me. There's a Discord as well, so find that here in the readme. And then there's a Twitter here as well. This is also me. I compared Marko and said it's forever destined to be the Nikola Tesla to the Edisons and Marconis of the front-end world. So if you know this history, basically Edison and Marconi got credit for inventing a lot of stuff in electricity that Nikola Tesla had done first. All right, cool. You can stop sharing my screen, Scott. There you go. Great, cool. Thanks so much, Ryan. That was super fun. Do you have any other comments or things you want our listeners to know about at this point?

00:43:22 - Ryan Turnquist

Yeah, I think just. Yeah, go check out Marko and use Marko Run to get started with it. Cool. Just excited to get more people in the Marko camp.

00:43:34 - Anthony Campolo

If someone were to contribute, what would be something that is both needed and feasible for someone who's never used it before?

00:43:44 - Ryan Turnquist

Use Marko or.

00:43:47 - Anthony Campolo

Yeah, so like if someone, so someone's like, I want to get, you know, there's always people like I want to get involved in open source and like you just need to kind of hand them a project, then they'll go do something. But if you just hand someone a project like React, they can't contribute to React. It's impossible. So is there actually things like. So I would say from what I've seen is that I think helping with docs and examples would be really useful. If someone were to build a Marko tutorial, like I'm working on one right now. I think that would probably be pretty useful for people.

00:44:13 - Ryan Turnquist

Yeah, that'd be useful. Yeah, definitely like docs useful like for Marko Run, I think like building like more adapters and stuff like that. So we, you know, have parity with, you know, these other frameworks for like deployed targets. So I think that would be a good thing to help out.

00:44:33 - Anthony Campolo

Yeah. The table stakes seem to be Netlify, Vercel, and Cloudflare. Almost everyone has all three of those. And soon they will all have Edgio ones as well because we'll build them and hand them to each project.

00:44:45 - Scott Steinlage

Force them.

00:44:47 - Ryan Turnquist

Yeah, yeah. Just to get started, I wanted to have something like Netlify that uses normal request/response type stuff, obviously Node. And then static was another different one. I feel like those three are good examples, and then you can probably build any of the other adapters based on one of those. Cool.

00:45:15 - Anthony Campolo

Scott, do you have any questions as we close out?

00:45:18 - Scott Steinlage

No, this was super cool. I was really following along actually pretty well.

00:45:23 - Ryan Turnquist

So, yeah, it's neat.

00:45:25 - Anthony Campolo

I like it. Sweet. Great. Yeah. And I'm looking forward to continuing to build stuff out with Marko. I have a tutorial that I wrote like 90% of a long time ago, and then I kind of sat on it and didn't finish it. And then I'm like, I'll just put it out when Marko 6 comes out. And I realized that could be a while. So I'll probably finish it up and put it out maybe in a month or two, and include the Edgio stuff in there. So yeah, keep your eyes on that, and yeah, I think we can close it out.

00:45:56 - Ryan Turnquist

Is that just like a general guide or.

00:45:58 - Anthony Campolo

It'll be. So it'll be a tutorial that will walk you through a lot of, like, the stuff actually in the Marko docs in terms of, like, what are tags and how does all that work, the actual component stuff. Then it'll have the Marko Run stuff, which didn't exist when I first wrote it. I changed some of the projects so that you end up building out the structure of what the starter is doing, and then it'll be the deployment stuff after that.

00:46:29 - Ryan Turnquist

Nice. That'll be awesome.

00:46:32 - Anthony Campolo

Sweet. Well, thank you, everyone. This has been the JavaScript Jam podcast, and we'll catch you next time.

00:46:40 - Scott Steinlage

See you in the next one.

On this pageJump to section