I sure hope you're hungry. Cool, I'm starving. Wash those hands, pull up a chair, and secure that feedback. Because it's time to listen to Scott, Lindsay, and Wes Voss attempt to use human language to converse with and pick the brains of other developers.
I thought it was going to be food. So buckle up and grab that o***** handle, because this ride is going to get wild. This is the Syntax Supper Club. Welcome to Syntax today.
We have Brian LaRue on. We've had Brian on in the past once before to talk about Begin.com, talk about the old days of phone gap. And today we have Brian on to talk about a couple things. First, a very strong opinion he has about not running bundlers, and just raw JavaScript right to the browser, as well as Enhance.dev, which is a framework for building web apps, which is standards-focused.
Is that the quick rundown? Or give us the pitch for what it is. Yeah, I guess the foundation of it is server rendering web components. Yeah.
Without a build step. You can add a build step. If you want to make things slower, it's fine. Already getting spicy.
If your code's getting spicy, because maybe you're bundled in, you don't actually know what you're shipping. Maybe you'll want an error and exception handling tracking service, because maybe you're shipping some bugs. So head on over to Sentry at Sentry.io. Use the coupon code TastyTreat, all lowercase, all one words, you'll get two months for free, and you'll be able to track and solve your bugs way better and faster.
So, yeah. Love it. Got to do that. Can't fix bugs, you can't see.
Can't fix bugs, you can't see. That is a great tagline. So I'm going to start saying that, Brian. Yeah, that's good.
So we're both wearing our plaids today, in addition to being Canadian. This is our cultural identity, I think. Exactly. I can't believe that we're both wearing the red plaid today.
It just feels so right. There was a very high probability that this collision happened. Yes. How many plaids do you own?
I probably own like 15. Yeah. I've got a good battery of flannels in there that I rotate through, blue, green, red, and gray. It's a time of year.
It's freezing out there. You don't need to wear warm, cozy clothes. It's kind of like a holiday thing. Do you think they would be bigger in Denver than they are?
I think we do more like furs, alpaca furs. Really? Like, we've got alpaca furs in Denver. I don't, personally.
But that's what you see. That and Patagonia. We just got Patagonia. But you don't see flannels everywhere.
Yeah, I don't know. It's a real Canadian thing, for sure. Like, this is definitely part of the vibe. Part of our heritage.
You know, this is Arcterics, Blundstones. You're ready to walk around in any Canadian city. The Canadian Starter Pack, yes. So let's talk about opinion on not using a bundler.
So Brian is a really good follow on Twitter. He's always spitting hot takes, but not obnoxious ones. There's a lot of people that spend all day on hot takes on Twitter, and I find it to be obnoxious. I feel like Brian has a really good even head towards his opinions on Twitter.
I'm always interested in, like, what does that, you'll see me reply. What does that mean? Tell me more. And one of your things you've been talking about lately is that you don't use a bundler.
You don't text script it. You don't babble it. You don't run it through V. You just load JavaScript in the browser like some kind of psycho?
Tell us about that. Yeah, so I'm not anti-anything, but just to be clear, I'm pro start with the simplest thing that could possibly work. And I feel we reach for a lot of tools without actually measuring or thinking about how we're going to use those tools or what benefits they might provide. And so bundling is a technique.
It's not an edict. And browsers are designed to execute JavaScript, and they're pretty good at it. And in the past few years, they've gotten even better at it, especially networking. We've got, you know, HTTP2, HTTP3.
We can download things in parallel. We've got pretty good CDNs. They already brought lead and gzip stuff for you. And so I'm not saying don't bundle.
I am saying you should measure, and you can't fix what you can't measure. And so you should use a tool like Century to look at what you're building and understand what you're building to make that thing better. And, yeah, start with the simplest thing that could work. It's probably HTML, CSS, and JavaScript.
And, you know, if that isn't cutting it, then absolutely start, you know, doing what it takes to make things better. We started asking in Enhance, like, how far can we go here and what can we build? And, you know, we heard a lot of people say, well, there's certain types of apps that, you know, you just can't build unless you use a bundler. And we actually haven't found that edge yet.
And, you know, we put our work out there for people to see. So it's all open source, and you can, you know, go to enhance.dev slash showcase, and you can open up Chrome DevTools, and you can trace stuff for yourself and see and look at the source code if your source even works. And so, like, there are downsides to bundlers. And this is, you know, not like a hate or something.
You know, it's a developer experience hit. Your iteration speed will always be faster without a bundle step. You know, you can improve that bundle step by 1,000%. It's still slower by 100% than no bundle step.
So avoid a bundle step is just better developer velocity to start. Now, the other cost, and the bigger cost to me anyways, is the debug loop is harder. And you can bandaid that. So if you bundle everything, you've got one single file that's one column, and you get a bug at runtime, chances are Sentry's going to help you figure out where that was.
But chances aren't guaranteed that it will. Now, we can use things like source maps to make that better and get, like, a real stack trace where we've got a line number and we know what to go fix. But odds are you're going to chuck some darts with console that long before you figure that out. And that's slower developer speed.
So your game are hitting your iteration speed. And maintenance doesn't happen at a convenient time. You're going to be out picking up your kids or going over to your parents' house and have no computer. It's always at the worst possible time.
And then your error is going to be on, like, line one, column 10,000. Undefined is not a function. Good luck with that, buddy. And you're on the hook.
And so a real stack trace is actually quite nice when you're going to get an application. The other last thing to say about the node debug is it's contextual. So I feel browsers, as we put more and more work on them, it definitely is a great tool to have in your box. And it's a useful one.
On the server, there's really no evidence that this is a good thing. So we recently created a new project called AWS Lite. It replaces AWS SDK. You can find it at awslight.org.
And we didn't want to do this at all. This was really a thing that we kind of had to do. So Amazon did the JavaScript thing. And they created a new SDK.
And they based it on TypeScript. And they transpiled it. And it supports Deno node and browsers. It supports CommonJS ESM for all of those payloads.
And they ship it in a single package to MPM. And the resulting payload is something like 95 megabytes, which is a huge kick in Lambda's nuts for a cold start. And worse, they're forcing that as an upgrade path in Node 20. You can't use V2 SDK anymore.
And so we were facing a pretty big performance regression. And they were like, well, don't worry. You can just bundle it. And we're like, oh, man, that is not a great answer because now we can't debug it.
And Node errors are even harder to debug than browser errors because we don't have a dev tools for Node. At best, we're going to have a third-party analytics error reporting service. So you really want good line numbers in your Node process. And that's a different place.
In AWS Lite, we have this extensive set of benchmarks. And we show that we're about five times faster. But the really most fascinating part about those benchmarks, you can go see and reproduce this for yourself. So this is, you know, don't shoot the messenger here.
I'm just sharing data. This is science. Hopefully, we can all agree that that's a good idea. Bundling is slower than not bundling in this case.
Now, this is this case. This isn't all cases. So you'll hear people say, well, bundling is faster. And that's just not true.
Like, there's different cases. And not all bytes are the same. If you have a whole bunch of modules and you bundle them, certainly you have less imports. But it depends on what's in those modules.
If you're loading a bunch of dead code or you have a whole bunch of binary data in there, it could actually be slower. And in the case of the AWS SDK, it is. Or in our AWS Lite package, it is slower. So it always comes back to measure and observe and improve based on data.
And that's really what we're all about. And when I'm saying, you know, don't bundle, I'm not saying don't ever bundle. I'm saying don't start with a bundler. Maybe grow into that need and improve if you need it.
Yeah. So one of my long-term dreams is to be able to push the code I write to NPM as a package. You know, like, wouldn't that be nice? Because it's such a pain in the butt to try to figure out why a library is broken.
Because you go on GitHub and that might not be the same thing that's on NPM. And then you look into NPM, you're like, which one of these 11 outputs am I using? And then finally you open it and it's all like variables are called A and H. And it's so frustrating.
And I just wish that there was, I just want to import the code that was authored and run it. And obviously things make that impossible to do. Well, not impossible, but much trickier. So people are probably wondering right now, like, but what about X, Y, and Z?
So we've got a couple of whatabouts here. Yes, I love TypeScript. We do use it. We use it with JSDoc and D.ts files that we import.
We even write TypeScript. And then we just import those as JSDoc comments. And is it perfect? And is it as good as using raw TypeScript with all the tooling out there in the full ecosystem?
Totally isn't. But it gets us types. It gets us up, you know, red squigglies and autocompletes. Yeah.
And that's what we're really here for. So yeah, we use TypeScript. We like it. We use it with JSDoc, which, you know, sometimes people look at me like I'm a lizard when I say that.
It works great. And it's nice because there's a build stuff and it doesn't obfuscate my code. No, I was going to say, and there's like a low key. Sometimes there's like things that are easier with the JSDoc style typing.
Like you can type an entire function with an import rather than having to type the result of the function. Yeah. And I feel like things have gotten a little, I don't want to like make people feel bad, but like sometimes it feels like the type thing has gotten a little out of hand, really generic, not very specific. The guidance of the types is actually getting lost now.
And they're becoming almost too generic, too fancy. It's like, yeah, okay, we got type cards here, but I don't know what this T value is. This is a meaningless value to me like. When we hover over top of some of our Prisma type of errors, it's like a thousand lines.
And some libraries are starting to go less in the generic area and more in the generated area because it's just like, I can't read this error. I mean, I want to know if something's a stringer number and I want to know, you know, what the name of that variable is and what weird way Amazon decided to spell it this time. Aside from that, it's pretty diminishing returns for me personally. So, yeah, I like the lighter touch typing.
Like I don't think it has to go so deep. It really, it should be a convenience and it should be somewhat self-documenting. So that's another nice thing about the JSDoc. It comes in line and feels like, you know, now it's reading like what's going on.
And I don't have, and I know this is why people want to put it in one file because, you know, then it's all there. And that totally makes sense at author time, but it stops making sense at runtime for me. We'll talk about the JavaScript file. So one thing about shipping ESM straight to the browser is that you can have an entry point and that could have, it parses that and then you can have import inside of that.
And then it parses that and that could be imported inside of that. And you get a waterfall. So people are saying, yeah, HTTP2, HTTP3 fixes that. But then some people say, no, it doesn't fix that.
It doesn't. How do you, is that just something you live with? Is there's a potential waterfall of imports? Yeah.
So, you know, you're right in code. You can, you can not do that. There's a good part here. And the good part, I mean, honestly, a lot of the time we end up inlining the JavaScript, which sounds even crazier, I'm sure.
So we'll inline it in the HTML document at the end of the page because there's so little of it when you're doing progressive enhancement. We're talking tens of kilobytes, not megabytes. So when it's that small, and you can view source on enhanced dev and take a look at how we do that. It's literally script tags at the bottom of the page.
And it loads sub-second. Now, if it was huge, it was big, we want to split it up a little and get smarter about sharing code between different pages. Yeah, bring a bundle of the party. That's what those are designed for.
But we don't have that problem to start with. So I'm not saying that problem doesn't exist. I'm just saying we can sidestep that by being sort of intentional about how we write our code. And because a lot of these frameworks are starting to say default everything to the server, the amount of JavaScript you need on the client is, like, I just went to enhance-music.com, which is one of your things, and opened up the dev tools, clicked Builder for JS, and it is 21 lines, including the service worker registration.
So, like, it's not a lot of JavaScript. So does server rendering a lot of this just sidestep a lot of these waterfall concerns? Yeah, and, well, again, how you structure your modules and your components. In the transpiler world, we start with JavaScript.
You know, you write, oh, you don't really. You write JSX or you write, you know, .cell tree, .ashtore, or whatever. But effectively, you're writing what becomes JavaScript files. And then you execute those JavaScript files to generate HTML.
In our world, you're writing either straight up HTML, which I know sounds totally nuts, or you're writing a JavaScript function that returns HTML and runs inside of Node. And so the only thing that hits the browser ever is HTML, and then, you know, some small, pithy amount of client JavaScript for registering events and handling them. And it is a totally, it's pushing all the JavaScript into the Node runtime, basically. I'm curious about how you still manage to do things like, like, for instance, on this Enhanced Music page, right, you're able to have a player that sticks around amongst page navigation.
And that's, like, typically thought of as, like, a spa feature. How do you get around those limitations? It's an iFrame. It's an iFrame.
Really? Yeah. It's in the platform, yeah. Yeah, iFrame in a web component, of all things.
Oh, gosh, that's, like, the most old and the most new tech converging. Yeah, so we had a snarky person say, well, you couldn't build, like, a Spotify with, like, web components. And we were like, yeah, I don't know, maybe. And then we were like, oh, yeah, sure we can.
No problem. It misses on some aspects, I think, of the user interaction. If I was to redo this one, I'd probably actually just make it a single page, but not a single page app, but, like, actually just a single page. We got a long playlist and just hit play.
We would reload the page and reload the audio element with that player and pop your uncle. Because you don't really want to pause and navigate music at the same time. I don't do that anyway, so. I think it got vilified back in the table layout days and sort of left that one hanging, but it's pretty stable now.
The only issue I have with iFrames might be around rewriting client cookies. It's a bit funky. There are ways around that, too. So, you know, there's always a hack with browsers.
And what about, like, live reloading and dev tooling? Like, you make a change, you want to see an update in the browser. Do you still get that type of tooling when you go this way? Yeah, well, in Enhanced, we kick a web socket and we watch your file system, and we will force a reload of the client JavaScript if you've enabled that.
And, yeah, this is another great thing about the way that we're approaching things. The dev tools work, so you don't need a plugin or something. Like, the real dev, like, the VueSourcey inspect element dev tools, they all work, and they're great. Like, the only thing I find still really awkward right now with Chrome dev tools, slotting with web components.
The way they show it in the dev tool is kind of weird. They, like, render these sub-documents that you kind of got to dig into to find things. It's hard to describe. It's almost like they tag them and they put them in a different place in the DOM than they really are.
But that's the only thing that I found kind of awkward. Otherwise, browsers are really good now, man. Like, really, really good. Like, we are so spoiled.
The way it used to be was pretty rough compared to today. And it's hilarious because our ecosystems have basically niched us out of using the native tooling that's available to the platform that has been improving this whole time. So, yeah. I feel there's a lot of merit to getting back to some of these sort of really basic things and looking at how the platform works and using the tools that are bundled through the browser.
Even WebKit's tooling is actually pretty great, honestly. Yeah, there are times when it gets annoying in the WebKit land, but there's no one. Last night, WebKit announced their 17 release, and I could hardly scroll to the bottom of that blog post. It was unbelievable.
And Nicole Sullivan. They just hired Nicole Sullivan. Oh, they did? Yeah, and she's the manager of layouts or something like that.
Oh, man. Apple hired someone just to focus on layouts rendering in the browser. Wow. Yeah, it's good news for the web.
I love seeing that. It's awesome. Yeah, WebKit gets a rough rap these days, but I think they've been giving it a college try for sure. It's been improving.
And the baseline, our expectations now are pretty awesome. Oh, when are they going to finally have view transitions between their multi-page transitions API? We're asking for some pretty heavy-duty stuff. The browser's pretty good these days.
Remember we were stoked about rounded corners? Yeah. Y'all are spoiled. Yeah, stoked about that.
Oh, yeah. That was a thing. Yeah. Yeah, I love just getting in there and kind of working close to the platform, but it isn't without its quirks and annoyances.
We try and paper over that stuff inside of Enhance as much as we can, a policy that we need to compile. I read this the other day on Twitter. Someone's like, it was really bundlers that moved the state of the art forward. What?
You can only bundle to what the browser can do. The bundler didn't bring anything new to the story. It just let us write more JavaScript and get away with it. It really doesn't change the baseline capability available to us.
I think Babel was such a major step forward because finally we're able to write our JavaScript in such a better way. I know you didn't use any of the ES6 stuff until it was in the browser. Is that true? I think I remember that.
Yeah, I was on board with the transpiling thing at the beginning. Yeah, I just wait now. You do not have AHE. I can't wait for shit.
You don't want some testing? I definitely do. Browsers didn't used to be evergreen. I don't think they all were until roughly 2018.
I could be wrong about that. There was a necessity for a Babel. We needed a Babel if we wanted to use the latest stuff. There was no upgrading your browser.
But now I visit my parents in the holidays like everyone else and I don't have to upgrade any browsers. It's been done for me. That is a huge boon for web developers. We can kind of depend now on a baseline capability.
I'm not the best developer in the world. I don't need the most bleeding edge features. I'm hiding dibs and showing them like everybody else. The browser upgrade path is so much faster these days.
So last night I was talking about how awesome WebKit is and people were like oh it's awful it's the new IE still and people are like older versions of Safari and I went and looked at the stats and I was like iOS 17 came out two and a half months ago and it almost has a bigger market share than iOS 16. The hardest browser to upgrade is you have to reboot your computer and reboot your phone in the middle of the night and put in your code. That's the hardest browser to update and they already in two and a half months have almost eclipsed the previous version of the browser. I think that's pretty amazing.
It's a way better situation than we used to be in. I remember being kind of absolutely the right thing to happen. I think the important thing to remember now is that we still need browser diversity and choice. If we have a singular engine that's auto-updating from a company that's effectively an ad network that might not be a great idea.
Safari is important. WebKit is really important because as Firefox wanes we do need that competition to keep everybody honest and keep privacy and the open web at the forefront. It's a one-way door too. We don't want that door to close.
We saw what happened with IE. It was a bad scene. Bad scene. We just had Eric Meyer on and we were asking about his idea about the futures of Firefox and he also lamented that it doesn't feel like it's going in a great direction right now in terms of longevity.
So we need WebKit out there. I'll say this though. Firefox has always been on the doorstep of death. There's never been a moment where it's been like oh man everyone's using Firefox.
It's always been this weird sort of outlier and yet they seem to survive. So I don't know how they keep pulling that. They're like a cat. They have like nine lives.
They keep coming back. Yeah I'm just waiting for them to pull out their AI model that's fair or something like that. Just like a Hail Mary you know? I hope so.
I'm a long-time Firefox user. I know we talk about this a lot on the podcast but I really hope they pull through. I keep a Firefox open. I run all three.
Because even though we have auto-upgraded and we have great standards there's still always some feature that's weird on one of these browsers. Like you can't even predict. You have to test it. Yeah I tend to switch my main driver like once every couple of like two months.
Especially now that with like one password or whatever I can bop around pretty easily. But just to get a vibe see what's working later. Let's take some time to talk about Enhance. Enhance.dev The HTML first full-stack web framework.
You have a really great little landing page here. Do you maybe I know we've already kind of touched on this a bit. Where do we want to start here? Do we want to talk high level?
Because I feel like we've already done that a little bit or do we want to start diving into some of these things? Yeah I think let's talk about what it is a little bit more. So is Enhance.dev a meta-framework? Meaning that you can build a full-stack application client-side, server-side run database queries with that?
I think it counts. The meta-framework terminology is a bit weird because you know we had client-side frameworks and then they decided to go full-stack. He's that loosely I'm just care quoting right now. And so I guess a meta-framework would be something that's kind of like client-side capable but also could do some back-end-y stuff.
And Enhance actually went the other way. So it started its life as another project called Architect and under the hood it actually is Architect as a plug-in to Architect. Architect is a serverless framework for building apps using Lambda, API Gateway and DynamoDB and people would ask us how do you do the front-end for Architect? And we'd be like however you want and they'd be like no seriously man how do you do it?
And they'd be like well I would return HTML and progressively enhance it and they'd look at me like I was a lizard. So eventually we kind of had to have an answer and that answer for us became Enhance. We didn't really want to go down the road of being yet another React framework or yet another kind of meta-framework that was focused on transpiling. We felt there was a need for somebody to be like hey why don't we do this with web standards?
Why don't we try web components? Maybe they're okay now and in our view they are. So this could be seen as the meta-framework for the web platform. Yeah.
Cool. And I think a big component of that is the as you mentioned web components and SSRing of web components. It seems like something that a lot of people are either I don't want to say ignoring maybe not putting up to a huge amount of importance. What are you guys doing to SSR web components and why did you feel like that was an important step to take?
Yeah so initial work in HTML is just always going to be faster. It's how browsers work. Script tags load JavaScript and so the more work you can do on that server before you send it down to the client the better. Web components have kind of been mostly a client-side concern and the web component upgrade is largely a client-side thing but Christopher Joseph on our team realized a couple years ago now actually that you could expand the web component template independent of the behavior and so he wrote a little mini interpreter and so Enhance literally takes web component definitions and expands them on the server and then returns the result in HTML and most of that HTML is in the light on by default and I know what you're thinking right now you're probably thinking it's an interpreter oh my god it's probably pretty slow.
We put server timing headers in recently and we're rendering something like 10,000 components in sub 10 milliseconds so it's plenty fast. It doesn't really need a build step to do that. You could save 10 milliseconds if you needed to but probably don't and we still can do caching headers and stuff if we want to like have a static result return to the client. So yeah it's a little mini interpreter that opens up web components and then pre-renders them and then your client-side code ends up just listening to events and responding to them and then occasionally maybe doing some DOM manipulation but in a lot of cases it doesn't need to and it's like the kind of key example I like to give when you're building an application you've got a big header chances are that's full of a bunch of anchor tags none of that really needs to listen to JavaScript anymore.
You can do all that with just plain old HTML and maybe some CSS for hiding and showing business and that's a Vue case for a server-rendered web component. There's no listening on the client needed at all and then the other thing is your header's not really something someone's going to reuse on somebody else's website. It's going to have your brand and your logo mark and all that so you don't really need a shadow DOM or any of that isolation. It's your website so it's specific to your design system and your application so it's a nice default and you can still drop into the client and do whatever you want.
I actually was just helping someone wrap some React components in web components the other day to see if we can strangle them out and it turns out we can and so there's a migration path here too for people that want to go more low level or eat more performance out. Yeah, that header example is very interesting because I'm working on some show notes for our episode on React server components and one of the examples I'm trying to go through is a header. A header should be server-rendered however there might be parts of it that need to be dynamic like a little notification bell that checks if you have any updates or something like that. That could be done in the client but the one question I don't have the answer to is what about just underlining the current page?
You want to show an active or an active parent. Do you have to re-render the header on every single page then? Yeah, we do. Yeah, we allow for you to take over at the client level and do things like change which parent is currently highlighted.
You get past the request when you render and so you know the path and so you can check against that to do the underline or the highlight or whatever. But yeah, as you click around the default experience would be fully server-rendered for every request and yeah, there's a penalty to that. Some of those requests you might want to embed a single-page app but that's kind of the nice thing about starting this way is that you have that flexibility. Really, a single-page app is a one-way trip.
You can't really come out of that and turn it into this multi-page experience but you can always embed that needed to update whenever there was new chats or something that like a part of the website that needed to be dynamic. Is there something in Enhanced that would let me say ping the backend and refresh just that part of the application or was that a full page reload? No, yeah, we support there's a better way. We support web sockets and because you've got all of AWS at your fingertips you can use things like SNS or SQS for asynchronous events so you could listen to the database DynamoDB.
You could stream the response of a reader right to that database to a web socket and it could push the update into the client. The client doesn't even need to pull for it and that could be an upgrade. That doesn't even have to be the default experience the client JavaScript kicks in opens a web socket connection and your progressive enhancement is listening for these events to upgrade the experience. And I theoretically also could push HTML over that web socket as well.
Yeah, man. HTML style. All right. Yeah, I'm into it.
I'm feeling it. It's weird but it's a thing. Yeah, because if you have a pretty heavy dependency or a dependency that can't run in the client but it's needed to render that chat window it might make sense to just render that part on and that's big in the Ruby world big in the PHP world so it's kind of interesting we're starting to see it now in JavaScript world. Yeah, we're doing a little bit of it and HTML over the wire is the same thing it's JSON over the wire it's just text so inner HTML works great with text and yeah, it feels strange.
It feels like you're doing something you're not supposed to do but it works perfectly fine and is absolutely a valid technique. Yeah, the jQuery load function I'm pretty sure if I remember correctly the second argument to the jQuery load function was a selector meaning that you could load an entire HTML page and then it would return to you a subset of the DOM to let me select this piece. Yeah, why not? And I think whatever it is that gets the job done is valid.
All these tools are available to us and we can kind of count on the browsers being fairly good these days so it's neat watching the HTML thing take their whole thing is like turning formerly inert DOM elements into suddenly interactive DOM elements but you do it all declaratively which I really, really love and I think there's more to be explored here around declarative marking up attributes or using things like web components to add enhancements when the behavior is available. Yeah, it's an interesting world. What about like state management? I know that is like one of the biggest topics in React Land.
Yeah, this one comes up a lot so we tried to not have an opinion and then we realized that's like basically telling people to go ask themselves so we're forming opinions now so you can use a MobX or an X8 or whatever if you want on the client, that's fine. Our approach generally is get the thing working first with just HTML and then intercept that on submit on the form and start doing your JavaScript magic as a second step because it's going to be way easier than trying to decrypt how a state machine client side works to a backend. You'll end up with just the thing that only works with JavaScript and you'll end up with something honestly a lot more complicated so it seems more complicated to get the backend working without client JavaScript at first but it actually turns out that in most cases you won't need state management at all. We have a pattern on our blog where we get into how we would theoretically show you how you could do it using a service worker and it's pretty involved.
We've got to take it off the main thread because we don't want to involve awaits blocking the UI so we put it in a worker but we essentially listen for events and we use a thing called morph DOM to update the DOM based on stuff coming back but we will only do this after we get the form working first and for a lot of forms it doesn't matter. If your form submits and it reloads the page you're just happy you got that person's email and that person I guarantee you doesn't care and browsers are pretty fast networks are pretty fast in a lot of cases we're talking sub-second responses we're not talking three, four second wait times here so most of the time you don't need these tools and I would say try and build without them and reach for them only when things get so complex that you have to have a state machine on the client. We're working on some better examples that show what I'm talking about with WebSockets because we think that's probably the end game here usually you're submitting some value to some either API or database and then you want to respond to the client with some result of that and that result might be errors it might be problems that they need to fix a form you spell your name wrong or you use a character you can't use or you use a username that's not available because it's only available in the database that's a call that only the back end can make and so in these cases you may want to reach for a slightly more complicated thing but you really do want to get that back end working with the client first without any JavaScript if you can on the client. Is there any special sauce around form submissions?
So we built our website and we love form actions and I see React is starting to add that too how do you do a form then? Do you just create one thing we mentioned is you have file system based routing so you just make up a folder and you put a file in it and that's your route so you just make an API route? Yeah we have a concept of API routes they follow the same symmetry as the page routes and you can just put a form in your page and then you'll have an API route at whatever path that you want and then And you would export a function named post to respond to a post. And Bob's your uncle.
That will either return a redirect or JSON, depending on if it was called with XHR fetch. XHR being our good old friend XML HTTP request, which nobody uses anymore. But I still say sometimes when people look at me like I'm weird. So if you use it at XHR or fetch, we'll return a JSON payload.
But if you submit that form, just like regular HTML submit, it'll do a redirect instead. And the page will re-render with the state that it needs. And you don't need to do any rejigging. Yeah, that's kind of built in.
But there's some work for you to do there. We have a thing we call the problems loop. So there's some requirements for a good form. A good form is going to give people good feedback.
It's going to give them good errors. It's ideally going to give them good errors before they submit that form. So there's some client-side JavaScript involved. When you do submit that form, you better not lose the values that I entered that were good, especially the long form.
So if I have to fill out my address a second time, you're going to lose me as a customer. And if you want this form to be bulletproof, you want to work with our JavaScript enabled. And so in order to achieve all of these things, you have to use a session. And this can get a little tricky.
There's a bit of hard-to-parse ideas going on here. So when I submit the form, I want to do the validation on the back end. I have to do it on the back end. I can't validate on the client and not have back end validation or else someone could break our security.
And when that validation finishes occurring, if there's a problem, I want to return those in a session because we're going to redirect if that form is submitted without JavaScript. And I want those values to be populated. Tools like Rails build this in and enhance we have a set of components to build this in. So this pattern is just there for you to have.
And then at any time, you can intercept that on submit and redo it yourself on the client. But I find once you've built out a few of these bulletproof forms, you'll get to that client step and you'll be like, well, I don't really want to rebuild the whole thing. I just want to say, for example, do that username check before they submit or maybe a password strength thing. You don't want to submit a form if the password is like one character.
And those are great use cases for progressive enhancement on the client. And, yeah, you'll have a form that's probably sub-5 kilobytes of client JavaScript, which is a pretty good experience. Yeah, right, yeah. Does it enhance do anything for CSS or does it just say, hey, you offer your CSS as CSS and we use web components for scoping?
Is that the vibe? So we've got opinions. One of our opinions is utility CSS is pretty good. And we think if you're going to try and have this, if you want to avoid the ever-growing styles.css file and you want to use something like utility CSS, utility CSS will fall apart.
There are specific components specific to your infrastructure or your application that are going to need specific styles. And in those cases, we'd recommend just embedding a style tag in the component and write rawdog.css and it'll be scoped to that component. And then we have a utility system. People get really divided about this.
So you can bring Sass, you can bring Tailwind, you can write just raw CSS. Yeah. But we really, really, really think there are advantages to using a utility system and learning it. Our utility system is inspired by more tachyons than Tailwind.
And we do a fluid type style. So it's responsive, which is to say you don't need a bunch of breakpoints. It will scale up and down to mobile and desktop interfaces without having to rely too much on breakpoints. You'll still need breakpoints for some stuff.
Like we don't hide and show that sidebar menu, for example. But like for the text in the page and most of the components in the page, I mean, flex and grid are really, really good now. And fluid scales and CSS variables, I mean, come on, we are spoiled. So yeah, we found we don't need a lot of extra stuff there.
We bake in our sort of opinions and you can use them if you want to, but we absolutely recognize that people have their own opinions. So it's their own thing. And yeah, you can do whatever, basically. But we want to get better at explaining this fluid stuff.
I feel it's actually pretty important, but people aren't quite there yet. Yeah. I'm just rolling through all of your CSS file on begin.com and you can kind of get an idea of how it all works. It looks good.
It does actually get back to measuring, though. And just not to belabor it, but I think the ever-growing CSS problem still does even exist a little bit in Utility World where we've got build steps and it can be solved. You can have a file that doesn't get any bigger and support light mode and dark mode and multiple device sizes and fluid scales is the path. But it's another system and it's a new thing to learn.
So there's straight offs. It's worth measuring and looking at. And if you're finding that your design system is getting unruly, I think all paths point to components and fluid scale. Yeah.
Yeah. There's two things for us before RCSS will finally get into the heavy land is the contrast color function and the relative color syntax. You give me those two things and holy cow, RCSS files will get way smaller. There's so much.
There's a couple of problems right now and yeah, it will solve all of those. Yeah. I love that. Well, I'm going to take a deeper look at your CSS.
The layout stuff is so good these days. One trick that we're still trying to figure out is do we want layout components? Like remember back in the flash days, you had like VBox and HBox and stuff like, you know, grid, you can get that kind of feeling, but there is a, there is a bit of a barrier to entry there. And so we've been toying with the idea, should there be layout components?
Yeah. It did work well in Flex and it's kind of a cool way. We kind of do that on syntax on the new syntax site. We went hard on grid for everything.
So even vertically, the site's laid out with grid and name zones, gutters and columns and everything for just about everything within what are, we're just, they're just class-based components. It's just a class name, but you could say it was still a layout component. Totally. Yeah.
I think it's great. Like we're, we're in a weird spot right now where the state of the art of the browser has actually exceeded the state of the art of the practice. Yeah. And we're still learning what is all the, what are all these new tools meaning?
And like, yeah, they're coming fast and hard. Like WebKit is dropping new stuff every week. It feels like finally. And yeah, there's all sorts of cool stuff in Chrome.
Like view transitions are barely explored and offer, I think like a lot of functionality that we used to think was reserved for native apps. Yeah. I'm excited about that. That and a scroll driven animation is going to be pretty, we're going to, somebody on Twitter is saying how they're so, so happy that the, um, parallax websites are dead.
And I was like, buckle up. We're going to have another run of that. Yeah. Right after skeuomorphism comes back fully, we'll also get, yeah, parallax is coming back.
I'm here for it. Yep. Retro skeuomorphism. Weird, it does look retro though.
Yeah. It's like, oh wow. There was like stitching in that leather of the, oh yeah. I want to ask you quickly about AWS reInvent.
So that is Amazon's massive conference. Um, you went there. How was it? Why were you there?
I, well, I go, I've been going for a long time and, uh, I go now as an AWS serverless hero, which is their sort of developer community, embarrassing name for it, but awesome. Um, they, they spoil us and it's great. We kind of get sort of priority seating and all the keynotes and elbow our way into all the good parties, but it's, um, it's overwhelming. So there's between 60 and 70,000 people there.
They book out the Venetian MGM, the Bellagio, I think two or three other hotels, but I can't remember which ones I kind of don't leave the Venetian or the wind. That's the other one. And, uh, there are hundreds and hundreds of sessions a day. There are dozens and dozens of parties, uh, every night.
It is, um, almost overwhelming. So for, for me, I'm kind of in the serverless-y backend-y niche of Amazon. Amazon's huge. There's 400 services and it spans everything from, you know, databases to machine learning to servers to whatever.
So the serverless world and infrastructure's code world is kind of where my interests lie. And, um, yeah, I try and catch two or three sessions a day. I did a couple of talks and, uh, otherwise I hung out with cool people and watched the keynotes. I saw Chris Williams there, which was awesome.
I hadn't seen him in years, the old curator of JSConf. Yeah, he, uh, he's doing good. It was just a lot of fun. I didn't catch COVID, unbelievably, with all those people.
So get vaccinated and wear masks. It works. Um, yeah, and it was very Gen AI themed, which is a bit eye rolling, but also, um, where we're at right now as an industry, there's clearly a sea change happening. There's a lot of undiscovered country there and Amazon wants to own all the, you know, wheelbarrows and pickaxes for this new gold rush.
And so they're, they're things called bedrock. It's a, it's kind of a sprawling service for managing a large language models. And I'm going to add support in the form of a plugin to actually architect to begin and enhance soon. It's, um, it's pretty neat.
You can pick from different open source models out there, like cloud from Anthropic or Amazon's Titan. And, um, it does like, it does all the gross stuff. So it hosts the model and you can send it prompts and you can get the responses back to a Lambda function. You don't have to deal with clusters or keeping a server up or managing the models or the model versions there.
These things are coming so fast. So there's a new model every month and you want to change and swap them out and compare them. And you definitely don't want to build that infrastructure. And so for them, it's like, you know, you change one line of code, you get a different model under the hood.
You can train it with your own knowledge base. You can have it access your own databases with vector databases. So it can, it can do what are called rags, which is retrieval of information. Um, so you can make, you can make it smart and customize the agent for your own use.
But these things are so early and they're so unpredictable right now. That's got to be taken with a big spoon of salt. Like people, people are really excited and venture capitalists will basically fund anyone that can spell AI right now. And, um, it's not, I wish it was mine.
It wasn't mine. I stole that from Austin Collins from serverless framework, but, uh, to give attribution, but, um, yeah, it's a little heady. It's like, I'm there for the serverless stuff and it's almost now a boring technology. It used to be the racy thing.
You know, it used to be, oh, serverless, you guys are nuts. Now everyone's like, yeah, serverless. Yeah. That's what we do.
So yeah, it was cool. It's a, it's big. I recommend every developer check out at least once. Um, it's, it's, uh, there's nothing else like it.
And it's so weird because JavaScript in that world is a kind of a redheaded stepchild. It's not, not the thing. Most of the developers there are probably writing Python or Java. And, uh, I just, the scale of AWS is always amazing.
I remember when I, we were trying to do the transcriptions for this podcast and I, that was the first time I had seen the new version three of the API. And I was like, this thing is absolutely massive. There's so many, like the fact that they were able to get all the teams together and build this amazing TypeScript API. Like that's why we understand it's 95 megs, but it's unbelievable.
All the little niches that AWS has. They are unlike any other org. So they're, um, they don't coordinate. That's their secret.
And so like that SDK is a small team, a two pizza team. It really is. So every little service is a small team and they can only communicate with each other via APIs. And that's why we see so many different takes on APIs with different kind of flavors of payload and the result of that is a lack of consistency and the confusing developer experience.
But the benefit of that is they get this huge amount of scale and velocity. I think they move as fast as a startup, but they are massive. That facilitates startups like ours where we can create like kind of a sanity layer on top and make things a little more sensible and easier to digest. And I think I checked for us, we use something like 30 services total.
So like less than 10% of all of AWS. And there's something for everyone there. And a lot of it isn't for me. And that's okay.
Like, you know, they've got, you know, traditional databases like Postgres and RDS and Aurora. And like, I'm all in on DynamoDB these days and I like it a lot. And like, that's fine. And like, you know, some people don't like that and I get it.
That's cool. Don't use it. So they're just trying to capture everyone. And that's what Begin CLI is, right?
Like last time you were on here, Begin was a way to interface and host your applications. Is it still that or has it sort of changed? No, it's still that. Yeah, still doing its thing.
Still stable. Build serverless apps. We originally were kind of more architect focused these days. We're, you know, using Enhanced as your way of getting a site online.
But yeah, within a minute and a half, you can have a URL. Within another five, you can have your own domain. And that's all running on our Amazon. And if you upgrade to our pro tier, you can run it on your own Amazon account, which is kind of unique.
I think the only other people doing that would be like flight control. He's got the same vibe. I think at the enterprise level, that's what they want to see bigger companies like HashiCorp who do Terraform. You know, they don't host anything.
People host their own Amazon, but they use Terraform to deploy to Amazon and keep it under control. Any thoughts on last time, you know, it was early days and now Dino is much more stable. We've got Bun, several other frameworks. Any thoughts on all these new jobs for front times?
I feel like they really validated Node, which I actually wasn't expecting. Node was feeling stagnant and it lit a bit of a fire under Node to get unstagnant. And in the meantime, they're all chasing Node compatibility. So they kind of just ratified Node as the standard, which is great.
I still hack around on Dino. I didn't like Bun personally a lot. It didn't work on Amazon Linux and they were not super receptive to that idea. So I was like, whatever.
That's where I run my workload. So not for me. And that's okay. Yeah, I actually have been falling back in love with Node lately because of all these things.
They sort of made it better. Like Node's built in test runners. Really nice. And like .EMV support.
All the little things. We just had Yagitz on. He is working on config files for Node. So you don't have a million flags in your package JSON.
Yeah. So yeah. And he said they are very close to having TypeScript support via a loader as well, which is pretty nifty. We're goofing around with those loaders, doing some weird stuff with import maps, loading some things client, some things server, sharing validation logic.
And yeah, it's promising. The ESM thing was a real speed bump. But I feel like we've got the tire back on the car and it's driving down the road now. And there was a minute there where it was like, oh my God, this is so painful.
But they really turned a corner. Cool. Was there anything that we missed, Brian, that you wanted to cover? No, I mean, this was awesome.
I really appreciate you guys having me back and letting me share my heresy in the build. Yeah, it's been great. Give Enhanced.deb a try. Okay, shoot me a, follow me on Mastodon.
I'm trying to get off this Twitter habit. It's a hard one to kick up. It's actually harder than that. I quit smoking and I can't get off Twitter.
It's weird. Oh yeah. What about threads? I was noticing like, my threads is popping.
Anytime I post anything on threads, it does super well. I feel like, everyone's like, oh, threads is going to die out. I think it's finally, it's past that initial curve. Obviously, it's Zuck at the helm there.
But yeah, Instagram really wants me to use it, but I'm holding back. It's so ad heavy, or at least Insta's so ad heavy that I'm even kind of fading there. And the ads are not good, which is kind of the problem for me. It's like, if the ads were actually like, oh, maybe I want that plaid shirt.
No, that's weird things that I do not want. Yeah, I'm avoiding that one too. I've been enjoying Mastodon for what it's worth. And weirdly, LinkedIn is starting to do super well for me too.
I've been making fun of LinkedIn for years. And now I post stuff and it gets like, like legit engagement. Like people, actual nice comments and people are having good conversations. So I was surprised.
Yeah, and it's civil because of the nature of it. Yeah, apparently civil, yeah. I know we started making LinkedIn a priority for syntax to post our things, to increase our footprint there. And it's like, I think at first people were like, why are you doing that?
Well, people are coming back. Yeah. I had the same thing where I was like, I don't know, but then, yeah, I'm finding it to be pretty okay. Yeah, absolutely.
Do you have a sick pick for us today? Oh my God, yeah, I do. actually i'll just say analog pocket oh cool um i got one and uh i've been replaying uh minish cap zelda like a game boy it's like it is all game boys and it plays the carts so if you have old like game boy advance or game boy color or original game boy but it also lets you load roms so you can do that too does it have emulators baked in or are you you gotta do a little install dance yeah it's it's easy and yeah i have every super nintendo game every it's pretty fun um totally recommend if you're into retro gaming at all remy sharp sent me a game boy and i got into it and i was like these are so fun and then the algorithm did find me on this one i don't remember where and i was like you might be interested in this oh yeah i'm interested in that yeah and yeah i got one and it's super fun just like to pick up and play like old games that you played when you were a kid or perhaps prior to your birth yeah yeah my son who's six he has recently uh picked up his mom's old game boy and uh now he's playing pac-man on the game boy and he's like this is incredible like yeah game boys pretty dope man they are yeah so that's my sick pick that's a sick pick i had no idea this was a thing 219 bucks that seems pretty reasonable given that every game is free and your old parts will work that's like the even cooler part so like i dug up my cards and i've got all the old zeldas and yeah it's super fun and the screen on that thing is it's great like stuff looks really good nice for gen z's listening carts are um cartridges not vape products yes you cannot vape you cannot vape a mario game awesome and shameless plugs what would you like to plug oh well uh please check out begin.com um deploy not uh using enhance.dev and uh hit me up on one of those socials and tell me how it went sick also try and integrate with century yeah he's doing it for us that's amazing i know but i actually really i think that's a great product i think it's a necessary step for a production app you got to have observability in the systems to make them better so yeah people should check out century it's a good call yeah we feel that way too all right thanks again head on over to syntax.fm for a full archive of all of our shows and don't forget to subscribe in your podcast player or drop a review if you like this show