JS Party – Episode #215
Remix helps bridge the network chasm
featuring Kent C. Dodds
Kent and our panelists dive deep on the hottest new React framework: Remix. What it does today, what makes it special, how it lured Kent away from a lucrative independent teaching career, and what’s coming up next.
Raygun – Never miss another mission-critical issue again — Raygun Alerting is now available for Crash Reporting and Real User Monitoring, to make sure you are quickly notified of the errors, crashes, and front-end performance issues that matter most to you and your business. Set thresholds for your alert based on an increase in error count, a spike in load time, or new issues introduced in the latest deployment. Start your free 14-day trial at Raygun.com
SignalWire – Build what’s next in communications with video, voice, and messaging APIs powered by elastic cloud infrastructure. Try it today at signalwire.com/video and mention “JS Party” to receive an extra 5,000 video minutes.
Sourcegraph – Move fast, even in big codebases. Sourcegraph is universal code search for every developer and team. Easily search across all the code that matters to you and your organization: find example code, explore and read code, debug issues, and more. Head to info.sourcegraph.com/changelog and click the button “Try Sourcegraph now” to get started.
Notes & Links
Click here to listen along while you enjoy the transcript. 🎧
It’s going well, how are you?
Doing as well as can be expected in the world today. And Divya. Good to see you. It’s been a while.
Hey! Good to be back.
Good to have you. We are also joined by the one, the only, Kent C. Dodds. Kent, how’s it going?
Wow, thank you! It’s going pretty well. Thank you very much for having me on the show. I appreciate the opportunity.
Yeah, we are excited to talk with you, Kent. But before we do, we’d actually like to stop for a moment and acknowledge a little bit of what is going on in the world. We are recording this on February 24th, less than 24 hours from when Russia launched an invasion into the Ukraine. And we’re gonna try to escape for a little bit today, talk about technology, have fun, not think about the world, but we also know that our brothers and sisters in Ukraine can’t do that at this moment, and we want to take a quick moment of silence in solidarity with the people of Ukraine.
Yeah, wow. I mean, I can talk about this for an extended period of time, so I will chunk it up and start with how I got involved, or kind of the origin stories of Remix. So when the pandemic hit in March 2020 - or hit at least most of us in the U.S. - it really destroyed the React training business that Ryan Florence and Michael Jackson were running, because they were really focused on in-person training, and pretty much all companies had to stop that. So they had to lay off their employees, and it was a really bad time for their company, and they were figuring out, “Okay, so what are we gonna do next?” And for years, they’ve always wanted to take React Router to the next logical step and actually have a framework out of React Router. So they decided to go ahead and try that.
Actually, you know what - I think Ryan was initially building a website for something else that he was kind of experimenting with; I can’t remember exactly… So as he was building that, he kind of naturally started building this framework. He started to really like it, and he showed it to me, and of course showed it to Michael, and we were all really supportive. Michael started helping him with it, and they kind of pivoted to making software, and they thought, “Hey, how about we write software and get paid for it? That’s a novel idea…”
So they started to work on this, and that was like in April. And they kept showing me little demos of what they had, and then they started posting videos and stuff on YouTube of some of the unique characteristics of Remix. This is very early days, before they even had a mutations solution, and stuff. It was all just like getting data and showing it on the page. And of course, you could do your regular mutations the way you always did, but before the really nice APIs that they have now.
So ultimately, at the end of October they decided to release it as a developer preview beta of the software, and you had to buy a license. So a lot of people took huge issue with that, like “Oh, what the heck? I’m so used to not paying for stuff that people do for me.” And I was so eager to give them my money and use it. So that’s kind of the initial story. And they were still – it was in heavy development. It was just Ryan and Michael. I provided feedback. Ryan did say that Remix would have made some really big mistakes if I hadn’t provided the feedback that I did, so that makes me feel pretty good… [laughs] But I was pretty active in providing feedback.
Then ultimately, I decided I needed to revamp my website, give it a redesign and everything, and so I decided to use Remix because I was really dissatisfied with Gatsby, for a number of reasons that we can talk about later… And I was just blown away by what Remix enabled me to do, that I never would have felt like I had the time or expertise to do before. So I rebuilt my site in Remix, I couldn’t stop talking about it… Anybody who followed me last year on Twitter was just like “Shut up about Remix.” I’m always talking about Remix and how great it is… And a lot of people were like “Stop talking about it. It costs money. That’s stupid.” And I was like, “No, this is great. I think that it’s awesome that users of this software actually contribute back into the software financially, so it gets better… Whereas open source software, the more people who are using it, the bigger burden there is on the maintainers.” So I really liked that aspect.
[08:15] Ultimately, they decided that they could make a bigger impact on the world by being free and open source. So they got three million in funding, and hired a team, and decided to take it open source. And right two weeks before they went open source, I decided that I loved Remix so much that all I wanted to do was teach Remix… And talking with them, we decided that it would be better for everybody if I joined Remix. So I joined Remix, I left my gainful unemployment as a full-time educator to help people build better websites with Remix. So that’s where I am now.
So there are a lot of things to unpack there, to highlight. Ali or Divya, anything standing out to you that you wanna dig into first?
I’ll jump in. This is more of a career question than anything, but I’m really interested what made you make the decision to go from very successful teaching by yourself, which I think is a lot of people’s dream, to working for a company again?
So what I was starting to realize was like “I just don’t wanna do those things. I just wanna teach Remix. All I wanna do is teach people Remix.” And sure, I’m not gonna be able to update things like I was planning on… And I told people that I was planning on doing that. I always made it a point, it’s a plan and not a promise. Those are two different things. They did not buy updates. But I felt kind of compelled that I needed to do that, but I just really wanted to teach Remix.
So joining up with the Remix team offered me a couple of things. For one, it gave me a really easy excuse to say that I’m not gonna update the old stuff, because now I’m 100% on Remix, from like a title perspective. But then also, it gave me something that I never had before as an educator, and that is I can teach from inside the house. And what I mean by that - I’ve always been teaching React, I’ve been teaching Jest, Cypress - all sorts of technologies. And some that I’d created, like React Testing Library, and others where I guess I was inside the house there. But teaching from outside, you have to establish your credibility… I definitely have taken some stands against what the core team recommended. All of Testing Library was a big stance against what the React team and everybody else was recommending. So I’m not afraid to take a stance against it, but it is exhausting, and it would be much easier to not have to establish that credibility and just have it. And of course, I need to be credible, but to not have to argue with the people who say “Well, the React team says this”, and like “Well, in my experience, this…”
[12:09] So being inside of Remix and being the one responsible for teaching people Remix was really, I guess, compelling. So far, I am super, super-thrilled with the decision that I made. Like I said, all I wanted to do was teach people Remix, and now I get to do exactly that. And then I also get a direct say on what the company does and what we focus our attention on. They brought me on with enough of the company to be a co-founder, and so I am a part of all of the company decisions, which I really like as well.
So yeah, so far I’m pretty happy with that change. But I was totally nervous. I was like “Oh my gosh, I could do anything that I want to, and now I have co-founders to answer to, and employees that are looking to me, that rely on me to get stuff done…” But so far it has been really awesome.
Yeah, that is a very apt comparison. A lot of people are comparing Remix to Next. First, I wanna make it clear that we’re not after your Next.js apps. If you like Next.js, stick with it. We’re really focused on being an upgrade from React Router. So for us, if you’re using Next and you’re happy with it, feel free to stick with it. But so many people have asked us this question… It’s just such a common question. I will reference this blog post that we did a really deep dive on Remix vs. Next. Basically, we took the Next.js e-commerce demo, which is like “Here’s how you build an app with Next. We built it ourselves, so this is exactly how we envision people using Next.” And only if you think that you’re better than the Next team could you build something better, I suppose…
So we took that app and we did two things. First, we did a migration to Remix with that app; so we changed as little as possible, and just migrated it to Remix. And then we completely rewrote it from Scratch with Remix, and then compared all three apps using webpagetest.org. Webpagetest.org gives you like a real-world experience; you can control what device, and where in the world, and all of that stuff.
So this blog post goes really in-depth with the comparison between Next and Remix. It’s too nuanced to just give you a two-sentence answer, so I’m gonna just reference that. But the TL;DR is Remix is as fast or faster than next at serving static content, even though it’s server-rendered. That should say volumes. So hopefully that encourages people to take a look at that, because it’s pretty in-depth. But yeah, there you go.
Yeah, that’s cool. We’ll just have to add that to the show notes. I just pulled it up and it’s really very thorough, so… Yeah.
I think in our next segment we can dive a lot deeper into exactly what Remix does and doesn’t do for you. But quick question before we go there around the page versus open source question. I think there’s a lot of discussion about how can you make open source more sustainable, the challenges of maintaining especially a popular project, things like that… But there are also reasons that folks love open source. So I’m kind of curious, is there a company line about why you should still use Remix, even if you’re mostly using open source, or why it’s worth paying for it?
Well, like I said, it went open source in November.
[16:01] Ryan and Michael decided back in August/September timeframe to start talking to VCs, and VCs were like “Yeah, we’re totally into this. We want you to go open source, and then we can figure out services and things that you can sell to make this sustainable.” And we’re already working on some of those things.
So Remix is not going away. I wouldn’t have joined the company if I thought that Remix couldn’t be successful as an open source project as well. So if you take stock in my decision, then at least that speaks something, at least.
So we’re planning on – basically, our goal is we wanna help people build better websites, and insofar as we can do that with open source stuff, we will do that. And there are certainly some services and things that you need as you’re building a website, unless you wanna deploy your own version of these different services and manage all of that… Which most people don’t; they just wanna get their site up. So we’re gonna be building these services that people can use to deploy their apps. That’s how we’re planning on making money. But right now, we’re just really focused on getting adoption, and helping people be successful in using what is a relatively new(er) framework.
It’s kind of the Gatsby model of “We’re gonna open source the framework, we’re gonna provide a bunch of framework-specific services…”
With a completely different framework, but yeah.
Well, if we have time later, we can talk about how you dodged some of the pitfalls they fell into, and other things… But I’d love to maybe take a break and then get into the meat of what Remix is and what it does for you.
Alright, let’s hop back into Remix. What is it? What does it do for you? You mentioned that you envision it as an upgrade to React Router, though as I was digging in, it looks like there’s a whole lot more than that… So how would you describe the different pieces of Remix and what it does for you as a developer?
Yeah. Well, the router is actually one of the things that differentiates Remix quite a bit. And what’s really cool is that we’ll be able to move a lot of what makes Remix special into the router, so people will be able to just upgrade the router and get a lot of really awesome features. I think the primary differentiator between Remix and everything that’s out there, on both sides of the network chasm, frontend and backend – because frontend isn’t the only world that’s trying to solve the web problems; you’ve got Rails, and you’ve got Django, and you’ve got Laravelle, and everything… What really differentiates Remix amongst all of those is what we do about the network chasm. Like, you just communicate across HTTP, are you shooting grappling hooks across this huge cliff, trying to get to the other side of that network? And managing that is a source of a lot of bugs.
[20:29] So if you want to have an accessible app, that feels really snappy, you’ve gotta have a rich client. I’m not afraid to say that hey.com, at least in my experience, was not great at all. It was a really slow user experience, pretty buggy… And granted, I used it a month after it came out, so maybe that was a little early, but there are some serious shortcomings when you’re using primarily a backend technology and just trying to shoot a couple of grappling hooks over that network chasm. It is a hard problem.
And then on the other side, you’ve got frameworks that are primarily client-side, and they also have a lot of problems. You start talking about “Well, I don’t wanna wait forever for my framework to download, so I’m gonna prerender a bunch of stuff”, but now what you prerender is a bunch of loading states to your user, and so all of a sudden your Chase.com banking website has got like 13 spinners to load all of your stuff. Or you go to your power company and they’ve got like – on my power company they’ve got cool little windmills and stuff like that… You know, for power generation; like “We’re the future”, and everything. Like, that’s fun and all, but I wanna see my actual site.
So on both sides of this network chasm you’ve got some serious problems, whether it be the initial load time, or that experience once you get the user there. Remix, what really differentiates it, is it builds a solid bridge across the network chasm, where you can have the power of a backend framework and super, super-fast loading times, but also the power of a frontend framework that interacts with that network really efficiently. So from the developer experience point of view you don’t have a state management library. There’s no global state management to speak of at all when you’re using a Remix app, or developing a Remix app.
So the question of like “Does Redux work with Remix?” Well, yeah, it does, but why would you do that? You don’t need it. And the same with GraphQL - yeah, you totally can use GraphQL, but you’re gonna use it on the backend, with the backend portion of your code. The frontend doesn’t need to bother with shipping that enormous GraphQL client. So with Remix we take a lot of stuff that people are doing on the frontend and we’re moving it toward the backend, and so we ship less code, because Remix is managing that network chasm for you, rather than you having to bring in a bunch of libraries to try and piece together that.
I guess I should say, Remix is a web framework, not a React framework. It’s a web framework that is focused on an excellent user experience and web fundamentals. So where a lot of other frameworks try to use the web platform and wrap different APIs and give you maybe a nicer API, or what they might think is a nicer API. Remix actually takes a step back and exposes those Web APIs for you, and leverages the platform unlike anything else. And there’s so many things to say about this, but I’m gonna go ahead and stop. There are a lot more things that I could talk about, like how we use the platform especially, and how we normalize different deployment targets, and stuff… But I’m gonna stop there, because I could just never stop talking.
I think it’s really interesting that you brought up the chasm between what we talk about generally between client and server-side applications, because I feel like it’s really interesting to see the industry sort of bounce backward. Everything at one point was server-side rendered, and then we complained about how slow that was, which made us move towards something that was very JAMStacky, with fully client-side, like, load everything on, and then – load static pages, basically, so everything is pre-built… But then there were complaints around that, because it takes a long time for things to build… If you make any changes, you need to rebuild the entire thing… And then now we see this movement back with Remix and Next towards more server-side, or kind of leaning towards servers. I have opinions around that, but I’m actually curious around yours regarding that shift and what is propelling that.
[24:34] Yeah, yeah. I think that you can’t just have solid footing on either side of that and provide great user experience. You have to be on both. And modern infrastructure has made it so that it’s actually relatively simple to deploy servers. So you don’t have to manage servers; even long-time running servers as well. I’m not just talking serverless. You could totally use serverless or Cloudflare Workers, and stuff; they have a lot of things going for them. But even if you want to deploy a long-running server or process, Fly.io I use for my website, and Remix uses for its website, and I love it. It’s awesome. I deploy my site to six regions all over the world, Remix deploys its site to (I think) twelve… So it’s fast everywhere. We get all of the benefits to a long-running server process. We don’t have to make all the trade-offs with the serverless. But that said, serverless is also awesome. I’m really impressed by Cloudflare Workers.
So the fact is that you can’t have as excellent a user experience if you’re just gonna be building static files and putting them on a CDN. Now, if your site is truly static and every single user has the exact same experience on every single page, then that sort of site is a little less interesting to me, but those sites do exist. And CDNs also exist, and they understand shared cache headers, and you could totally have your server be your build server, basically. So if you use cache headers properly, you can get all of the same benefits of static site generation. And what’s really cool about that is if you decide “Hey, you know what - my site is 100% static. It’s just a blog. Every user gets the same experience” - that’s great. You can still build with Remix, and then you set up the right shared cache headers, put Cloudflare in front, or something, and then your origin server isn’t being hit. Anytime you do an update to a blog post, you tell the CDN, “Hey, blow away that cache”, and it will hit your origin server again and then cache it again. And then, what’s great about this approach his if you decide, “Hey, you know what - I wanna do some blog recommendations, or something. I wanna do something dynamic. I wanna have workshops and I wanna show what tickets are available, or whatever.” Then you don’t have to go straight to a loading spinner for all of your users. That’s what I did when I was on Gatsby. I was like, “I wanna have workshops, and I wanna schedule some workshops, and I’ve got tickets, and whatever”, I have to show them a loading spinner, because I’m using Gatsby. Or you could rebuild every time somebody buys a ticket, which - when it’s cached, it takes ten minutes or fifteen minutes to do that, so that’s not a great experience…
So if you just start with Remix and then set up cache headers for the static pages, and then you later decide “You know what - I don’t wanna cache this. I want every user to have a unique experience”, then you don’t have to rearchitect your entire site. So where Next will say “We like to give people the choice to choose SSR or SSG”, if you choose SSG, even with the same framework and you wanna switch to SSR later, you have to completely rearchitect that page. And that’s not the only thing that makes Remix compelling from a developer experience standpoint, but that’s one thing that we’re just like – like, the web has been doing this for a really long time, and so if you just leverage the web platform as it was established, then you can kind of change the nuance of how your site is being served to your users without rearchitecting how you built it. So yeah, I like servers… [laughs] And I like Fly, because it means I don’t have to manage servers myself.
[28:08] Yeah, it’s actually really nice to see a lot of the infrastructure sort of support that, and just the fact that now you don’t have to worry about having to scale yourself. I think the whole – at least for me, when I was getting really jazzed about client-side and fully-static was because I was just like “Oh, you could just basically load it in multiple regions really easily”, instead of having to basically provision a bunch of servers, which generally are very location-dependent and not as distributed… But now there’s a lot of infrastructure that supports that kind of multi-region servers. And Fly.io, as you mentioned, is one of them where it’s just really easy for you to do, it scales quickly, you don’t have to do a lot of the work and heavylifting… And the nice side is that - yeah, if you want something like serverless functions or whatever, you kind of don’t run into those issues in the past, with serverless functions, where it’s just like sometimes it’s slow, you have cold start, and just like all these problems that come with that, because it’s just like “Okay, your static assets are here, but in order for your serverless function to run, it has to go all the way to this other server, which is somewhere else, and so you get latency, which adds extra time to load… Which are added problems that I think we sort of gloss over when we’re just like “Static is great!”
I like your argument, which is just that there’s a balance… Because I’ve often seen, and I think I’ve seen you rant about it on Twitter as well, just the whole – like, there tends to be camps where people are like “I only want a server-side rendered” or “I only want client-side rendered stuff”, and it’s just like… As you mentioned, the platform, in a way, is this – it supports both really nicely, and being able to leverage that is fantastic.
And Remix is really well positioned to do that, in large part thanks to its ability to – we can deploy anywhere, so whether you wanna do a long-running server, or a serverless function, or a Cloudflare Worker - which is kind of like a serverless function, just in more places… And that’s actually really interesting, to be like “I don’t wanna have to choose a single region for my app, or my data, or anything. So I can deploy it all over.” But then the other thing that makes Remix really especially well-positioned for this is nested routing, which is a really unique feature of Remix as well.
Can we dig into that a little bit? When I was looking at the docs for it, it reminded me a lot of Ember.js’ approach to routing. Is it more or less the same concept, or is there something different? How does it work? And I guess maybe explain how it works regardless, because the React world may not be familiar with the Ember approach, even if it is the same.
Yeah. Well, you’re talking about me, because I never used Ember. Michael and Ryan - well, Ryan especially - was really big into the Ember community, and I believe that he took a lot of cues from the Ember router. So nested routing is a feature of React Router v6. So if you’re using React Router, upgrade to v6 and you’ll get a lot of really awesome benefits. Basically, a lot of people listening are probably familiar with Gatsby and Next, who have a very similar file-based nested routing. And it’s not a true nested routing, and there’s a very important difference.
So the way that nested routing from a file standpoint works in Next and Gatsby is you have your pages directory, and then you have your folder structure that maps directly to the URL. And so let’s say that you have an event, and so you’re at mysite.com/events/eventid, or something. So in the file system, that would be pages/event/ I can’t remember – each one of them do their own params thing… But the event ID .tsx, or whatever. So when you’re in that module, you’re gonna export a component that is responsible for the entire page when that route is active. So that means that when you’re working on the UI for when a user is looking at a specific event, you’re not just worried about the UI for this specific event, you’re also worried about the listing of all events on the left side; and you’re worried about the header, and you’re worried about the footer, and all of this extra stuff that is kind of outside of the scope of this specific area of the app that this route is responsible for. And that has some big implications.
[32:23] This is why layout components are a thing. Pretty much every Gatsby and Next app has a component called layout, maybe a couple components if you have multiple different sorts of layouts… And those layout components need to have props for different data that they’re responsible for; so now you’re also responsible for going and getting the initial data for those. Or it’s easier if the layout is just responsible for fetching the data when it’s rendered; so you just put a loading spinner in there. And it’s easier for you, but worse for the user. I call static site generation “spinner site generation.” [laughs] Because it’s very natural to do that. It’s easier as a developer.
When you have true nested routing though, your file system is basically the same concept. You have folders, and stuff, it all maps to the URL, but the component that you’re working on is only responsible for the area of the page that changes from route to route. So if I’m on my event details page, then that module, the component module that is exporting - it’s just responsible for rendering the event details. It doesn’t care about the header, it doesn’t care about the footer, it doesn’t care about the left nav, or whatever, any of that stuff. It’s only caring about that area of the UI that it’s responsible for. And that also has to do with data. And that route module also has a loader which is only run on the server, to go and get the data. And because it’s only run on the server, and Remix will call it if the user is navigating - so we do support client-side navigation; we don’t server-render every page. So Remix will make sure that we call that, whether we’re server-rendering or if we’re client-transitioning… And so it only runs on the server, you can use your private keys in there, you can connect to the database in there, you can do whatever you want to in there, because it only runs in the server. Oh, and by the way, you can use your GraphQL in there and you don’t have to ship the GraphQL client to the browser, because it’s all just on the server.
I guess that also makes error handling really nice, because then you’re not failing an entire page if parts of the page fail.
[35:52] Yes! Divya, you get it! This is so big. So React has had this concept of error boundaries for a really long time. It’s kind of like a try-catch in your JSX, sort of. So that’s awesome. Unfortunately, React does not support error boundaries in server rendering. So if you’re landing on a page and one of your components blows up, then the entire page is gone. So what we typically do is we’ll try to render the header and the footer, and we’ll put a little koala in the middle of the page, with a tear running down its face, and be like “Sorry, something broke.” But with Remix, we make error boundaries work on the server. And not only that, but they also handle errors that happen in your loader as well. So if you have any problems loading data, like maybe you’ve got some bad data and you call a property that doesn’t exist, or something - we will handle that in your error boundary, and it’s all contextual. So if you’ve got a particular event that’s busted, bad data, the user can use the rest of the app. And that’s huge. It even has business implications, because instead of users say “Hey, the app is busted”, they say “Hey, this event is broken. I can use all the other events, it’s fine, but this event is busted.” So that has huge implications as well.
I have a question about something you kind of alluded to there. So I love nested routing; it’s a beautiful abstraction, generally. I’ve always been sad that Ember take there hadn’t picked up more widely… But one of the challenges you can run into there is the data cascade, because you have many different queries that need to run for each of these different components. And even though they may not be dependent on each other, they can get serialized in different ways. And I know that Facebook built out all this tooling for coalescing up their GraphQL requests; we use something similar - though it’s a little more manual - where I work… But I’m curious, does Remix handle this for you? Does it give you a way to coalesce all of those different components at different layers of the route, their data requests, and run it as a single request?
Yeah, yeah. So we don’t run it necessarily as a single request. I mean, on a client transition I think we do… But we run them all in parallel. So every one of your route modules can export a loader, and when a user navigates to a different page, or if they just land on a page, then we run everything in parallel. So you cannot access your parent loader data, because if we allowed you to do that, then we would run into this data cascade, which is not good at all.
So yeah, every single loader runs in parallel. We do not have this problem… And I guess I’ll fill in the silence and talk about forms. [laughs] So loading data is an interesting thing, but making changes to data is what really makes the difference between a website and a web app. I mean, the distinction between a website and a web app is kind of silly anyway, but a lot of people will, I guess, say that; I don’t know, I don’t care what the difference is. You can build web apps with Remix, you can build websites… I don’t care. But mutating data is often the missing piece in most frameworks. Most frameworks are like, “Yeah, okay, we have a really nice API for loading the data. Oh, but you’re gonna change something? You’re on your own. You’ve gotta figure out how to update the data when you make a change”, or whatever. So we’ll bring in these different libraries that know nothing about your routes, and you have to wire everything together.
So Remix says “No. That’s a very important part of the web. Since Web 1.0 we had forms for mutating data, and we’re gonna do that again.” So Remix gives you a really nice API for data mutations that is just a form. And when you load data, you use your loader; when you mutate data, it uses your action. So you have this form, it automatically posts to the route that you’re currently on, and so just like with the loader, when you’re writing your component, you’re like “Oh, I need more data. I’ll just scroll up the file to my loader, make some changes on the server-side”, and then boom, I can use it. If you’re writing a form, you can just scroll up to your action function, and now you can handle what happens when a user submits a form. And this, again, only runs on the server, so you can do all your validation logic there, and whatever; you can share validation logic if you want to… So if you wanna run some validation logic on the client, you just literally take the validation logic, put it in the function and use it in both places. Like, in the same file. So it’s pretty straightforward to do that.
And also, when the server finally does respond, the browser is going to render whatever HTML the server responded with, or if the server is doing things right, they’re gonna redirect the user somewhere else, so they can go and get that. So what that effectively is - we say hey, all of the data on the page is completely up to date, because we just barely got it all from the server. Remix does the same thing. By default, when you make a mutation, Remix says “Who knows what changed on the server?” Nobody knows. Not even the developer sometimes. “So we’re just gonna go refetch everything.” So what this means is by default you never have to think about keeping state up to date. You don’t have to worry about application state at all. That’s why I said you don’t need Redux, or anything like that, because as soon as the user makes a mutation, Remix will go ahead and update all of the state that’s on the page.
I think it also highlights a really important point which you’ve just mentioned, which is - they use the platform piece, which also helps remove any obfuscation around writing data to the server. I’ve worked with a lot of different frameworks before, and forms are generally the one that cause a lot of trip-ups, because… Like, mutations is not just about new data, it’s about how the original data is changing. There’s so much logic that you end up writing, at least in state management systems, where you’re checking to see how the data changes… Because one, you might want to – for instance, with forms there are instances where you wanna show how the data is changing… Like, “Oh, I’m incrementing, so I wanna show it as green, or I’m decrementing, and I wanna show it as red”, or whatever. So there’s a lot of nuance there that tends to get added, and a lot of logic that gets added that makes it really complex. And then you also have to deal with the other piece, which is not just that, but also the specific actions that you want to happen. So using the platform, as you mentioned, it’s just get and post. It’s fairly straightforward. [laughs]
[44:06] Versus in state management systems you’re like “Okay, if the data changes this way, I want it to be a put. If it changes in this way, I want it to be a delete”, or whatever. So you’re constantly just like writing to different routes, which adds to the confusion, at least for someone who’s newer or someone who’s unfamiliar with the framework. So it’s really cool that this works off of knowledge, or at least fundamentals that is across – it’s just the web, basically.
Yeah, yeah. And you know what - what you’re describing is there are lots of ways to do this if you’re not gonna do it the web way. So when you come into a codebase where multiple developers have been working, you have to get into the mind of the developer who built it to figure out what they were thinking. Like, what’s their mental model for how this is updated. And that is not great for a team. So it’s way better to come to an agreement on the mental model for how we do mutations, and let’s just use the web as a model for that, and everything else branches off of that.
So wherever you go in a Remix app, you know exactly what the developer was thinking when they built that mutation story, because it’s just the web. And on top of that, if you are working with Remix for a long time and then you move on to a new project that’s not using Remix, you can carry all of that knowledge with you, because you’re still on the web. So the transferable knowledge that you build with Remix can’t be overstated. That benefit is huge
Well, it’s interesting, because when we’re talking about form validation, we’re basically talking about taking what the user gave us and making sure that it’s correct; so like that this is an email, or that it has a certain length, or whatever… And you can 100% use the HTML attributes for all of that stuff. That is awesome. But you can’t just rely on client-side validation. We all know this. So you have to think about “Okay, so what about the backend?” And because your action runs just on the server, then you can write all your validation logic right in there. So within your action, you say “Get whatever the user inputted as the email, and just make sure it has an @ symbol on it, and something before the @ and something after the @.” That’s as much as you wanna do with email validation. Or make sure their password is X number of characters long. And if it’s not, then you return errors, and right in your component you have access to what those errors are and you can display those. So that’s as much of an abstraction that Remix gives out of the box. And for 90% of the use cases, that’s enough. So it’s possible we could offer more…
And one thing that we talk about a lot with Remix is that we’re center-stack. We don’t wanna be backend, or frontend, or whatever… And full-stack is interesting, but a lot of people take issue with that, because we don’t have like an email package, or something like that. But we focus on center-stack, which is unique. That chasm is real, and it causes a lot of problems. So by focusing on solidifying that bridge across the chasm, we can slowly eat into both the frontend and the backend, and we do plan on building more things for frontend stuff, as well as backend stuff. So eventually, we’ll start eating into both sides of this, and potentially having some other abstractions for form validation as possible… But we don’t have anything on the table right now, because what we have is pretty dang good.
[48:12] And primarily, we just focus on the web platform APIs. We do expose the form body object that you get when a user submits a form, and stuff… So we can give quite a bit of – I mean, the web platform gives us a lot just out of the box.
I’d love to talk in the next section about what’s upcoming, but before we do, I noticed - we’ve been talking a lot, and Ali, you’ve been there, listening. What’s standing out to you? Do you have any thoughts or questions for Kent?
Well, it sounds awesome, and I’ve played around a little bit with Remix, but haven’t gotten as deep as I want to. What would be your recommended resources for getting started?
So because I am full-time on Remix, if you don’t have a good experience with Remix, it’s my fault. Or at least my responsibility to make better. Right before we launched the 1.0, I’ve put a lot of effort into a really awesome Getting Started guide, or a deep-dive… So Ryan, also an educator - he put together the Quick Start. So that should be like a half-hour experience, exposing you to the concept of loaders, and actions, and forms, and stuff like that. And then I put together a deep-dive that goes really deep on how to hand-roll your own authentication, and how to get a Postgres – or I think we use SQLite with Prisma, so you can swap it for Postgres. And how to get all of that database stuff set up. How to build an Optimistic UI experience with Remix, which by the way, is really great; the Optimistic UI story for Remix is awesome.
So yeah, it gets really in-depth, it’s basically like two workshops, maybe three worth of material, and that would be the best way to get started. Do the Quick Start, and then if you really wanna dive deep, then do the deep dive. Oh, and actually, I should mention also - we have a really active Discord community. So if you do wanna get into Remix, 100% join that, because our Discord community is really friendly and happy to help. Yeah, I take pride in that. [laughs] They’re awesome.
Yeah… [laughs] I’m looking out five years, but – um, the near future for Remix is this thing called Stacks. And we typically don’t like to talk about things that aren’t shipped yet, but I’m gonna break that rule a little bit, because we’re pretty close on this, and I’m super-excited about this. There’s one thing that lots of people like to talk about with frameworks, and that’s how fast I can get started. Anytime I’m brought into an interview, they want me to demo, like getting off the ground running, and stuff… And I think that’s deceptive a little bit, because that does not matter for anybody who wants to build something that lasts. Who cares if it takes five minutes or an entire day to get off the ground running if you plan on maintaining this app for the next ten years? It could take two months to get off the ground running; if you’re gonna plan on maintaining it for ten years, that is a fraction, a tiny piece of the time.
Now, of course, it does not take that long to get off the ground running with Remix, but I think what is way more important is how maintainable, changeable and adaptable is your app over the long-term. So we really focused right from the get-go on making it so that you could adapt your app to changing requirements over time. So I feel like we’ve really nailed that. And we’ve got a couple other things in the future that I’ll talk about in a second to make that even better. But because we’ve focused so much on that, the getting started is pretty good, but there are things that you kind of have to build yourself right now. If you wanna put together auth by yourself, or whatever you wanna do.
A lot of people like to say, “Hey, Remix isn’t really a full-stack framework because it doesn’t even have auth, and it doesn’t have a database, and it doesn’t have an ORM”, or whatever. And yeah, okay, that’s fine; what they’re really asking is “We just don’t wanna have to think about setting that up ourselves.” They don’t really care that Remix doesn’t itself ship with those things, they just don’t wanna set it up. And that’s fine.
And actually, another thing is a lot of Remix users, especially because, again, we’re targeting React Router users - a lot of these people are just using WebPack, bundling it all together and sticking it on a CDN or something, on some file-share thing, or whatever, and serving their app internally, or something. So they’re not used to deploying to a service, or deploying even an internal node hosting thing, or whatever… And so what we’re focused on with Stacks is providing you a really easy way to get set up to deploy to a particular target, to have a database setup, to have user authentication already set up for you… And the thing is that Remix doesn’t actually provide abstractions for these things, beyond managing cookies, and stuff. The abstractions that we do provide and the exposure to the web platform we give you makes it really easy to build these things yourself. And when it’s really easy to build it yourself, then you can manage it over time, and make changes to it over time, which I think is way more valuable than an abstraction that you have to learn.
[56:43] So what we’re doing is we’re creating these stacks, we’re generating this code for you that you can manage yourself. It’s not a lot of code, but all the configuration for a GitHub Action, and a dockerfile for deploying to Fly – that’s actually the one that I was finishing up this morning, was a Fly stack that has authentication, a Postgres database that’s all ready for read replicas on Fly, and multiple regional deployments… We have staging deployments as well for your dev branch… And then I set up Cypress for end-to-end testing, with even mocking of third-party services all set up for you… And Vitest for your lower-level unit tests… Prettier, TypeScript, ESLint, all of that stuff. So all you have to do is run this little script, and boom, you have this full app. So that is the near future, is Remix Stacks. We’ll have the same thing for architect, and whatever else, and I’m gonna withhold one little aspect of this for a part of the surprise when it finally comes out, because it’s gonna blow your socks off. It’s so good. So that is one thing that’s coming up close. I’ve got a couple other things, but I’m gonna stop talking for a second… [laughs]
I’m actually curious… With frameworks there’s usually the core, and how it’s built, and so on, and I think Remix currently has the server adapters, which is what you were mentioning with Express, and Vercel, and Netlify, and so on. Is there any plans as to extending or allowing plugins to be built from the community perspective? So if you wanted to add other adapters or ways in which you can use Remix - is that something that is in the pipeline?
Yeah, yeah. That actually is totally possible right now, and we’d love for Netlify and Vercel to take ownership of those packages. It’s like a couple hundred lines long. Maybe 200 lines long. It’s not a lot to make an adapter. The biggest challenge is because we want to normalize all the platforms, we normalize it to the Web Fetch API. So request-response has to be a fetch request-response, and headers, and all that stuff. And so your adapter is basically responsible for taking the request, converting into a web fetch request, and sending it in to Remix. And then Remix sends back a response, you convert that into whatever platform response that you need, and then send that response the way the platform doesn’t.
So yeah, it’s totally possible to build your own adapters. And also, we have a really awesome plugin type API where somebody could have – by the way, Remix isn’t just for UIs. You could take an Express REST API or some sort of made-up jumble of endpoints and migrate that over to Remix, and Remix could totally do that as well. So if you had something like that, you could install a plugin and all of a sudden have an admin interface for your REST API, or whatever. Swagger docs, or something. That would be a very straightforward thing to build with Remix, which - I’m really looking forward to when people discover that, because it’s huge.
One thing that I really like about Remix is how abstractable it is, from both the platform standpoint, but also the lower-level abstractions within the code, and then even the configuration abstractions to be able to add an entire set of routes just by updating the Remix config. A lot of the exciting things from the future will come from the community when they discover these abstraction points.
[59:59] Nice. Yeah, I think that’s usually what helps with adoption oftentimes, when there are these ways in which you can kind of extend and adapt an existing framework or a platform, because that’s when you know that the community cares, or they wanna use it for various use cases. It’s really hard as a core developer or building a core product to know all the various use cases, but yeah - if you wanted to build something like auth, or a database, or all of those things, those are essentially extensions of the core. So it’s really interesting to see how or what users care about; when they build it, it means that the community is growing. It’s a good sign.
Yeah, we’re seeing a lot of excitement on that end of things. Kball, you asked earlier if we have abstractions for forms… And there are a couple of members of the community who have built some really awesome abstractions for forms that are Remix-specific, that are really cool. And some things – like, somebody build a Remix auth that has different strategies for email and password, or magic links, or GitHub, or whatever, OAuth… And some of these things are just web platform abstractions; they’re not even Remix-specific, which is pretty sweet.
Another thing that I wanted to mention that is coming in the future - a really common need is a real-time sort of experience. You can absolutely use WebSockets with Remix. We expose the web platform to you, and web workers, and all the cool stuff that you wanna do… But we wanna have like a router-intelligent abstraction for this, so we’re gonna build in some really awesome abstractions for real-time data. There’s a GitHub discussion about this that Ryan opened up recently, and our API ideas for this are really cool.
Yeah, yeah. It’s gonna be great! Actually, somebody has already written a blog about how you can get WebSockets working with Remix today, but we’re gonna have really nice stuff… If you wanna do WebSockets and try and scale that yourself, or use some sort of pusher, or something like that… Or even polling. We’ll have a really awesome API for you for that.
In general, the roadmap and the future - you can bet that anything that Remix can do to improve the user experience or Remix apps, we will pursue that. And anything we can do to improve the developer experience as an input into user experience, so long as it doesn’t reduce the user experience, we will pursue that as well.
There’s a lot of excitement about React version 18, and server components, and stuff. We are very well situated to take advantage of those when they can improve the user experience. Right now they cannot. It is not released yet, and it is not great yet. But we’re hopeful that it will be, and we do have a blog post that shows where it’s at right now, with the current demos. And like I said, it’s not great. We’ll put a link to that in the notes.
But yeah, literally, people will just have to rename their files to .server, and all of a sudden it’s a React Server Component. People asked about that a lot. We are not currently doing anything with that, because it’s not ready. We are already way better than what they can do when we have React 17.
And people talk about streaming - same story. People talk about partial hydration - we haven’t seen anything that’s really compelling from that aspect either, but when we do, if that ever becomes something that… If you can do better than Remix, where we’re at right now, then we will pursue making that happen. And I can’t see any reason why we wouldn’t be able to support partial hydration in the future, if you could actually demonstrate that it was better for the user experience.
Right now, a huge problem with partial hydration - and for those who don’t know, partial hydration is basically you render your HTML, and then you can render different components individually, like hydrate individual components, and stuff. It sounds technically really awesome, because you don’t have to load all of this code. The problem is that as the user starts using the app, when they click on the button, they have to wait until it’s hydrated. [laughs] And that’s not a good user experience.
[01:03:56.03] So getting all of the HTML and everything on the page - that’s one aspect of the user experience. Really fast. That’s awesome. It’s like, good on ya. Get that HTML on the page. Awesome. But the user is here now, and we need to give them a good user experience as they use the app. So we haven’t seen anything that’s super-compelling from that aspect of like “Okay, so now that the user is here, let’s make sure that the app is ready for them to start using.” And we are keeping an eye on this stuff, but what we have done so far is we’ll take existing demos of different things and we’ll rebuild it in Remix, and we’ll say “Yup, Remix is better. Okay, good.” We’ll move on and we’ll wait until they can get things better.
So you can talk about technical improvements and the technical aspects of why certain things are better, but Remix - we’re all about “Show us. Show us why it’s better.” We’ll keep an eye on it and we’ll make sure that we can pivot as needed, but right now, Remix is the best way to build a web application in 2022. That’s why I joined the company.
Can we go and talk a little bit then about commercial sustainability here?
Because this is a common topic of concern on JS Party, is the sustainability of companies that are focused on open source. We saw the devastation that npm turned into… Certainly, Gatsby has challenges, and things like that… And one of the things that at least my take has been like companies that are focused around a particular open source solution seem to be struggling more than companies that try to ride the wave of many open source. Gatsby is having its lunch eaten by Netlify and Vercel. They provide the types of things that Gatsby has, but not just for Gatsby, and things like that.
Now, one exception that is sometimes seen is things like Tailwind, where they’re a commercial success around training rather than around the framework itself, or the tooling, or something like that. So to the extent that it’s not giving away company secrets, can you talk a little bit about where you see the sustainable path here? What’s gonna keep Remix the company from going away in two years and stranding Remix the framework?
Yeah, that’s a super-great question, and a lot of people are wondering about that. Nobody wants to rewrite their product in a framework that might not be around in the future. So like I said earlier, I would not have jumped ship from my gainful unemployment to Remix if I didn’t think it was gonna be successful. Seriously, even if I didn’t think it would be successful without me, I still wouldn’t have done it, because I want it to be successful in its own right.
So there are a lot of directions that we can go. Hosting is an obvious one. We’d love to partner with folks like Fly in the future… [laughter] And just provide a really awesome deployment strategy for Remix and React Router apps. So that’s definitely one avenue that we’re exploring. Also, images… My personal website gets about half a million pageviews a month…
Yeah, it’s a lot. So images – because my website is a blog, I have a lot of images. And I host on Cloudinary, and Cloudinary is outrageously expensive.
So I cannot wait until we build something for images with Remix. So in the future, that’s another option. We’re not committing to any of this, but I’m just giving you some very clear ideas of different things. Like I said earlier, we’re gonna offer whatever we can offer to help people build better websites. Some of those things will just be bits of code and things that they can just install in the Remix app and just run it along. We could have a Remix images thing where you install this plugin and all of a sudden you can serve your own images. It’ll be just kind of like Cloudinary, where it will resize, and all of that stuff. But if you don’t wanna host that yourself, you don’t wanna manage that yourself, then we’ll have a service for that.
Same thing with email - probably you have some sort of email thing, but we might offer an email service. Or internationalization, or CMS, or whatever. So I guess I should say that we do have financing from VCs, and we can probably build a really good business out of this initial funding that we’ve received. But just like every other company, the seed round is not the last round, and we’re planning on showing that we can have enough adoption that people are really interested in what we have to build. And then when we go and raise more money, then we can use that money to really build some really awesome, sustainable business services.
[01:08:20.24] Ryan, Michael and I have been in this business for a long time. Ryan actually has been doing this before CSS was invented, so he’s been in this for a really long time. We know what it takes to build a really awesome web platform or web presence, so we’re going to create software solutions for all these problems that we’ve experienced.
I shipped apps at PayPal to millions of users all over the world. I’ve got like 3,000 signed in users on my website… I get a quarter of a million unique visitors on my website every month… So we know how to build and ship web applications that serve millions of people. We know what it’s like to build in the enterprise, so we’re going to solve the problems that we experienced in those places, and offer those as services. So let your imagination run wild with that, but that is our plan.
Nice. I think you all are thinking about the right problems, because a lot of things – like, specifically with images, like you mentioned, and probably video as well at some point… They’re issues that are very difficult to handle. There’s git LFS, which is a nightmare to deal with if you don’t want to use a hosting platform and having to deal with that, and storing it, and resizing it. It’s a lot.
I remember Netlify doing something very similar with that, and there’s a lot of nuances that you need to get through, understanding what users want with it. So yeah, I think that would be really cool to see.
Yeah. Exciting times ahead. But right now we’re focused on adoption, and if anybody wants to help with that, really, seriously make a good impact on our success in the future – you know, because the more success we have in fundraising, the more smart people that we can hire to help us make this a success, and the better the framework can get. So if you really wanna help, then what we need is people to get really good at Remix and teach people what they know. That is what we need right now. So meetups, speak at conferences… And by the way, RemixConf is coming at the end of May, and it’s gonna be awesome. Fly is a sponsor, so I hope to see you there, Divya.
And Amplify is a sponsor too, Ali, so I hope to see you there, too. Kball, get on the ball here! [laughs]
Do you wanna do a live show?
Yeah, since there’s two of us…
Let’s do it!
Kball, you should totally just come.
We can talk about this offline, but we have historically done live shows. You’ve just gotta treat us like speakers.
Okay, alright. Yup, let’s talk about this. But yeah, come speak at RemixConf, or speak at other conferences about Remix. We just really need to help people understand the magic of Remix, so that we can make the web better. That’s our ultimate goals.
Ryan and Michael and I like to talk about how we’re just sick and tired of using our kids’ school’s websites, and we want those to be better by default. Ryan and Michael would be like, “Man, who built this stupid thing?!” and they open up the dev tools and find out that they’re using React Router, and like “I did.” [laughter] So they’re looking forward to having really awesome user experiences by default with something that they built.
I love that phrase, “Make the web better by default.” Alright, thank you for joining us today. This has been super-fun. I appreciate it. And I’m excited to go try out Remix. I have not yet tried it; I’ve just read about it and seen you tweeting, so I’ll be trying that out.
Yeah, thank you so much.
Thank you very much.
Alright, and that is it for today’s JS Party. We will see you later, all!
A better idea would be to replace/improve the fetch spec.
Our transcripts are open source on GitHub. Improvements are welcome. 💚