skip to content
Video cover art for RedwoodSDK with Peter Pistorius
Video

RedwoodSDK with Peter Pistorius

Peter Pistorius shows how RedwoodSDK turns Cloudflare Workers, Durable Objects, and React Server Components into a powerful toolkit for real‑time personal apps

Open .md

Episode Description

Peter Pistorius introduces Redwood SDK, a server-first React framework built on Cloudflare, explaining its principles, real-time features, and vision for personal software.

Episode Summary

Peter Pistorius joins Anthony Campolo and Dev Agrawal to discuss Redwood SDK, the successor to the original RedwoodJS framework. Peter explains the decision to deprecate the old framework while keeping the Redwood name, honoring the community and original vision. He walks through the core design principles — zero magic (no transpilation tricks or code generation), composability, and web-first standards using fetch and native browser APIs. The conversation moves into a live code demo showing the framework's router, middleware system with "interrupters," react server components, server functions, and how flight data works under the hood. Peter demonstrates real-time capabilities powered by Cloudflare's durable objects and WebSockets, file uploads streaming directly into R2, and the simplicity of single-command deployment. The group discusses the move away from GraphQL, the rationale for going all-in on Cloudflare despite vendor lock-in concerns, and the "personal software" philosophy inspired by Maggie Appleton's barefoot programmers concept. Anthony demos his AutoShow app built with Redwood SDK, and Peter introduces shareware.dev as a monetization concept for selling composable source code. The episode captures a framework at an early but promising stage, with a clear server-first identity in a landscape dominated by client-side routing.

Chapters

00:00:00 - Introduction and the Redwood SDK Origin Story

Anthony Campolo welcomes Peter Pistorius and guest host Dev Agrawal to the stream, kicking off a wide-ranging conversation about the state of JavaScript frameworks. Peter shares how the team decided to deprecate the original RedwoodJS and rebuild from scratch, choosing to keep the Redwood name to honor the community, Tom Preston-Werner, and the original contributors who built the project over five years.

Dev introduces himself as someone passionate about JavaScript frameworks and mentions his recent talk on TanStack. The group discusses how TanStack's Tanner Linsley has been building tools even longer than Redwood has existed, and Peter acknowledges the early stage of Redwood SDK while expressing commitment to the long road ahead. Anthony notes that the tight Cloudflare integration recalls the early days when Redwood worked seamlessly with Netlify before multi-provider support complicated things.

00:06:33 - Framework Maintenance Challenges and Early Questions

Peter reflects on how supporting multiple third-party authentication providers and hosting platforms drained the team's velocity and ultimately contributed to tearing apart the original framework. The conversation touches on AWS Lambda's shortcomings and the potential for SST on Cloudflare, with Peter highlighting the Alchemy project by Sam Goodwin as a promising infrastructure-as-code tool.

A viewer question about whether Redwood SDK uses Parcel leads to a quick clarification that the framework is built on Vite, not Parcel. The discussion naturally flows into the broader challenges of maintaining open source frameworks when dependencies and deployment targets multiply, setting the stage for why a focused, single-platform approach made more sense this time around.

00:09:50 - Personal Software Philosophy and Branding

Peter shares his screen to walk through the Redwood SDK homepage and its nostalgic branding inspired by 1990s computer advertisements that encouraged families to bring PCs into their homes. He explains the "personal software" manifesto — the idea that software doesn't need a brand, monetization strategy, or VC funding, but can simply solve problems for yourself, your friends, or your community.

Dev connects this philosophy to Maggie Appleton's concept of barefoot programmers and home-cooked software from the local-first conference scene. Anthony explains the related concept of digital gardens — websites as iterative, evolving projects rather than polished products. Peter reveals that the team initially resisted calling Redwood SDK a framework, preferring "toolkit," but ultimately embraced the framework label after realizing people understand and expect that term, drawing a parallel to Prisma's years of resisting the ORM label.

00:15:08 - Why SDK Became a Framework and Core Design Principles

Peter explains the composable architecture behind Redwood SDK — a Vite plugin providing access to Cloudflare Workers, React server-side rendering, server components, client hydration, and a lightweight router. He discusses borrowing route function naming conventions from Remix's router and how patterns like nested routes and loaders trace back to Ember and have been reinvented across many frameworks independently.

The conversation explores Tom Preston-Werner's concept of the "adjacent possible" and how multiple discovery explains why framework authors often arrive at similar patterns simultaneously. Peter outlines three core principles: zero magic with no transpilation side effects or code generation, composability through discrete pluggable functions, and web-first design that surfaces native browser APIs directly rather than through abstractions. He contrasts this with the old Redwood's "magic exports" like cells, which broke the implicit contract developers had with TypeScript.

00:21:24 - Zero Magic Philosophy and the Problem with Transpilation

Peter goes deeper into what "zero magic" means by explaining how the original RedwoodJS used Babel transpilation heavily to create magic exports — functions whose behavior couldn't be understood just by reading the code. While this was elegant for developers 99% of the time, it created painful debugging experiences and made the framework extremely hard to maintain, with complex Babel configurations that no one on the team fully understood.

The new approach strips out all code generation, scaffolding CLI commands, and transpilation side effects. Peter explains that the framework ships only two starter templates — a standard one with authentication and Prisma, and a minimal one with nothing. Dev raises an important question about how these zero-magic principles reconcile with React server components, which themselves introduce directives that feel magical. Peter acknowledges the tension but argues RSC's underlying technology is genuinely web-first and makes the most sense in a server-first architecture.

00:27:10 - Live Code Demo: Routes, Middleware, and the Document

Peter begins a live walkthrough of a Redwood SDK application, starting with the defineApp function that takes an array of route handlers. He demonstrates the middleware system where a context object passes through sequential middleware functions and becomes available in every route. The routing uses a render function that matches URLs to JSX documents, co-locating API routes and page routes in the same space.

He shows the Document component, which replaces the traditional index.html file and gives developers control over every byte sent to the browser. By toggling a single import for client-side code, Peter demonstrates switching between a fully server-rendered HTML page with zero JavaScript and a hydrated interactive page. He explains that this architectural choice lets developers keep marketing pages completely JavaScript-free while other sections of the same app are fully interactive, eliminating the common flash-of-unauthenticated-content problem.

00:33:20 - React Server Components and Flight Data Explained

Peter walks through how React server components work in practice within Redwood SDK. He shows a server component rendering JSX to HTML alongside a client component with interactivity like state and click handlers. When a client component calls a server function, Vite's transpilation step creates a unique key mapping for each exported function marked with "use server," which generates RPC-style fetch calls under the hood.

Using the network debugger, Peter demonstrates the POST requests containing action IDs and emoji payloads, with the server returning flight data — React's serialization format for describing what changed on the page. Dev asks Peter to explain the flight data concept for viewers, and Peter describes it as the RSC payload, a progressive JSON format that tells client-side React what to import and render. The group discusses Dan Abramov's blog post on progressive JSON as a resource for understanding this serialization approach.

00:40:19 - Real-Time React with Durable Objects

Peter demonstrates Redwood SDK's real-time capabilities by swapping the standard client initialization with a real-time client that upgrades the first request to a WebSocket connection. Without changing any application code — still using regular server actions and page renders — he shows two browser windows sharing state in real time through Cloudflare's durable objects, which support thousands of concurrent WebSocket connections.

The group discusses how this approach compares to Dev's own work on real-time capabilities for Solid Start, where he introduced a "use socket" directive and reactive signals passed between client and server. Peter introduces the fellowship program sponsoring Johannes Schickling to work on Live Store, a sync engine for data that could offer an alternative real-time approach with less overhead than full payload transfers. Dev expresses interest in exploring the Solid bindings for Live Store.

00:48:12 - Web Standards, File Uploads, and the Cloudflare Bet

Peter explains why he considers React server components fundamentally web-first despite their magical directives, since they use fetch under the hood. He demonstrates file uploads in Redwood SDK, showing how form data streams directly from the browser through a route handler into Cloudflare R2 storage with minimal code — just a single put call. Downloads work the same way in reverse, streaming the R2 object body directly in a response.

The conversation takes a fun detour when Dev points out that R2's name follows the same letter-shift pattern as HAL from 2001: A Space Odyssey — R2 is S3 shifted back one letter in the alphabet, referencing Cloudflare's S3-compatible storage competitor. Peter discusses the broader Cloudflare ecosystem and defends the decision to go all-in on a single platform, citing the free tier, 330 global edge nodes, and the elimination of the "five taxes" developers pay when integrating external SaaS services.

00:57:00 - Server-First vs Client-First and Building for the Majority World

Dev challenges Peter on the tension between Redwood's server-first architecture and the local-first movement, noting that most personal software builders at the local-first conference were using client-first technologies with sync engines. Peter responds that personal software meant for communities and collaboration inherently requires a server, and that server-first is simply a more natural model for the web's request-response foundation.

Peter frames Redwood SDK's design philosophy around building for the majority world, speaking from his experience living in South Africa where bandwidth costs can consume 25% of a person's income and devices aren't high-end. He argues that shipping less JavaScript, optimizing for memory and network usage, and making things fast by default aren't just nice-to-haves but essential for global accessibility. He explains how Live Store on durable objects could bridge the server-first and local-first worlds by giving each user their own cloud database that syncs to local devices.

01:03:43 - Anthony's AutoShow Demo and Shareware.dev Vision

Anthony demonstrates AutoShow, an application he built with Redwood SDK that transcribes audio using the Deepgram API and generates summaries and chapter breakdowns via OpenAI's ChatGPT. He walks through the architecture: a client component calling server functions, results stored in D1 and rendered with dynamically generated routes. He describes how he migrated the project from a CLI tool to a Cloudflare worker with React, then ported it to Redwood SDK with AI assistance.

Peter introduces shareware.dev as Redwood SDK's monetization concept — a marketplace where developers can sell composable source code for tools they've built without needing to create brands, pricing strategies, or support structures. The license would prevent commercial redistribution while enabling yearly access. This ties directly to the personal software philosophy: build something useful, and if others want it, sell the source code rather than running a SaaS business around it.

01:14:01 - GraphQL Retrospective and the Decision to Rebuild

Dev asks what happened with GraphQL, and Peter explains that the multi-client architecture — where mobile and web consumers define their own data needs — made sense on paper but created too much boilerplate for startups where the same developer builds both the frontend and API. Anthony adds his own extensive GraphQL experience, noting that most complaints about GraphQL stemmed from not using an opinionated framework like Redwood that solved common pain points around auth, libraries, and endpoint security.

Peter describes how React's evolution toward server components was incompatible with the existing Redwood architecture, and stalled growth convinced him a ground-up rewrite was necessary. He shares the personal story of Tom Preston-Werner offering him leadership of the project after Peter's own startup failed, his initial refusal, and the weekend reflection that led him to accept. The prototype built on Cloudflare in November exceeded expectations, leading to the March release roughly five years after the original framework's debut.

01:57:35 - Team, Tools, and Closing Thoughts

Peter credits the core team — Justin, Harmon, Amy, and himself — noting that Justin wrote the majority of the framework code. He reflects on how the framework emerged almost naturally from strong principles and a clear vision of who they were building for. The conversation turns lighter as Dev recalls meeting Peter at the last Jamstack conference while still a college student, and Peter jokes about trying to pitch his previous startup Snaplet.

The group wraps up with Peter recommending Whisper Flow as a voice-to-text tool that helps him communicate more effectively than typing. Anthony encourages viewers to star the Redwood SDK GitHub repository and follow Peter on X. The stream closes on an energetic note, with all three expressing excitement about the framework's trajectory and plans for future collaborative streams exploring other framework ecosystems like Solid.

Transcript

00:00:02 - Anthony Campolo

And we're live. Welcome back to AJC and the Web Devs with Peter Pistorius and special guest host Dev Agrawal. What's up, Peter? It's been a while.

00:00:16 - Peter Pistorius

Thank you. Thank you for welcoming me to AJC and the Web Devs. Are we the web devs?

00:00:22 - Anthony Campolo

Yes, all three of us collectively are the web devs.

00:00:25 - Peter Pistorius

That's great. I'm proud to be a web dev. I'm doing really well. I'm happy to be here. Can I swear on this?

00:00:35 - Anthony Campolo

Of course. Yeah.

00:00:36 - Peter Pistorius

I'm happy to shoot the shit here with you guys.

00:00:41 - Anthony Campolo

I love the streams where I get to shoot the shit. And you're someone I love shooting the shit with. You all are making a ton of content — you're doing talks, you're going on podcasts. You haven't done that in, like, a couple years. So how's that been? You got the Syntax podcast in the mix now.

00:00:59 - Peter Pistorius

Wes is amazing. I've watched that talk several times and I have his intro stuck in my head. It's always fascinating for me to watch other people introduce their own podcasts, because Wes goes, "Welcome to Syntax." So I like AJC and the Web Devs as well. Yeah, it's been really great creating new content. There's a lot of excitement around what we're building, and I'm happy to tell people about it.

00:01:30 - Anthony Campolo

Yeah. When did the name Redwood SDK come into play?

00:01:37 - Peter Pistorius

There was a lot of work that went into calling what we're building "Redwood SDK." For those of you that don't know, there was this original framework called RedwoodJS, and we decided to deprecate the entire framework. We had to come up with something new. Originally we were going to actually just take the name RedwoodJS for ourselves and rename the older version to Redwood Classic — RedwoodJS Classic. And I actually saw that Remix referred to their thing as "classic" as well.

00:02:16 - Anthony Campolo

They ripped us off. Yeah.

00:02:17 - Peter Pistorius

No, no.

00:02:19 - Anthony Campolo

It's just funny because Ryan Florence particularly has accused three other frameworks of ripping Remix off. So it's a joke. I would never say it to anyone else but him because he deserves it.

00:02:31 - Peter Pistorius

I think there's always a natural thought process when things like this happen. But essentially we wanted to keep the name Redwood because deep down we are still the exact same. We have the same ideas we were putting forth with the original framework. We have an amazing community. I think we have a little bit of traction with the name already, and it has its association to Tom and David Price and Rob Cameron, and I wanted to honor that. The community that we have is fantastic. So what I wanted to do was honor that and give it a good go — figure out what we needed to do to be compelling to developers today, figure out growth, and really build something that feels amazing.

00:03:25 - Anthony Campolo

Awesome. I am so stoked for this conversation. Dev should get a chance to introduce himself.

00:03:37 - Peter Pistorius

I was going to say something.

00:03:39 - Anthony Campolo

To be expected. Dev, you should give your quick spiel on Redwood and what you know about it.

00:03:46 - Dev Agrawal

Yeah, of course. Happy to be here. Happy to be talking about Redwood. I just love JavaScript frameworks in general. I feel like I have the opposite of JavaScript fatigue — most people are getting tired of JavaScript frameworks, I just get excited by them. I'm happy to see people putting effort into this. Okay, does that mean I'm going to experience a crash in like three more years?

00:04:18 - Anthony Campolo

You'll eventually hit a point where you need to ask yourself, do I want to keep doing this, or do I want to actually just build something instead? But you can build one — you don't necessarily have to do one or the other. I want to get back into actually talking about frameworks. Continue.

00:04:34 - Dev Agrawal

Yeah, for sure. I'm trying to build at least one of my own as well. But it's just a fun landscape to be a part of. Seeing how people approach building frameworks is such an interesting task. You basically have to shape and formalize an opinion of how web apps work, what's the best way to build on top of the web, then document and codify everything around it, ship it as a framework, and hope people are successful.

So yeah, super excited for this conversation. Also, I just gave a talk today at Frontend Nation called "Meet the Web Framework from the Future." Unfortunately it was not about Redwood — it was about TanStack, which I'm super bullish on. Something I'm going into today's conversation with is trying to figure out what Redwood is doing that's different from other frameworks.

00:05:34 - Dev Agrawal

What are the trade-offs? What are the things you're doing better than anyone else? What are things you could be doing better? And just maybe, what are things that I need to unlearn from other frameworks?

00:05:49 - Anthony Campolo

Ben Patton has a comment here saying this is a good opportunity for Redwood SDK to become a real JS option comparable to Phoenix LiveView — a canonical full-stack framework you could actually compare as a full-stack framework, unlike most JavaScript frameworks. I agree with that comment.

00:06:07 - Peter Pistorius

I just want to say that TanStack — Tanner has been building his router and all the tools he has for longer than Redwood has existed. What he's built is amazing.

00:06:23 - Anthony Campolo

He was building React Query when Redwood first started, and then he's gotten to this whole back-end journey. Redwood's like six years old now.

00:06:33 - Peter Pistorius

Yeah, there's a long tail of hard work he's put into it, and I think it's really paying off now. I just want to preface that by saying Redwood SDK is early, so we have a long journey ahead of us. And I'm here for that.

00:06:56 - Anthony Campolo

I just used it and it feels pretty solid to me. I think the fact that you're building it really heavily around Cloudflare brings it back to that feeling I had when it first only really worked for Netlify — a really nice dev experience because you'd just build it and deploy it and it would just work. Then once we had seven deployment providers, it got really complicated.

00:07:19 - Peter Pistorius

Totally. One of the things that really started to tear it apart was the fact that we supported all these third-party authenticators and third-party hosting providers. At the end of the day, we couldn't keep up with all the maintenance work on all those packages. It slowed down velocity. And besides the fact that AWS Lambdas did not live up to what we thought they would — yeah, unfortunately.

00:07:55 - Anthony Campolo

We got a question here that only you can answer. I came across a PR on GitHub yesterday where Redwood SDK and Waku are using the Parcel RSC package in the React repo to implement React Server Components. Is this true? I thought we were using Vite, so we wouldn't be using Parcel.

00:08:14 - Peter Pistorius

I don't think so. I'd be really interested to see where that PR is, but we're not using Parcel. Yeah. AWS is awful — you need a degree just to understand how to use their dashboards. And everything is a three-letter acronym.

00:08:37 - Anthony Campolo

Acronym. Yeah. One thing that would have worked nicely would be SST. Now that it's on Cloudflare, SST could still work with Redwood, since you don't have an infrastructure-as-code layer right now.

00:08:51 - Peter Pistorius

Well, we don't, but there is a really amazing project being built called Alchemy — Alchemy.run.

00:08:58 - Anthony Campolo

And that is a similar thing, for sure.

00:09:02 - Dev Agrawal

Yeah, I'm a big fan of the work Sam Goodwin is doing with Alchemy.

00:09:07 - Anthony Campolo

Yeah, you guys talk about it on Twitter. It's pretty sweet.

00:09:11 - Peter Pistorius

There's so much to unpack here. Maybe I can share my screen and give a little more context about what Redwood SDK is and why we ended up calling it SDK.

All right, I'm going to share my screen here. So this is our homepage — the first one we've shipped, and we're busy building a new one. Our tagline is "This could be the start of something small." We have this nostalgic imagery based around people introducing computers into their homes. I grew up in the '90s. For me, there were all these really great print ads based around people trying to convince you to get a computer in your house, because that wasn't a thing yet. It was fascinating to see all these different companies with these tongue-in-cheek ads for putting PCs in your home.

00:10:23 - Peter Pistorius

Actually, let me bring some of these up here. We did a whole bunch of research around this.

00:10:33 - Anthony Campolo

You had these on, like, cassette tapes or CDs or something.

00:10:38 - Peter Pistorius

Yeah. These are some of the print ads from that time. I don't know why there are people in bikinis here, but there are little kids full of surprise. Like, a cool accountant dude doing music.

00:10:54 - Anthony Campolo

Ladies.

00:10:55 - Peter Pistorius

Oh man. This one here I actually recreated using AI. We just wanted to grab this vibe from the time when I was growing up and use it for our own brand. The reason why is that I think software is changing. Software used to have to be written by experts — people that knew how to code. And I think that's becoming less and less true as we discover the power of AI. What I'm seeing is that there are a bunch of technical people who maybe just understand computers really well but don't necessarily have hard-core software skills, and they want to enter the conversation. They also want to build software to scratch their own itch.

So we created this manifesto called Personal Software. There's a video around this — Amy actually narrated it. But the idea is that you don't necessarily have to write software just to make money.

00:12:04 - Peter Pistorius

You can write software that solves a problem or scratches your own itch. And doing that, you can help your friends, your community, or even the small business that you work for, just by being helpful with software. It doesn't have to have a brand. It doesn't have to have a monetization strategy or full support capability. All you really need to do is just solve a problem. That's where "This could be the start of something small" comes from. We wanted to bring that idea to people again, because that's what it was like in the early days. You just wrote code for the hell of it. It wasn't about getting VC funding, hyper growth, et cetera. It was just about building software — one for the craft and two for solving people's problems.

00:12:53 - Dev Agrawal

Cool. I love that there is a lava lamp in the background of that image. Great shout-out to Cloudflare.

00:13:02 - Peter Pistorius

Very intentional.

00:13:04 - Dev Agrawal

Yeah. I want one of these at React Rally. I actually got one from the Cloudflare booth, so it's been sitting next to me for a while. And yeah, the idea of personal software — I think I was properly introduced to this last year, thanks to Maggie Appleton and her talk at local-first conf about...

00:13:28 - Peter Pistorius

Yeah.

00:13:28 - Dev Agrawal

What was it — home-cooked software and barefoot developers?

00:13:32 - Peter Pistorius

Barefoot programmers. Yeah, yeah.

00:13:34 - Dev Agrawal

Barefoot programmers. Yes. Amazing. And I love that people are — and especially framework authors are — leaning into this. A big shout-out.

00:13:43 - Peter Pistorius

Totally. It was a very big inspiration for us. I've reached out to her and asked her if I could continue down the path of what she had very eloquently said, and she gave me her blessing.

00:13:59 - Anthony Campolo

I'm sure it's fine.

00:14:01 - Peter Pistorius

Yeah, well, I should probably cite her. But you're right.

00:14:05 - Anthony Campolo

Yeah, just put her name somewhere in there and link to her page. That's cool, because a lot of people reference her when they talk about the Digital Garden. And I don't know if she came up with that term or if she popularized it, but that was a term people always associated with her. She's just good at that kind of thing.

00:14:26 - Peter Pistorius

What is a digital garden?

00:14:27 - Anthony Campolo

A digital garden is when your website is not something you think of as selling a thing or publishing really perfect, set-in-stone content, but where you're constantly iterating and building and changing — thinking of it more as an iterative development experiment that you're always just working on.

00:14:50 - Peter Pistorius

That's cool.

00:14:52 - Anthony Campolo

So it's more like gardening — you're tending all these different things that are growing over time, instead of necessarily building a structure piece by piece that does a specific function. I think that's kind of the meaning behind the term, which I always really liked.

00:15:08 - Peter Pistorius

Okay. And the reason why we ended up calling it SDK was because when we built it, we actually didn't want to call it a framework. We felt like what we were building was a set of really discrete components — or functions — that were composable. We kind of explain that here. So we resisted calling it a framework. We wanted to call it a toolkit, because we felt we were not producing a framework. We were giving you these composable pieces that you could fit together. It felt like you own it because it's just Vite — a Vite plugin that gives you access to workerd, and then workerd has React server-side rendering, React Server Components, and then we have a client-side hydration part. On top of that we built a router that's super lightweight and super composable, and then we just handle request-response. But after speaking to a bunch of people, they were like, "Hey, remember Prisma? Prisma was trying to not call themselves an ORM for many years."

00:16:27 - Anthony Campolo

And eventually they caved about it.

00:16:30 - Peter Pistorius

Yeah. And they were like, "No we're not." Maybe that was a really good marketing strategy. And eventually they're like, "Okay, fine, we're an ORM. That's what we are." So we decided we're just going to lean into that — use the term people understand. And it's more helpful, right? Like if I said this is a toolkit for building web apps, I guess that makes sense. But if I just say it's a framework, you're like, yeah, I get it.

00:17:00 - Anthony Campolo

I think it would be more confusing to say it's an SDK or toolkit, because people usually associate SDK with a specific company that built something to work with their platform. That's not the only definition, but that's how we hear it a lot. And "toolkit" — especially now that "tool" is being used in AI contexts — can mean so many things. It's not like this is really that different from the original Redwood framework. It doesn't have GraphQL, but it still has a clear separation between front and back end, is still React-based, still gives you database access and a full end-to-end experience. So it's still a framework, just one where you made it easier to swap in the parts.

00:17:44 - Peter Pistorius

Yeah, it feels incredibly composable. And a lot of people have described it as feeling invisible — like you're just writing the code you care about, trying to build the software that matters to you, and you're not fighting the framework. It's invisible to your goals.

00:18:08 - Anthony Campolo

I do think it's invisible in terms of how it interfaces with Cloudflare. I think people who've never used Cloudflare before will hit some weird infrastructure things, because there's a learning curve to Cloudflare itself and Workers — especially if you're going to do things like worker bindings to bring in D1 and R2, there are specifics to that. The good thing is Cloudflare has done a good job creating prompts and docs, so you can use AI to get through it. I was able to create an app within an hour or two, probably because I'd already used all this Cloudflare stuff. The framework is just giving you the workers, there's the front end, and they're doing something with the router that I didn't fully understand yet because I was just kind of vibe-coding it. But it did feel invisible — I just don't think it would have felt invisible if I didn't have the prerequisite Cloudflare knowledge.

00:19:07 - Peter Pistorius

That's fair, because Cloudflare is a little bit of an odd duck. When you think of Cloudflare as a hosting provider and compare it to other offerings, it's like they give you all the parts and you compose them yourself. It's not plug-and-play in the way other hosting providers are. It feels way more configurable. Anthony, you built something with Redwood SDK — do you want to share your screen?

00:19:40 - Anthony Campolo

You actually have a code project you should show first.

00:19:45 - Peter Pistorius

I do, I do.

00:19:46 - Anthony Campolo

Yeah. I want to get more into your code first because I want to make sure I understand what the actual conventions are correctly.

00:19:56 - Peter Pistorius

Okay. I just want to frame that demo with the principles we put into building Redwood SDK. I can also explain where these come from.

00:20:12 - Anthony Campolo

We got all the time in the world. Feel free to explain at length anything.

00:20:18 - Peter Pistorius

Okay, cool. We built Redwood with GraphQL four or five years ago. At the time we were just getting to know what Babel could do and what transpilation could do. And when you give someone a tool like that, they use it. So we used transpilation quite heavily. We introduced something I call magic functions — an export on a file or module that invokes some kind of activity based on the framework. A really clear example is a cell in the original Redwood. A cell was a way to query your GraphQL endpoints, and you could define an export for a loading status, an error status, a completed status, and the query itself. These were just exports shipped out of that module, and you didn't have to connect the dots in your code. The transpiler would pick that up and do it for you automatically.

00:21:24 - Peter Pistorius

That is what I call a magic export or a magic function, because you cannot — as the programmer just looking at the code — reason about it. You can't connect the dots. You have to understand something about the framework to do that. Those things made building the framework really hard, because it's extremely nice...

00:21:44 - Anthony Campolo

For the dev 99% of the time, except for the time it breaks. It's such a double-edged sword because it's so nice when it works and so bad when it doesn't.

00:21:57 - Peter Pistorius

As a programmer you understand TypeScript or JavaScript. You're entering the conversation with the framework with some prerequisite knowledge — the language you're coding in — and there are contracts in that language. And the framework author has thrown those away. They're like, "Hey, remember that thing you explicitly understand about the language? That doesn't matter anymore. Just do this weird other thing that we suggest."

00:22:25 - Anthony Campolo

200 lines of Babel config that you will never be able to understand.

00:22:28 - Peter Pistorius

Yeah. And no one else on the team can maintain them. So I wanted to get rid of that. I wanted to make sure that when you were programming, it felt like you were programming — programming in TypeScript. To do that, we had to take out any code generation. So there are no magic types, no transpilation side effects. And a lot of people will say, "Hey, but you're using JSX and TypeScript." Yeah, we are, but what I mean is the framework itself isn't doing anything crazy.

00:23:02 - Anthony Campolo

So there's no scaffolding CLI commands at all?

00:23:05 - Peter Pistorius

Nothing. We don't even have a CLI.

00:23:08 - Anthony Campolo

So you just generate from one of the two templates, right?

00:23:15 - Peter Pistorius

Yeah, we have a standard starter, which includes web authentication, uses Prisma as the ORM, and includes a durable object session. And then we have the minimal starter, which includes absolutely nothing.

The second principle that was really important to us was composability. It's really nice to have these distinct pieces that you can connect together in any way possible. You see that with Vite — you have your Vite config, you can introduce plugins. We wanted to give you that ability from the start. Our project is just Vite, and our router is just a simple set of functions that you can compose in any way to create a certain shape. And by the way, I did look at Remix's router when I built our own. You'll see a lot of the function and method names are the same.

00:24:17 - Peter Pistorius

I took them from there. I'll happily say that I did because the ideas are good. We just modified them to make sense in the world we wanted to build. Really, it's just the prefix part and the route part — that's it. So Ryan, come at me. He won't.

00:24:40 - Anthony Campolo

A lot of these patterns appear in SvelteKit, they appear in Solid Start, Nuxt — there are a lot of frameworks that have somewhat similar and somewhat differing patterns that you can map to each other in lots of different ways. I think it's good to sometimes use the same naming, because if it's going to work the same way, people can come in with that knowledge already.

00:25:08 - Peter Pistorius

Yeah, totally.

00:25:09 - Dev Agrawal

And especially things like nested routes and loaders. These are concepts from before even React Router. Ember was probably the first to introduce them through a router, and then they made their way into other routers. It's not always easy to trace them back. But yeah, some people get overly excited about, "Hey, we invented this — did you steal this from us?"

00:25:34 - Peter Pistorius

Yeah.

00:25:34 - Anthony Campolo

They invented all sorts of things they never got credit for. So I always thought it was kind of ironic.

00:25:41 - Peter Pistorius

There's this thing Tom Preston-Werner speaks about called the "adjacent possible." There's a certain period of time where everyone sees the same stuff, and some people will speak about it and share it. It's not necessarily that they're stealing each other's ideas — they're actually thinking of them and doing them at the same time. I think the theory of relativity is actually one of those adjacent possible ideas.

00:26:11 - Anthony Campolo

Yeah. The term "multiple discovery" is used a lot — Leibniz and Newton both created calculus at the same time, or Darwin and Wallace both independently arrived at evolution. So the adjacent possible is what makes parallel discoveries possible. And if you're doing it publicly, you're being influenced by other people sharing their work. It's more like a research and development project — the way science has been done for 400 years, with everyone building on each other's pieces.

00:26:41 - Peter Pistorius

Yeah, there is no other way. And then the other thing we wanted to do was lean heavily into the web. So everything we do is fetch. And if the browser offers a native implementation of something, we just surface that to you directly — not through an abstraction. I think that future-proofs a lot of the work we're doing on the core of the framework. All right, let's do some code.

00:27:10 - Dev Agrawal

Actually, I have a couple quick questions about the principles before we get into the code. The biggest thing I'm curious about is: how do you reconcile these design principles with something like React Server Components? Let's say composability — I can probably understand that server components allow composable logic across client and server. But use client and use server definitely feel very close to magic. I don't necessarily mean that as a bad thing. I'm a big fan of use client and use server, and I think some magic is sometimes nice. I also understand the motivation behind the zero-magic principle — it's a good value to hold and it leads to good design. But I'm curious: you want your framework to be zero magic, but you're also using React Server Components, which seem to bring a lot of magic. And at the same time, it doesn't seem exactly web-first, even though it might sometimes seem like it.

00:28:26 - Dev Agrawal

So yeah, I'm just curious about the thought there.

00:28:29 - Peter Pistorius

Yeah. So—

00:28:30 - Dev Agrawal

You've had this question before as well.

00:28:33 - Peter Pistorius

I have. We're trying to be non-contradictory in our statements, but then people see us using something like React Server Components and they're like, "Hey, how do these things work together?" So I don't really like the way directives are implemented. I wish they were a little less magic — not just a string at the top of a file or function. But fundamentally, the underlying technology of how they implemented it is really, really web-first and really, really straightforward in my mind. Maybe this is because I've implemented them twice, but I still make really dumb errors when using them. So there is a bit of an issue, and I think we're going to fix that over time.

00:29:34 - Peter Pistorius

One of the things I want to point out is that React Server Components make the most sense in a server-first architecture. If you have a client-side router and you're trying to lean into React Server Components, it's probably not the right tool for the job. But if you're doing request-response — where you have this single entry point, you're setting middleware, setting cookies and sessions and headers — and you're outputting something at the end, it's going to feel a lot more intuitive. That's what we've noticed with what we've built. And I can actually explain a bit about how I see React Server Components and React Server Functions working, and how they are actually the inverse of what people expect. Could we get—

00:30:25 - Anthony Campolo

Into this part? Could you pull up one of the files that relates to React Server Components specifically — that would help.

00:30:31 - Peter Pistorius

Yes, yes. All right. I'm going to—

00:30:34 - Anthony Campolo

Show me a server component, sir.

00:30:37 - Peter Pistorius

I am going to show you a quick demo. This is a Redwood SDK app. It starts off with this defineApp function, which takes an array of route handlers. We have the middleware here. You can introduce another piece of middleware — so you can say, "this is another piece of middleware," and you get the context from here and can actually modify the context. I'm going to turn this off for a second.

00:31:10 - Anthony Campolo

Quick comment while you're doing that: I think that's why the initial community reaction to RSC was so negative — we're all doing client-side stuff. Fuzzy says this is interesting because he's wanted to hear the take of RSC from a framework author's point of view, because it's not really meant for the normies. There are maybe like a dozen people on Earth with the experience to actually talk well about React Server Components.

00:31:36 - Peter Pistorius

Yeah, but it's getting better. We are early and we've got to keep that in mind. The patterns that React Server Components introduce are really powerful, and they do end up making development a lot easier. It's just that we're super early.

All right. So this is middleware. What will happen is when the request hits this server, it will first go through this, and then hit this one where you can set up a user. The context object is available in every route. There's also a global called requestInfo that you can import in your server functions and use there. And then you get into this part where you define the render. So we say: when this route is matched, render this document — when this route is matched, render this document. Back me up and let me know if that doesn't make any sense.

00:32:36 - Anthony Campolo

From here you should go to the document file.

00:32:39 - Peter Pistorius

Okay. So when we say render

00:32:43 - Anthony Campolo

You didn't have a document file before in other frameworks.

00:32:46 - Peter Pistorius

Exactly. Usually what you would have is like an index.html file.

00:32:51 - Anthony Campolo

Exactly. Yes.

00:32:53 - Peter Pistorius

But we were like, "What we want is to give you the ability to control every byte over the wire." How do you do that? Well, I guess it starts with where you embed your pages when you render them out. So we have this React component here. You can set the title, include stylesheets, and also import the client-side code. And that's why this is important — I'm going to open up the network tab.

00:33:20 - Anthony Campolo

We can't see the network tab because the font is super small — can we bump it up?

00:33:27 - Peter Pistorius

I'll just restart my server here. Okay. So here we have the network tab. What you can see is that it's importing a whole bunch of chunks — React Refresh, because this is development mode. So it's importing JavaScript, CSS, images, and things like that. But because I control the document, I can actually turn off client-side hydration — so it's purely server-side rendered. If I refresh this, you're seeing it just pull in the CSS, the favicon, and HTML. This is just HTML now, and I can click around and nothing will happen. There's no interactivity, no JavaScript.

Why is that important? You can keep your marketing site — or parts of your site that don't require any JavaScript at all, not even React — completely separate from the parts that do. And these are all server-side rendered. You know how you've sometimes built a website where the marketing site tries to figure out if you're logged in, and you see this thing that says "Log in," and then all of a sudden it flashes and says "Go to dashboard"?

00:34:46 - Peter Pistorius

That's because it's loading the whole page, loading a ton of JavaScript, and then running a separate query to a server that says, "Hey, is this person logged in? Oh yeah, they are." Flip the button. Here, you can just do it properly from the start.

00:35:02 - Anthony Campolo

So Fuzzy's asking a question: shouldn't the script tag be deferred or async module?

00:35:06 - Peter Pistorius

No. We actually use an optimization here where we preload the module to begin with. So the very first thing we do when we hit this is start preloading the module. Then after the route comes into place, we execute it if it is imported. We've gone around this a couple of times, and my description might not be 100% accurate because I didn't actually write this code. But before we implemented this, what we were seeing was a delay in when hydration or interactivity would be available. Because we were doing it here down at the bottom, interactivity would only happen once everything had finished loading. This is streamed down to you as well, so we want to do this as quickly as possible. That makes your time to interactive really fast. And if you are shipping a Redwood SDK app, you are almost 100% guaranteed to get a 100 score on Lighthouse without trying.

00:36:12 - Peter Pistorius

You have to try really hard not to. And I think that's because we have taken the fundamental pieces of the web and made them first class.

00:36:27 - Dev Agrawal

Does this do any of that fancy event replay that React has, where if React hasn't hydrated the page, it's going to record any user events that happen and then replay them once hydration is complete? Is that a thing?

00:36:48 - Peter Pistorius

I don't think so. I've never experienced that or seen any code that could make that happen. So I've just turned client-side hydration back on. Right, let's have a look here quickly at the HTML. Let's turn it off again and refresh this. So you see down here we have this script tag that's included in the page. This is React Server Components flight data. What this tells the client-side React to do is what to import and how to get things booted up. And it's all in this JSON.

00:37:30 - Anthony Campolo

Tailwind in there.

00:37:32 - Peter Pistorius

Yeah, yeah, it's all in there. But the problem is none of this stuff will work if we don't have any client-side code in it. So here I'm going to enable it again. Now the client-side code will deal with this and make it interactive. What you're seeing now is I'm clicking on these little emojis and they're appearing on the screen, or I can type one, two, three, four and they'll appear on the screen. This works through React Server Components. Another thing that I wanted to show you is how, like we said, we give you access to every byte over the wire, and that includes the client-side hydration. So if you open up client.tsx, you'll see that it imports client and initializes it. I can just put a console.log in here, or I can enable something like TanStack Router. If I wanted to do client-side navigation, I could do it in here.

00:38:31 - Peter Pistorius

So my initial payload would be server-side rendered, and then I would initialize React and could enable some kind of browser-based navigation. Okay, so that's the one thing I wanted to show you. Now I want to show you how this is implemented, how React Server Components work. So we have the reaction page. It doesn't have use client at the top, so that means it's a server component. What's happening here is this JSX is getting rendered out into HTML, and there is no other functionality included. But the emoji picker is a client component, because it has interactivity like state and click handlers. So how this works is, if you push a key down or click one of these emojis, it calls a server function.

00:39:49 - Peter Pistorius

The server function is just imported from here, and you execute it like this. So what this server function is, is just a bunch of functions that have use server at the top. What this is doing is storing state on the server. It's taking a reactions array and appending the current reaction to it. And then there's another...

00:40:19 - Anthony Campolo

Pause you right here for a second and go back to this file. Yeah. Can you talk about the real-time aspect to Redwood? This is really important and fairly significantly different because now we're off GraphQL. We don't have to worry about any of that bullshit. We can actually do this now.

00:40:36 - Peter Pistorius

So I will show that to you a little bit later. I just want to go through the whole app flow, and then I will show you the real-time stuff. But yeah, you ruined the aha moment for me.

00:40:51 - Anthony Campolo

I just wanted to bring it up because we're seeing it in the code, and because Dev specifically has been working on this. He was doing this for Solid, so he's going to have a bunch to say about it. But yeah, that's fine. Continue with the flow you were going on.

00:41:02 - Peter Pistorius

Cool. Yeah. This is actually one of the features that we think is experimental because we haven't built enough on top of it yet.

00:41:13 - Anthony Campolo

I want to use it, actually, so that would be a potential thing.

00:41:22 - Peter Pistorius

So addReactions appends a reaction to the array. Then we have another function called getReactions, which is on the reaction page. You'll see that this is server-rendered. So when we introduce a new one here, it adds it to the array and then it appears on the page. Do you want to know how that flow works and why I think it is actually web-first, like it supports web APIs?

00:41:54 - Anthony Campolo

Is there a diagram, and can we ChatGPT out a diagram right now?

00:41:59 - Peter Pistorius

I think I can show you the code and then we can draw one at the same time if that helps.

00:42:04 - Anthony Campolo

That'd be cool.

00:42:06 - Peter Pistorius

And we can go through that. So okay, let's do that. We have this addReaction thing. It's a server function. What React Server Components does in the background, and I mean Vite when it's transpiling, is it has this step where it looks for use server in your code and says, "Oh hey, all these functions that are being exported here, we have to expose them as an RPC." So it creates a unique key-value pair for this particular function. It's actually the file name, so it'd be something like src/app/pages/reaction/functions.ts, and then #addReaction, #getReactions, #resetReactions. So it creates this key that maps to the particular function. Then on the client side, when I call this function, it's going to create a fetch call to my server that has that key in it. That will execute this function on my server, and then that function will return two things.

00:43:13 - Peter Pistorius

It will first return the return value from this function. If it had one, like this one, it returns reactions. Then it will return the entire rendered page. So this whole thing here will be returned as flight data. Sorry, I'm trying to read the comments as well while I'm speaking here, so let's have a look at the network debugger. Let's clear these off. So I'm going to run this. Oh, okay, here we are now. Just to make this full screen. Scroll down to the bottom so you can see here what's happening: we're posting to the server, and it's got this __RC thing, and then it's got the RC action ID. You see there's the file name and the function name, and then you'll see we're also pushing in this emoji. What's happening is it's returning flight. So it's saying, "Hey, this is the new page." React's client-side stuff picks this up and does the render diff on the front side.

00:44:36 - Peter Pistorius

So you get this experience where it looks like the stuff is just appearing, but it's actually being rendered by React through the server, et cetera. And that's how React Server Functions work.

00:44:52 - Dev Agrawal

Thanks. For people who might not be familiar, you're using the term flight. Do you want to give a quick explanation of what flight or flight data means?

00:45:03 - Peter Pistorius

Yeah. So this is actually what the React team calls it. I call it the RSC payload, and I think that makes more sense. That's what it is. It's an array, right? And you'll see it's got all these weird little things. It's its own DSL. It'll say this is an import of this file and this file, so it imports those over the wire. Or actually, I don't know. I don't know enough about this format to be able to tell you exactly what it does, but it explains what appears on the page or what has changed on the page. Yeah, that progressive JSON is exactly what you're seeing here.

00:45:54 - Anthony Campolo

I'll read out some of these comments that we were just showing on screen. Bro Nifty, you were saying he was chatting with Ryan of Node and Deno about basically what we were calling self-hosted Durable Objects, and this is very much the concept. And Fuzzy said React takes the Atkins diet and comes out looking like Billie Piper after... okay, this is a lot of references. So Atkins? Know who Billie Piper is?

00:46:19 - Anthony Campolo

Meat, I think. I have no idea who Billie Piper is, either.

00:46:23 - Peter Pistorius

[unclear]

00:46:27 - Anthony Campolo

Billie Piper is the actress who played Rose Tyler, the companion to both the Ninth and 10th Doctor on Doctor Who. You Europeans.

00:46:37 - Dev Agrawal

All right, I'm back. I also posted a quick link in chat to a recent blog post by Dan that talks about this idea of streaming data over JSON. I think if someone wants to look more into what flight data is, or this special form of serializing data over streams, that's a pretty good read called Progressive JSON.

00:47:10 - Peter Pistorius

Yeah, I love that blog post. It was fantastic. Thanks for sharing that. It gives you a lot of good context. So that's why I say that RSC is actually web-first, because it's just using fetch under the hood. There's a whole bunch of moving parts there: a client part, a server part, and a transpilation step that maps these things out. You could actually write those maps by hand, but it would kind of suck. Maybe they should have done that first. They should have been like, "All right, if you want to expose a function as an RPC, put it in this thing and map it yourself." That might have been better for people to swallow than doing the step there. And you see this in TanStack? I think they actually use a function to mark whether something is a server function or not. So there are alternative implementations.

00:48:12 - Peter Pistorius

But I wanted to stick to what I felt was what the React team put forth, because I think what we're building is a really good answer to some of the other more popular React frameworks. If you're looking for something that is not as opinionated, that is just bare-bones and clean. Okay, so there's something I want to show you, and it's real time. We support the ability to control every byte over the wire, and one of the things that we introduced because we are building on top of Cloudflare is real time. They have this thing called a Durable Object that allows you to have thousands of WebSocket connections, and it can scale infinitely, let's just say an infinite number of WebSockets. We wanted to make that part of the framework, because we have this idea that React could be really good at that as a first principle. If your state lives on the server and all your rendered diffs, or all the things, are coming from the server, you could just push that up to the server and make real time work.

00:49:26 - Peter Pistorius

So I'm just going to copy this code here, and I'm going to place this into client.ts. If you remember correctly, we have this file here, our document, which has this client.tsx thing. "I thought state should live in the server signal." I don't know what that means. I'm sorry.

00:49:50 - Dev Agrawal

That's a reference to the real time stuff that I was working on.

00:49:57 - Anthony Campolo

I know what it is. It's a signal.

00:50:00 - Peter Pistorius

All right, so what I did was replace the initialization of the client over here with the initialization of a real-time client. What we do is the first request upgrades itself to a WebSocket, and then subsequently we pass all the requests and responses over this WebSocket. And we have this key here, which is the page name. So what's happening here is I refresh this. You saw all those emojis appear because that's the state stored on the server. So if I reset the server and start it up again, there will be no more emojis. There's just the one, the initial state, and then I can add a whole bunch more. Now if I open up another browser window, I'll stick those in there. You'll see that initial state rendering in, and then, oops, I can hit one and two and three and just spam this like crazy. And you get real-time React. I didn't change any of the code.

00:51:00 - Peter Pistorius

I'm just using server actions. I'm still doing page renders. But me and this other browser now are in the same key, this part here. We're on the same page. So I can also be explicit here and make this just /, and then my page will be real time. That's how we're thinking about this. There are some other nuanced things around this. You can do client-server-client, or you can also do server-client updates. There's a whole bunch of different ways that you can communicate. Let me just make this full screen. So we've got client-server-client, and then we've got server-client updates. These docs really go in depth about how this works. We'd love people to try it out and let us know where it doesn't feel right, because this is one of our experimental features. Some APIs might change.

00:52:00 - Peter Pistorius

So yeah. I don't know if people know this, but we're also starting a fellowship for open-source developers. One of the people that we're sponsoring to begin with is Johannes Schickling, and he just built something called LiveStore. LiveStore is like a sync engine for data, and he's going to improve it on Cloudflare. There's a whole bunch of stuff that he wants to do around this. This might be a better way to do real time, one that doesn't send full payloads over the wire and things like that. So yeah, this is LiveStore. You should check it out. It's got a beautiful website. We're sponsoring Johannes for three months, and he's going to build some really cool stuff on Cloudflare and help us with Redwood SDK.

00:53:07 - Dev Agrawal

Yeah. Super excited about LiveStore. I'm hoping that in the next week or a couple of weeks, I can get a chance to play around with it, see if the Solid bindings are doing what I'd expect, and maybe update them as well.

00:53:25 - Peter Pistorius

Nice.

00:53:26 - Dev Agrawal

Super. That'd be great.

00:53:28 - Peter Pistorius

Cool. Maybe we can hire you to update those for Solid.

00:53:32 - Dev Agrawal

Probably. Yeah, I would be happy to see people and companies actually putting money behind Solid. There is a bit of that going on.

00:53:46 - Anthony Campolo

Find an eccentric billionaire who has a bunch of money to give away. That's the only way it's gonna happen. So. Thanks, Tom.

00:53:54 - Peter Pistorius

Uh, yeah.

00:53:56 - Peter Pistorius

Yeah, you need one of those. Wait. Doesn't Solid have a good sponsorship already?

00:54:00 - Anthony Campolo

Not a billionaire. Yes. Billionaires backing Solid? No.

00:54:05 - Dev Agrawal

I mean, yeah, Sentry employs Ryan to work on it. There's a bunch of open-source sponsors on Open Collective, and that money goes to fellowships very similar to this, where we hire people from the community or pay people from the community to build some cool stuff around Solid. And last year there was a hackathon, which I ended up winning, so I took a bunch of...

00:54:29 - Peter Pistorius

Of.

00:54:30 - Dev Agrawal

Money, I guess.

00:54:32 - Peter Pistorius

Oh, you actually won money. You can win money at hackathons. What are you talking about? I didn't know that's a thing. I thought it was just for the, like, clout or something.

00:54:39 - Dev Agrawal

Yeah, it was an open-source hackathon, funnily enough. It had money. The project got 7,000. Not too much, but it was good enough. And it was the...

00:54:51 - Peter Pistorius

That's a that's a shitload of money. I live in South Africa. That's like a lot of money. Yeah.

00:54:56 - Dev Agrawal

No, for sure. Yeah, for India as well, that was a lot of money. And the project that was...

00:55:01 - Peter Pistorius

What.

00:55:03 - Dev Agrawal

Exactly.

00:55:03 - Peter Pistorius

What are your parents? Are they still in India?

00:55:07 - Dev Agrawal

Yeah, my entire family is in India. I'm just here as a visitor. But yeah, the project that ended up winning was an extension to Solid Start that added real-time capabilities. So this is something that I am personally super passionate about, about how frameworks especially... yeah, go ahead.

00:55:25 - Peter Pistorius

What I just showed you, does that raise hairs on the back of your neck, or does it look relatively okay?

00:55:35 - Dev Agrawal

So what you shared looks a lot like how I initially approached real time. But how I was initially approaching it was more framework-agnostic, where you can use this approach in whatever framework. What I ended up doing for the hackathon was very specific to Solid. The basic concept was that, along with the use server directive, I introduced a use socket directive, which would communicate over WebSockets instead of HTTP. And you can create and pass around signals, which are reactive state, from client to server or server to client. That was the way that I had reactive updates. Whereas the way that you're doing it is a lot simpler, a lot cleaner, where you just rerender a route or a server component from the top down on the server, which is going to go and fetch all the data it needs.

00:56:36 - Dev Agrawal

And then you use a key to invalidate it when there's a server action. That was my initial approach, which was a Next.js library called Plug, where you use the key to invalidate a real-time update, and then all the clients would refetch. Maybe even the server components would get regenerated. But obviously it didn't have good integrations into Next.js because it was just a library. So what you're doing is basically a much cleaner version of that because you can build it into the rendering or the framework itself. So yeah, it's definitely a very interesting approach.

00:57:14 - Peter Pistorius

And we have Cloudflare backing us up. A lot of people thought that our decision to go all in on Cloudflare was controversial. Like why? What about lock-in? And it's like, okay, I can put on my tinfoil hat and think about all the things that could go wrong with Cloudflare, or I could just try and build some awesome technology and see if it sticks, if people love it. That's good enough for me. And maybe ten years down the line Cloudflare is like, "You know what? We're going to delete all of this stuff." Everything they've done is open source, so I don't really think there is that direct of a vendor lock-in. I think what there is is a deep amount of productivity that you gain from using Cloudflare as your provider of choice. And it's free. Like, where on earth do you get something like that? And it's everywhere. There are 330 nodes all over the world.

00:58:18 - Peter Pistorius

I have one in South Africa, which is down here at the bottom of nothing, and the sites that I build are fast. That matters to me. A kid who's living in a rural community, nowhere on earth, in a place that doesn't really feature, can build software, can ship it, and it can still feel fast for them. I think that's really powerful. They also don't have to pay $20 for a hosting provider, $20 for a database, $20 for an auth provider. Everything is there that you need to build software. And you can really focus on the software that you want to write, not having to plug different sets of infrastructure together. So you're not trying to figure out what service to use, like, should I use this or should I use Postgres? Sorry, I'm ranting here, but...

00:59:07 - Anthony Campolo

No, I think D1 is what really pulls it all together. When I was first looking at Cloudflare, it was in 2021. I found the original forum post from when I was first like, "Hey, we should try and do Cloudflare for Redwood." And it was April of 2021. It was completely impossible in every single way you could possibly imagine. One of the biggest things is that there was no way to do the database. You couldn't even run Prisma, let alone a database. So once they got D1, that was a huge piece that actually made this feasible.

00:59:36 - Peter Pistorius

Yeah, absolutely. They've been improving their offering year on year, and it's faster than I can imagine. They have really solid engineers and a solid engineering culture. I'm sitting from the outside and looking at what they're doing, and it seems like a startup. They're running their teams like startups. They ship fast, and they put awesome things out there. Someone has asked, did I not consider Deno? And I did.

01:00:06 - Anthony Campolo

We could list ten things Cloudflare has that Deno deploy does not have. So that's. It's not even close.

01:00:12 - Peter Pistorius

And the thing is, they.

01:00:13 - Anthony Campolo

Also, they don't have an African region, I'm sure.

01:00:17 - Peter Pistorius

And another thing to consider is that they actually are building their own framework. So I mean, Deno is building their own framework. There's no way that I can enter that conversation and have a better seat at the table than someone who works for them. So when I looked at that, I was like, okay, I don't want to compete with this. There is already a framework that is doing this.

01:00:44 - Anthony Campolo

It'd be like building the framework on Vercel. I'd be like, I'm going to make a framework around Vercel. It's like, are you now? Yeah.

01:00:50 - Peter Pistorius

That's a good. Yeah. It's like I, I found this hosting provider, they're called Vercel. I'm going to build the best framework for them.

01:00:56 - Anthony Campolo

So Cloudflare doesn't have 30 frameworks; 30 frameworks work for Cloudflare because every framework eventually made it work for Cloudflare. Cloudflare frameworks used to be things like stuff Luke was writing, like Worktop, that had like 200 GitHub stars. That was a Cloudflare library from back in the day. Hono is kind of like a Cloudflare library. But again, it's not just Cloudflare. There's a suite of things that are meant to just use the standard JS implementation, and so that kind of goes along with the Bun and Deno stuff as well. There are certain deployment platforms that are now leaning more into that. But there's not a lot of really well-known frameworks that were just started around Cloudflare and built around Cloudflare specifically, except a couple from people who worked at the companies, and they did not become very popular. They were very interesting, though.

01:01:48 - Peter Pistorius

I just want to share my screen again, and I want to show you some of the other stuff about the framework. Sorry, is it okay for us to stay like this at this point?

01:01:54 - Anthony Campolo

This is really great, man. We can go any direction you want to. Feel free to drive the conversation and we'll ask questions when we can.

01:02:00 - Peter Pistorius

Okay, so one of the things that I love about React, and I mean they didn't invent this, but they really popularized it, was the thought that if stuff changed together frequently, you put it together in the same folder. I wanted to bring that to the way that you define routes. So if you have a look here, you're defining a route and then we're actually returning a JSX page. You can also define an API route, and then you can return a response. So you're co-locating API routes and JSX routes in the same space. Let's just pull up the browser here. Over here, /api, hey. So you can co-locate these two things together. And if you wanted to group them by prefix, you could say, "Hey, actually, what I really want is these things to be under real time." Let me just grab that, put that in an array like that, and then I need to access this via real time, and then I get that same thing.

01:03:18 - Peter Pistorius

We have middleware. This runs before every request. It's global. But sometimes you really want to scope things down to a particular request, and it's really annoying to have to grab the request and do something on the URL if this or that. That's how you have to do it if you wanted to do authentication just on a particular URL, or didn't want to have sessions or things like that. You could actually move this down here. You can move this into the document or the prefix, but that's still for all these things. Actually, you can't do this on the prefix; you can do it on the document. Sorry, I'm making assumptions here, but I want to show you something called an interrupter.

01:04:21 - Peter Pistorius

So an interrupter is a locally scoped, per-route piece of middleware. The way that works is you create a route, wrap it in an array, and then declare another function. This function can interrupt the request flow. So what you could do is say return new Response(...) and then give it a status code. We could do, like, 404 or something like that. So this one will run first. This one will not run, so we won't get "hey," we'll just get this page can't be found. Or we could do something like, if request.method is not equal to POST, and say, I don't know, 503. I forget. All right, it's unable to handle that request. What you can also do is then pull this out and create a function.

01:05:30 - Peter Pistorius

So you can say const isPost = ..., and you can stick that in here. You can start pasting this throughout your codebase. You can create these distinct little functions that can validate request methods, or whether the user is authenticated, or whether they have admin rights, et cetera, and introduce them here. So you can say if there's a POST, and if they're an admin, or if it is authenticated, and these will run sequentially. If they fail, it will interrupt. Then you're just returning a response. So if someone is not authenticated, return an unauthenticated header and also redirect them at the same time to the login page. That's the surface area of the router. The router's implementation is just this prefix function, the route function, the render, and then there's another one called layout, which allows you to handle nested layouts. And that's really all we have. We give you the ability to return JSX, which is then rendered into HTML, streamed down to the browser along with the flight, or the payload.

01:06:47 - Peter Pistorius

And then it hydrates on the client side. What's really cool is, because we're just doing request-response, you can actually serve Hono from Redwood. If you prefer to write your API routes in Hono, just do that.

01:07:06 - Anthony Campolo

You can do that with Azure too. You can like just stick fastify in it if you want.

01:07:13 - Dev Agrawal

Yeah, basically anything that works with standard request-response, right? I guess this is one of the nice things about the movement toward everything using web standards, is that you can bring five routers into your app if you want.

01:07:28 - Peter Pistorius

Yeah, that's.

01:07:28 - Dev Agrawal

A great idea. But you can.

01:07:31 - Peter Pistorius

Yeah. If you're trying to port something over from some other legacy system, and you're like, actually, we want these things, we want to put a React front end on our API, just bring it in. Or just send the request directly to the API and return the response, proxy it essentially. This is one thing I wanted to show you when you said that. The standardization of request-response is so nice. It's more than that. I like to call it Unix pipes for the web browser, because you can literally take a request and pass it from service to service. And I see that in uploading files.

01:08:11 - Anthony Campolo

Bump your file up.

01:08:13 - Peter Pistorius

Oh yeah. Sorry. So this is how you handle file uploads in... oh no, I wanted to get the client-side stuff. Wait, let me quickly go grab another codebase here.

01:08:28 - Anthony Campolo

Yeah, I was kind of curious to talk a little bit about the the database and storage aspect of it, but, um, you can kind of share your thing first and then I'll ask some questions about it.

01:08:38 - Peter Pistorius

Okay. All right. So this is an app called Buildable. It allows you to create invoices, and you can upload a logo for one of your invoices. So I'm just going to find the page that does that. I think it's over here. Nope, that's not it. It's over here. Can we take, like, a two-minute break?

01:09:11 - Anthony Campolo

You can take a break, and me and Dev can chat and fill time while you do something if you need to.

01:09:17 - Peter Pistorius

I need to do something. I will be back in a second.

01:09:20 - Anthony Campolo

Do it man.

01:09:22 - Dev Agrawal

No worries. We can keep filling up time with random chatter.

01:09:26 - Anthony Campolo

Oh, actually, I can present my screen. I want to show it real quick. Amy, because she's amazing, has Awesome RedwoodSDK already. I used to manage the last one, Awesome Redwood. It's got me on there. I probably did like 90% of the maintenance of this thing, so it's got a ton of stuff. Every single thing on here is at least three years old, so no one should use this. This is a cautionary tale. Stay away from this repo. This is what you want.

01:10:00 - Dev Agrawal

Thanks.

01:10:01 - Anthony Campolo

And so it's got drizzle example. That's okay. That's interesting. I was going to ask how important really is Prisma to the framework at this point. Doesn't seem like it's that important anymore because it used to be the thing that.

01:10:13 - Dev Agrawal

You would.

01:10:13 - Anthony Campolo

Start with to generate your GraphQL schema and also your scaffolding and all that stuff's gone now.

01:10:19 - Dev Agrawal

Mm-hmm. Yeah. I mean, I see your usage with Prisma. It's in the starter project, but I believe the starter project...

01:10:27 - Anthony Campolo

Standard is what I'm saying. It comes with Prisma but I'm just asking like how can I rip it out and use something else.

01:10:34 - Dev Agrawal

Yeah. Because there is a minimal starter that doesn't have Prisma, so you can bring whatever in.

01:10:42 - Peter Pistorius

Yeah, we have one.

01:10:43 - Dev Agrawal

Yeah, that's one.

01:10:44 - Peter Pistorius

We have Drizzle and we have a Drizzle example. And we also have a Better Auth implementation.

01:10:52 - Anthony Campolo

Well, I took that actually because the main docs only have the passkey example.

01:11:02 - Peter Pistorius

Yeah. Yeah.

01:11:07 - Anthony Campolo

This must be it.

01:11:10 - Dev Agrawal

Yeah. I'm sure there are community templates for every framework that use Better Auth. It's one of the nicer things that has happened since auth got released. I'm happy I don't work at Clerk right now. I'm sure there are...

01:11:26 - Anthony Campolo

No, there's no Clerk example right now with this new one.

01:11:31 - Peter Pistorius

I mean, technology is fashionable, and I can almost guarantee you that this shape of Better Auth is not the last one that we'll see.

01:11:43 - Anthony Campolo

Clerk working with Astro, too. I was like, oh my God, now I have to switch to Better Auth. After trying Better Auth in Astro and then going to Clerk, I'll go back to Better Auth.

01:11:52 - Peter Pistorius

Yeah, yeah.

01:11:54 - Anthony Campolo

Or I can just build the first Clerk example.

01:11:56 - Peter Pistorius

I mean, none of this actually matters to your users, right? So yeah. Okay. I want to show you how file uploads work and why fetch is such an amazing piece of tech to build on top of. So this is a standard input for a file. It accepts images, and when you change the file, it grabs the file from the target, constructs a form, appends the file to this form thing, and then pushes it up as fetch. So it says, hey, the body is the form data, it's a POST, and it sends it up to this route here.

01:12:38 - Dev Agrawal

That route, is that a utility for type-safe URLs throughout?

01:12:44 - Peter Pistorius

It is. But we are going to introduce one that is automatic. Because with this one, what you're literally doing is passing in the string, and then it allows me to generate the type-safe URL.

01:13:03 - Dev Agrawal

Yeah. This is almost how TanStack Router works, except that you give it the URL pattern and then the parameters separately, and at runtime it will come up with the string.

01:13:18 - Peter Pistorius

So what I want is, if I define a route in my worker, I want that to be typed, because what if I decide to change my route and then ship something that is referencing a broken string? That's the number one reason why I want this. But ours doesn't do that right now because I'm explicitly providing those things. I need to figure out how to do this without a generation step. Maybe it just isn't possible, in which case I just won't do it. Sorry. Yeah. Okay. So this is a simple way to send up a piece of form data to a server. Then on the server side, how you actually deal with this is you have this route, you pull out the form data, you pull out the file from the form, and then you stream that directly into R2. So R2 is Cloudflare's bucket storage, or file storage.

01:14:19 - Peter Pistorius

So you'll see here I just say environment.R2.put, I give it a name, and then I just stream it inside. That's it. So I pass it directly from the browser, it comes through my route into R2. How easy is that?

01:14:41 - Dev Agrawal

This looks clean.

01:14:44 - Peter Pistorius

And then if you want to actually send that file down to the client as well, it's the same thing. So it's like download: you get the object from R2, and then you just stream it down. So you say new Response(object.body), and that's it. So there's no crazy libraries or abstractions on top of this. We're just using fetch, Request, and Response, using the technologies that the browser gives you. Yeah, it makes things really simple.

01:15:20 - Anthony Campolo

So Dev is making a joke about the name R2. The name is the same way that HAL gets his name in 2001. HAL shifted one letter in the alphabet each way. Think about it.

01:15:36 - Peter Pistorius

It. No.

01:15:38 - Anthony Campolo

You guys are smart. You'll figure it out.

01:15:40 - Peter Pistorius

Okay, I need to write.

01:15:45 - Dev Agrawal

You're making me pull up the English alphabet.

01:15:48 - Peter Pistorius

It's too late.

01:15:50 - Anthony Campolo

Once you realize it's gonna blow your mind.

01:15:51 - Dev Agrawal

Oh, it's IBM.

01:15:54 - Anthony Campolo

I never knew that until like a month or two ago, and someone on a podcast mentioned it. I'm like, that's incredible. So R2 is S3 shifted over one.

01:16:04 - Peter Pistorius

Shifted back one.

01:16:05 - Anthony Campolo

Shifted back one. Yeah. Shift. When I say over, I mean in either direction.

01:16:09 - Peter Pistorius

Okay. Yeah. Interesting, huh? Smart.

01:16:15 - Anthony Campolo

Because it's meant to specifically be a replacement to S3. They made S3 compatible API. They created a tool to specifically migrate your data from S3 to R2. It was a huge thing.

01:16:25 - Peter Pistorius

Yeah. And that thing has got a really great name. It's got the word sucker in it. It's called, I don't know, like the Ingestor Sucker or something like that.

01:16:40 - Dev Agrawal

Wow. We found at least one company that's good at naming things.

01:16:45 - Peter Pistorius

The Super Slurper. Yeah. I mean, sucking and slurping is basically the same thing. The Super Slurper. It's a really great name, and you can tell that it's a company that has fun.

01:17:00 - Dev Agrawal

I mean, Cloudflare, out of every company in the world, you would expect them to be good at cache invalidation. So they're probably also good at naming things.

01:17:11 - Peter Pistorius

That is good.

01:17:13 - Dev Agrawal

That's okay.

01:17:15 - Peter Pistorius

Yeah. That's it.

01:17:17 - Dev Agrawal

That's it. Thank you very much for the tour of Redwood. A lot of things seem very exciting. I just have so, so many questions. But I want to first make sure that you have talked about the things you want to talk about, and if Anthony has things that we might want to address first, I can keep going about talking about frameworks.

01:17:42 - Peter Pistorius

I have spoken about everything I want to talk about, and it was nice to do some Q&A.

01:17:48 - Anthony Campolo

Then from dev.

01:17:49 - Peter Pistorius

See you guys.

01:17:49 - Anthony Campolo

Later. I'm just kidding.

01:17:51 - Peter Pistorius

Um.

01:17:52 - Anthony Campolo

I'll show my AutoShow implementation, but we should keep going. Dev, you should ask whatever you want. We can take as much time as you need.

01:17:59 - Peter Pistorius

Just so you know, it is really late for me, so.

01:18:02 - Anthony Campolo

Okay.

01:18:03 - Peter Pistorius

My bedtime is around about now. I'm a parent to a three-year-old, but I'm going to stay here with you. Let's...

01:18:11 - Anthony Campolo

15 more minutes. Is that okay?

01:18:13 - Peter Pistorius

Yeah. Yeah, yeah, yeah. I'm not going to go sleep after this anyway. I'm probably going to sit there and be, like, thinking.

01:18:20 - Dev Agrawal

Of course. Okay. I guess the first thing is, what happened with GraphQL? I'm sure both of you can talk to this question, but what was the original idea behind building a framework around GraphQL, and what are some learnings that pushed you away from it, especially when rebuilding or rethinking what a framework should look like?

01:18:52 - Peter Pistorius

Yeah. So a lot of the things that we put into RedwoodJS were things that we learned at a company that Tom was building with one of the other GitHub co-founders called Chatterbug. It was a language-learning startup, and they had a mobile app and a web interface. So that kind of multi-client world, where the developer could define how they wanted the data, made a lot of sense on paper. In practice, though, I don't think it really worked out. I don't think that a tool like GraphQL works really well for a startup. There's way too much boilerplate to make it work properly, and the majority of the time, the same person building the front-end app or the mobile app is the same one building the APIs. So it didn't really make sense that you're offloading this to separate teams.

01:20:00 - Peter Pistorius

Yeah. It was a really trendy piece of technology back then, and I think there were even GraphQL conferences. I think that's a really, really good lesson: just because something is trendy...

01:20:15 - Anthony Campolo

I spoke at like five GraphQL meetups, dude. I worked at GraphQL company for an entire year. Dude.

01:20:20 - Peter Pistorius

Do they still exist?

01:20:23 - Anthony Campolo

You remember StepZen?

01:20:26 - Peter Pistorius

Are they still here?

01:20:27 - Anthony Campolo

StepZen? They were acquired by IBM. So they're now one of 100 services. He had worked at IBM before he created the company, on the Watson team way back in the day, early AI. That's cool. But yeah, it was a good move for them because that made the most sense. So they're now probably one of 100 services on IBM's cloud that no one uses.

01:20:50 - Peter Pistorius

And the thing is, for a lot of corporates, when you give them those lists of things like separation of concerns, multi-device, and blah, blah, blah, that makes a lot of sense to a person working in a big corporation. They're like, yeah, this covers all the bases. I'm not going to get fired for making this decision. So maybe that makes sense. You can also speak, I guess, quite a lot to what happened with GraphQL.

01:21:25 - Anthony Campolo

Yeah, I actually went through a whole round of interviews just a couple of weeks ago with Apollo, and I thought I was going to get the job, but then they had layoffs and did a hiring freeze on the role. So I think it was just a bad point in time. But there was a moment where I was like, oh, I'm about to do GraphQL again. I loved GraphQL. I feel like a lot of people's problems with GraphQL were partly self-inflicted because they weren't willing to accept that you're going to have to do it a certain way, and they would bristle against that and be like, no, but I like the ways I did things before. You kind of had to fully buy into it, and Redwood made that really nice. The problem is that everyone who complained about GraphQL was complaining about not having a thing like Redwood, not realizing that if they had used Redwood, it would literally solve like 90% of the things they were complaining about with GraphQL, which is too many weird libraries that are changing and breaking, and you don't know how to do auth, and you don't know how to secure the endpoint itself.

01:22:25 - Anthony Campolo

You don't know how to do all sorts of stuff. So Redwood made all those decisions, and then Redwood itself kind of got into a mode where the React core library was moving in a different direction, and it couldn't continue with the progress of the underlying React framework while still doing the GraphQL thing. So there had to be a split at some point where you had to rewrite the whole framework. There's a really early podcast episode in late 2020 or early 2021 where me and Chris were talking about things like Snowpack and Vite and React Server Components. React Server Components were announced in December of 2020. I remember the day after it was announced we had to do a podcast episode. We were talking about it, and I was saying, you know, we're using Webpack and Babel and we have all this stuff already. I was like, you probably have to rewrite the entire framework from the bottom up to use these new tools. That's exactly what I said.

01:23:19 - Anthony Campolo

That's exactly what you ended up doing, like four years after the fact.

01:23:23 - Peter Pistorius

Yeah. So I didn't come to the decision to build a new framework from scratch lightly. But I looked at what we had, I looked at our growth, and it had stalled. I don't think that what we had built was really going to translate into more users in today's landscape. I think RSC is something that we tried to implement in the framework for a bunch of years; it just didn't pan out, and we would have been left with a shape that just didn't make a lot of sense, you know, client-side rendering, this website and others on a different server. And I really wanted to build on a platform. I'm getting off on a tangent here, I'll come back to this a little later. I really wanted to give people the ability to exit out of the framework in case the framework didn't exist anymore.

01:24:30 - Peter Pistorius

I wanted to make sure that it was composable, that you could plug literally anything you wanted inside of it. That meant that I had to expose those parts to you and do it in an idiomatic and pragmatic way. I didn't want those black boxes that we had in RedwoodJS. Actually, the inspiration for what we've done now is translating back into Redwood GraphQL. We're going to unpack it so that the people who have invested in that framework can continue using it long-term, but they can own every single little piece. Someone asked, are we going to fork Preact? No, no. I really want to stick to React and web standards.

01:25:16 - Anthony Campolo

You assume that anything parasocial fics says is not actually true, or something you need to respond to. Seriously? Ever.

01:25:23 - Peter Pistorius

Okay. I mean, I do think it's great. It's super ambitious. I think, you know, someone was saying that one of the lead developers at react, uh, or on Preact actually works for Shopify, so maybe it makes sense. Yeah. They said it's a.

01:25:37 - Anthony Campolo

Yeah, they hired the team and the remix team. That's why Preact and remix are now the same framework, because they hired all those people like two years ago, and people now are just realizing it because they don't pay attention to these things.

01:25:49 - Dev Agrawal

Yeah. And React is heavily used within Shopify for a bunch of things here and there.

01:25:55 - Peter Pistorius

Yeah. I think what they're doing is super interesting. If you look at their principles, they're so similar to ours. Given that, I think that there's probably going to be a level of success. I do think that they're going to change the name. I don't think Remix v3 is going to work for them long term, simply because of the AI and the legacy memories that it has. Billie Piper, who's that, man? I'm just kidding. I know who it is. She's the person from Doctor Who.

01:26:37 - Anthony Campolo

Uh, Chris was here. He would get it.

01:26:40 - Peter Pistorius

Yeah. So one of the things... now I forgot the thing that I wanted to speak about when I said I wasn't going to talk about that right now. Oh well. Okay. So we all know that programming is becoming less emotionally difficult, or let's just say less difficult. When I say emotionally, it's because there are things that I don't like to do as a developer. I don't like to build forms. I don't like to build authentication. But my day-to-day job requires me to do those things. Now I can just ask AI to generate it. The emotional lift on me as a developer is lighter. I can offset all the stuff I don't like to an LLM. So I like to say that coding isn't difficult anymore. It's not the hard part of writing software; it's the architecture. Oh man, that guy's going to go, damn it. It's the architecture, and it's when you ship to production.

01:27:39 - Peter Pistorius

So connecting services together: we could probably get AI to figure that out later with MCP servers and things like that, but it's still tough. It still takes me out of flow, and it's the thing that I hate the most. Whenever I ship, it's broken. Like, ah, I forgot to set that one secret, or the migration didn't run, or whatever. When you ship with Cloudflare, it's a single release command and it's live. If you want a staging environment, you just prefix CLOUDFLARE_ENV=staging, and it will create a new domain for you, a new database, everything new, and then you've got it on a staging environment. It feels like you're shipping things like you used to do with PHP. You're literally dragging and dropping a file onto the server, and the moment that's done, it's live. There's a lot of power in that. All of a sudden you can quick-fix things.

01:28:34 - Peter Pistorius

You can build something in an hour, have it live, and show someone. It doesn't feel like you're gluing together thousands of different services, creating API keys, and giving them your credit card. Actually, I like to talk about SaaS services as paying five taxes. Whenever you use an external SaaS service with the platform that you're building on, you pay five taxes. The first is you have to figure out which one to use. Say, for instance, you wanted a database. You go around, you look at all of them, you read their marketing pages, you look at their pricing plans. There's a lot of work there. Or you just ask someone for a recommendation because they did the work before you. Number two, you create an account. You give them your credit card details, and then you grab an API key. Number three, you figure out how the library works locally.

01:29:29 - Peter Pistorius

Sorry, yeah, let's just go with that. Number four, you have to figure out how to make it work in production. And number five, if you're lucky, you'll get a staging environment. So before you can even get to the point where you're feeling productive with an external service, you're paying a lot of that emotional baggage of being a developer. You're using all of that just to get online, and then it's there, and then you're stuck in the service for many years and you can't get your data out of them and whatnot. So you should own the stack, and Cloudflare allows you to do that.

01:30:07 - Dev Agrawal

Cool. No. Yeah, I think that's the five taxes should definitely be a blog post. And I want to reference this like, many times throughout my professional career.

01:30:18 - Peter Pistorius

I mean, you felt that, right? Like it's it's so real.

01:30:21 - Anthony Campolo

It was funny. I think that's the most fun part, and that's why I did it for like ten different frameworks and services. I just wrote a blog post for each of them, and then as soon as I got it working, I was like, all right, cool, what's the next thing? I guess the point was just having a deployed page with some text on it. It was never actually the point where I was building a substantial app with anything happening in it. But I figured out a billion different ways to deploy stuff.

01:30:47 - Peter Pistorius

Let's let's like, let's do this now. I'm gonna what I'm going to do is share my screen. Um, oops. And I'm going to show you.

01:30:57 - Dev Agrawal

How to implement Clerk in Redwood, and look at the five taxes.

01:31:02 - Peter Pistorius

No, I'm going to show you how easy it is to release something. Uh, is my font big enough? There we go.

01:31:08 - Anthony Campolo

All right, a couple more. NPM run release.

01:31:12 - Peter Pistorius

So I'm going to create a new app from scratch. Create Redwood SDK test app. All right. So we're just downloading this now, test app, installing the packages. I think we have about 200 megs of packages. The biggest one is MiniFlare, which is Cloudflare's local emulation environment that gives you a database, queue, and storage locally. It's really great. So when you install the packages and you have everything you need, I'm just going to see if this is working.

01:31:49 - Dev Agrawal

Also a quick shout out to Vite 6 and the environment API that makes something like this possible.

01:31:57 - Peter Pistorius

Totally, totally. Vite's amazing. Okay. Hello, world, we got that there. All right, now I'm going to release this. Yes, I wish to proceed with deployment. This is an app that has a database and a durable object. Oh geez, what was that authentication error? Okay, I'm not logged in because I've been testing some stuff with containers, and I messed this up, so maybe I can fix this. Hang on. I logged in. But anyway, let's just take this here.

01:32:42 - Anthony Campolo

And I've got one deployed also.

01:32:48 - Peter Pistorius

Like one shot deployed. Right?

01:32:50 - Anthony Campolo

Yeah.

01:32:52 - Peter Pistorius

And when I did that the first couple of times, I would be surprised. Yeah, yeah. This sort of demo was possible ten years ago, but every time you deploy, you're getting a site that's working.

01:33:14 - Anthony Campolo

You could do that ten years ago. You just have to write 10,000 lines of CloudFormation. That sucker would work the exact same way every single time until the end of time. It would outlive all of us and our children.

01:33:27 - Peter Pistorius

Okay. All right, so I'm gonna release. Boom! Oh, what the fuck? I don't know what I did with this thing. Like, I've totally screwed this up.

01:33:41 - Dev Agrawal

No worries. All right.

01:33:43 - Peter Pistorius

So my account.

01:33:45 - Anthony Campolo

Has to do with permissions. It looks like.

01:33:48 - Peter Pistorius

Yeah, there's an error here with my role because I'm one of the beta users in containers, and that required a different role. I think I've completely broken my user now, so no worries.

01:34:02 - Dev Agrawal

Cloud permissions are tough. I guess the final question that I have in mind is basically the move from client-first routing and rendering to server-first. Server Components make the most sense when you have a server-first architecture. I think that's pretty much a superpower of it. Pretty much since React Server Components came out, I have been thinking about, or at least theorizing about, this sort of framework that would be a server-first framework, embrace Server Components, and offer all these backend capabilities like auth, database permissions, queues, everything just out of the box. I think Redwood definitely appears...

01:34:55 - Anthony Campolo

To be something quite like that.

01:34:57 - Dev Agrawal

Exactly, yes. So I think it's a great overall concept of a framework, and I'm really happy that it exists. I wanted something like this for a while. But the more I try to build things with Next.js, React Router, or really any of these modern frameworks, and I was at Local First Conf last week where a lot of people are building things that they would call personal software, things like note-taking apps, music apps, almost none of them seem to be using any server-first technologies. It seems like people who are building this sort of interactive, dynamic, personal, local-first app are almost all picking client-first technologies that use a sync engine to talk to a server. There's no server rendering, there's no Server Components.

01:36:00 - Dev Agrawal

It's client-routed, client-state everything. And I know you're sponsoring LiveStore, which is kind of a sync engine and client-side database. But I don't know how that would work with a server-first framework that has server routing, where by default the route is a request on the server, not on the client. So I'm just curious about your thoughts there on server-first versus client-first.

01:36:29 - Peter Pistorius

Yeah. So I think one of the things that you have to think about is that with the examples you gave, like note-taking apps and music apps, that is personal software, but it's not the way that I see it. That's personal software for your own machine, for your own consumption. It's not something that you're using with a community or a company or friends. So you are scratching your own itch, but you're not really helping other people. Maybe you are. Maybe your personal app does do that. But I think... Dev, are you still here? Yeah, you are.

01:37:09 - Dev Agrawal

I'm back.

01:37:10 - Peter Pistorius

So.

01:37:10 - Dev Agrawal

Yeah. Just small, small issues.

01:37:13 - Peter Pistorius

Okay, so I think that's the difference. There are apps that you can build that can help your community, your friends, your family, or your small business, and those things require a server. Even a local-first app requires a server. There has to be a place where the data lives so that you can continually get it or share it among devices and things like that. And server-first is simpler. It's a much more reasonable way to think about building for the web, because that's how the web fundamentally exists. It exists in this request-response model, and everything has been architected toward that. Even the browser is built with those capabilities in mind. The fact that we have client-side routing is, in my opinion, a response to something that existed ten years ago. And you said it yourself: there is no server-first framework within the React community yet, except for Redwood SDK, and maybe there will be more. But the fact that we have client-side routing was a response, in my opinion, to mobile apps and the experience that you could get on a mobile app.

01:38:30 - Peter Pistorius

It was snappy. It could have transitions between screens. It gave you that polish that mobile apps had at that stage. But I don't think that's how we should be building apps in the future. I think we should be optimizing for memory usage, for network usage, and really leaning into the technologies that we have fundamentally built these things on top of, optimizing for developer happiness and speed and all that other stuff. I'm not saying that you can't make any choice of technology fast, but is it fast by default? What is the bare-minimum experience? And, sorry, I'm ranting here for a while, but I'm building this from the perspective of someone that grew up and lives in Africa. In South Africa, we have the biggest disparity in income in the world. There are people here that spend 25% of their money on bandwidth, and shipping a bunch of JavaScript down to those users isn't really the way to do it.

01:39:46 - Peter Pistorius

And certainly you could give them an app and that would work as well. But what if they wanted to write software for themselves? What does that look like? Their devices aren't brand-new iPhones or really fast laptops. So you don't want to eat up the battery or consume all the memory. Those are the considerations that we have in mind. We want to build a framework for the majority world, and we want to make sure that if it's good for us, if it's good for people in our communities, then it's by default going to be good for other people as well. If it's fast here, it will definitely be fast in a place that has better network and better computers. That's the perspective that we are coming at this from.

01:40:38 - Dev Agrawal

Okay, interesting. How does that fare with the sponsorship of LiveStore, which seems like very much the opposite, where you want a database on the client side, not just any database, but SQLite running in memory? It seems like quite the opposite of that idea.

01:40:57 - Peter Pistorius

So what we are going to make: LiveStore at the moment can work in Durable Objects. Durable Objects are stateful serverless compute. You and I can connect to a Durable Object, but each of us will get our own database in that Durable Object. We want to make LiveStore work there. So your data lives in the cloud, but can also sync down to your local machine and other devices that you own. That kind of lives in this world of personal software because you still get to own your data. It's like a discrete database for every single user. Maybe you're sharing data between Durable Objects, or across far-apart regions. I don't exactly know 100% what that looks like, but I think there is a space for that. There is a space for a sync engine. It enables a different class of application to be built.

01:42:03 - Dev Agrawal

For sure. Yeah. Cool. I'm happy to hear that.

01:42:10 - Peter Pistorius

Cool.

01:42:10 - Dev Agrawal

Very excited.

01:42:12 - Peter Pistorius

Yeah. Me too. I feel like the future is now. This framework is so exciting to me. I mean, I'm building it, but from what I've seen, how people have responded and how people enjoy writing software with it, it feels like we built something incredible. My first take was, why aren't all frameworks like this? Why did we take so long to get to this shape? And I don't know why. I don't have a good answer for that. I know it's my own thing, but it feels like... neither of you have children, but when you have a child, they just kind of exist. They come out of you and you're like, whoa, there's a human being. And they came out with a personality, and I didn't do that. Sure, I did that, but I didn't do that. That's what it feels like with this framework.

01:43:07 - Peter Pistorius

It just existed. It came out of something, and I think it came out of principles. Myself and Justin, most of us are in South Africa. We had these principles, and we had this ideal person that we wanted to build the software for. I think because of that, it just popped out in this shape, and that shape is pretty good. If your kid is good or bad... I'm just kidding. No, they're all good.

01:43:37 - Anthony Campolo

Awesome. Did you have any more questions, dev?

01:43:40 - Dev Agrawal

No, I think I'm good for now.

01:43:42 - Anthony Campolo

All right, so I need.

01:43:43 - Dev Agrawal

To see what you're building.

01:43:44 - Anthony Campolo

Yes. I mean, you already know it's AutoShow. I just built AutoShow in Redwood, so.

01:43:50 - Peter Pistorius

I want to see what you're building. Let's do it.

01:43:52 - Anthony Campolo

Yeah. Okay, so first I'll do the app, and then we can go into the code. I think this is the one I want. Okay. So basically the API keys won't be here because this will eventually be an app that people sign up for. They buy credits, they use credits to generate show notes, but you can give a URL. The URL I'm giving is from this thing I did where I took two interviews that both talked about my experience at Lambda School, and I kind of pulled some clips and stitched them together. There's like an eight-minute thing because I always wanted to have something to give people when they're like, "Hey, should I do a bootcamp?" because I got asked that question a lot. It would take me at least eight minutes to explain and give that answer, so I'm like, here, just listen to this.

01:44:41 - Anthony Campolo

So what it's going to do is transcribe it, then take a prompt with the transcript and feed it to ChatGPT, and it's going to ask it to write a summary and chapters. Oh, okay. I know what I did wrong. I was going to change this model at the last second, but I typoed it.

01:45:08 - Peter Pistorius

Aren't those models typed? Those strings are typed, right?

01:45:13 - Anthony Campolo

Yeah, they should be.

01:45:19 - Peter Pistorius

So you built this in Redwood SDK?

01:45:22 - Anthony Campolo

Yep.

01:45:24 - Peter Pistorius

And what did that feel like?

01:45:28 - Anthony Campolo

Pretty good, honestly, because when I was saying kind of toward the beginning, like butter... well, because of the Cloudflare experience I had, yes, it did feel like butter. I already had some experience with R2. I got like 90% of a blog post about it. Okay, I'm not sure why I'm being dumb. Let me just put it back to the original model. This one I know for sure works.

01:45:52 - Peter Pistorius

What is your login pop up every time? That's weird.

01:45:54 - Anthony Campolo

Yeah, it's a 1Password thing. I had to turn this off, and then I had to turn it back on because I needed to log in to a thing. Streaming is such a process, but okay, here we go. I'm just going to go to the page where it's actually rendered. So you have a one-sentence description: a personal account of learning modern JavaScript, React.js, and insights into bootcamps like Lambda, including their impact and challenges. And you have a one-paragraph summary of the whole thing, and then it breaks it down into discrete chapters. So it talks about learning React...

01:46:29 - Peter Pistorius

How long is that? How long is that piece of audio?

01:46:32 - Anthony Campolo

It's eight minutes.

01:46:35 - Peter Pistorius

That was pretty quick.

01:46:36 - Anthony Campolo

Yeah. So I went through such a process to build this. I originally started with Whisper.cpp running locally and then calling out to the ChatGPT API, and that was great because the transcription was free and ChatGPT is super cheap. Or I would just copy-paste it and put it in the ChatGPT prompt and get the response back. But then Deepgram and AssemblyAI are two really good transcription APIs, so that's what's doing the transcription, and then it just feeds it to ChatGPT. So there are kind of two main things. There's the transcription side, so it's hitting Deepgram and then kind of parsing the output and giving you the whole transcript. Actually, one thing I didn't show here: you can see the transcript at the bottom. Some people may want this, they may not. You need it to generate the output, but then you also have the transcript if you want it. You could do speaker labels as well. And then the summarization part... Dev, you and I talked about structured outputs on one of our streams.

01:47:48 - Anthony Campolo

Right.

01:47:50 - Dev Agrawal

Yeah.

01:47:51 - Anthony Campolo

Yeah, I'm using it now, finally. So this is the prompt here. This is the simplest version of the app right now. In the full version that I have built, which I'm probably going to migrate over, there are like 20 different prompts and you can configure it. On the front page it'll show you all the different prompts, and you can click different ones to generate all sorts of different outputs. But I just wanted to show the very bare bones. So this gives you two prompts: the summary prompt and the create-chapters prompt. They all work pretty much the same way. You have a description of it, and then here you have kind of an example where it tells it what it should look like. Then it goes to the ChatGPT API. This is the whole structured-output thing. Then it does a validation step, and then it's all returned on the home page.

01:48:48 - Peter Pistorius

So this is a client component that calls a server function.

01:48:54 - Anthony Campolo

Yes.

01:48:55 - Peter Pistorius

Is that correct? And the server function does it. What happens after that? Does it redirect you somewhere, or does it just dynamically change the content once it has it?

01:49:08 - Anthony Campolo

So once it gets the response, it outputs it on the bottom and then saves it to the D1 database, which then gets it on your sidebar here. And then the routes are dynamically generated with the ID for each database entry.

01:49:25 - Peter Pistorius

So cool. Can I look at your worker file?

01:49:31 - Anthony Campolo

Yes. And this is the.

01:49:34 - Peter Pistorius

I see you split up the routes. That's cool. This is also one of the things where you can co-locate everything, even the route, and that feels really nice because you just stick them all in a folder.

01:49:45 - Anthony Campolo

And then this is how you get the summary with each job ID. Apparently there's a summaries endpoint, not doing anything with that one yet. Let's see what happens. Yeah, okay. So it's probably actually... oh wait, /api/summaries. Okay, cool. So that just gives you the raw JSON data. And then I'll also be using R2 because the way I have it set up right now, I have an S3 bucket where the audio file gets saved if you want to reference it later.

01:50:14 - Peter Pistorius

Very cool.

01:50:16 - Anthony Campolo

And so you want to see the worker.tsx.

01:50:20 - Peter Pistorius

So I see. Oh, you're actually spreading. That's the nice thing. Instead of using prefix, you just spread out the array, which is fine. You can totally do that. If we're just using ordinary primitives like an array, you can do whatever you want. The language works with you, not against you.

01:50:42 - Anthony Campolo

So the way I built this is I took my original implementation, which was for a CLI. This all started as a Commander CLI. Then I basically took out everything except for the Deepgram API part and the OpenAI API part, and migrated it to using a Cloudflare Worker and a React front end, so no Redwood at all. I basically had it use the Cloudflare Worker with a D1 database and the React front end. Then I took a starter project from Redwood SDK, and I gave it to ChatGPT along with the other project, the Cloudflare React one, and said basically, port this to Redwood. Then I gave it a couple Redwood docs as well. Since it maps close enough, since you're close to the metal, that basically works and it didn't really get tripped up on anything.

01:51:30 - Peter Pistorius

Super cool. Actually, one of the things that I haven't spoken about is our concept of monetization for Redwood SDK. Like, the thing is: monetize that.

01:51:42 - Anthony Campolo

You have a billionaire funding it for the rest of your lives, right? That's the deal, right? Tom. Forever and everyone else gets to be paid.

01:51:51 - Peter Pistorius

Unfortunately, that isn't the deal. The deal is Tom has given me some money, and that money will run out. At that point, I will be unemployed. So we don't spend this money. That's why I'm sitting in my garage right now. This looks fancy; this is my garage. Okay. And I'm wearing this hat because it's cold now. It is actually cold.

01:52:17 - Anthony Campolo

But for the sponsor project, are you managing the money that is going to that or is that separate money that he's also paying for that?

01:52:24 - Peter Pistorius

No, that's me. There's a separate entity called RedwoodJS, Inc. that I'm a shareholder of, and I've sold percentages of it to Preston-Werner Ventures and Tom Preston-Werner. But in order to monetize what we're building, we're thinking of building something called shareware.dev. Actually, we are building shareware.dev. The idea around that is: you, Anthony, have now written a piece of software. It's a tool that transcribes audio and has some other distinct abilities that solve a problem for you in particular. But you didn't build a brand around it, you've just built the functionality. You didn't create a pricing strategy. You didn't create a support strategy. None of that stuff. You can take that source code, put it on shareware.dev, because our framework is so composable, and sell just that piece of functionality on shareware.dev for whatever amount of money. You're literally selling the source code. It's an in-between answer between giving it away for free and having to support people, or selling them the source code.

01:53:40 - Peter Pistorius

Having the license be restrictive enough that they cannot use it commercially or redistribute it, and selling them a yearly license. We want to open that ability up to everyone, and I know that is a super ambitious idea.

01:54:02 - Anthony Campolo

So I just found this blog post. Back in April, David wrote a whole post saying he's no longer really involved, because he was kind of leading the charge for the longest time, but it sounds like he's saying, to learn more, you want to read from Peter. He says that the project is no longer in his or Tom or Rob's hands. "I trust Redwood will thrive under my friend Peter." This is incredible because the framework, for the longest time, started with you and Tom, and then you brought on Rob and David, and then the four of you were doing it for years and years and years. So this is a huge thing.

01:54:35 - Peter Pistorius

Yeah. And how this came about was, Tom jumped on a call with me one day. I had shut down my startup. My startup failed. I shut it down and gave the money to the investors. Yeah. I actually got my Snaplet cup here. That's all I have left of my startup. That and a wrecked emotional state and an FSJam episode. So I shut it down, I went back and worked for Tom. After a little bit of time, Tom actually said to me, "Hey, Peter, do you want to take over leadership of RedwoodJS?" My initial reaction was, no, no, I'm not doing that. Sorry. I just came out of a startup. I felt like I wanted to die in that whole experience, and I don't want to do that again. And he was like, "Okay, cool, I respect that."

01:55:32 - Peter Pistorius

And then I thought about it that weekend and I thought to myself, you know what? This is Tom Preston-Werner. He's one of the most prolific developers on Earth. Not only that, he's a really, really great guy. And he's asked me, Peter Pistorius, to run something that he's been doing for five years because he trusts me.

01:55:52 - Anthony Campolo

And no one else could do it. You're literally the only person who could do it. I can say that. Absolutely. For 100% fact.

01:55:58 - Peter Pistorius

Well, thank you for saying that. So I took that encouragement from Tom and I was like, all right, I think I can do this. I think I can make something of this. And that's what I'm doing. So we kicked that off in November, and we built a prototype on Cloudflare for the first month because we actually weren't sure. I was saying, okay, we're going to try this new thing, build the prototype. And it actually blew our minds. The implementation was better than what we thought it would be. And in March, I think we released it, or February. No, it was March. It was March. So it's pretty early still, but we're not far from 1.0.

01:56:42 - Anthony Campolo

It's a good time in March because the original one launched in March. So it's been exactly five years.

01:56:47 - Peter Pistorius

Yeah, I love that the timing is so similar. And March happens to be my birthday, so yeah, it's nice.

01:57:00 - Anthony Campolo

Awesome. Man, this is super exciting. I'm just hyped that you're back in it building the framework, and you're fired up about it. Because I feel like when you went away from the project, it was this huge, epic thing that you had built, and all these people were trying to make it work and maintain it and had different pieces of knowledge about it. There felt like a kind of disconnect there. It's not like anything you did wrong. It was just a complicated project, you know? So having someone who can just drive the framework is so important.

01:57:35 - Peter Pistorius

Yeah. And I actually haven't written the majority of code in the framework this time around. It's a person named Justin. Justin...

01:57:44 - Anthony Campolo

There are other people who are doing this with you. We should highlight any of them if there's more than them.

01:57:49 - Peter Pistorius

Yeah. So we have Justin, we have a guy named Harmon, myself, and then we also have Amy, who...

01:57:58 - Anthony Campolo

Yeah.

01:57:59 - Peter Pistorius

Yeah, yeah, yeah, she created this awesome video about personal software. She's also building shareware.dev, and she has really good taste when it comes to things in the framework. So all of us are incredibly aligned in what we're building, and I feel super privileged to be able to do this every day. I don't take that lightly.

01:58:26 - Anthony Campolo

Love to hear your take on what you're building. Peter is contagious, and I'm glad to watch it unfold. I agree.

01:58:31 - Dev Agrawal

Definitely.

01:58:32 - Peter Pistorius

I think I'm actually speaking to Ben tomorrow. Nice. Yeah. Ben is a tutor for... what are you two? You're a tutor for some kind of really popular video tutorial thing? My brain is cooked. Egghead. There we go.

01:58:53 - Anthony Campolo

Take that. Sweet.

01:58:54 - Peter Pistorius

Yeah. We actually would love to build an egghead course, so.

01:59:00 - Dev Agrawal

Yeah, I'm sure Joel will be excited about that as well. I'm supposed to do some sort of podcast with him as well. At some point you'll probably want to talk about Redwood as well. Another funny thing that I got reminded of was, you made a tweet a couple days ago talking about React and a lot of its issues, and how we need to just not look at the bad stuff that's happening and embrace the good, the stuff that's good about it. I made a funny comment on it, I believe, because I've been doing this thing recently, especially with Adam Rackis posts about React, where I try to put it under the stages of grief. So I think under your tweet, I called it, this is stage five: acceptance.

01:59:54 - Peter Pistorius

Yeah, I laughed. That was really good. Oh geez. Spam alert. Okay, lock it in. Lock it in.

02:00:04 - Anthony Campolo

That's funny.

02:00:04 - Peter Pistorius

Yeah.

02:00:06 - Dev Agrawal

All right, I guess. Yeah. A lot of people... Remix has very clearly declared that they don't want to do React anymore. Tanner's been pretty happy with Solid recently, I guess. I'm excited to figure out if Redwood is completely tied to React, or if it's possible to have a different rendering flavor, like a Solid-flavored Redwood or a Vue-flavored Redwood.

02:00:33 - Peter Pistorius

You know, I don't know enough about those other rendering frameworks to even speculate about what that would look like. I think the source of that tweet was that when we were coding JavaScript back in the late 2000s or early 2010s, it sucked. It was really difficult. It was difficult to reason about. You never really quite knew what you were doing because browser vendors implemented things way differently. There were no transpilers. Then Douglas Crockford wrote a book called JavaScript: The Good Parts. That book was amazing because it was like 100 pages. It basically said JavaScript has really good parts and really bad parts. I'm going to point out only the good parts, and from now on ignore everything else and just focus on this. You read that book and you're like, I get it, finally. So I want to do the same thing for React.

02:01:45 - Peter Pistorius

It's like, okay, we've gone through a lot of paradigms for client-side, server-side, and now we're in this new phase. There are things in the framework that just don't make sense anymore. You could feel that when they came out. So we have to move away from those.

02:02:03 - Dev Agrawal

And synthetic events.

02:02:03 - Peter Pistorius

Let's point out what the good stuff is and just use those. So I'm excited for the future of React. It taught me a lot about architecting front-end code, because everything else before it was a complete shitshow. Angular was terrible. jQuery was awesome, but it also had the same problem. They all surfaced the same issue, so you never knew exactly where things were and how things happened on the screen. But I've got to try some of these other newer ones because I have never actually tried them.

02:02:50 - Dev Agrawal

Let me know if I can give you a tour of Solid at some point.

02:02:54 - Peter Pistorius

Yeah, we should do that. We should do that.

02:02:58 - Anthony Campolo

Yeah, man. All right. Another stream in a month or two, or whenever you have the time, because this is super fun. There are a million things we could talk about, but thank you so much. Really great to get this huge download, and I'm excited. I think I'm going to be building on this now.

02:03:13 - Peter Pistorius

Cool. Thank you very much. I really enjoyed this conversation too. I felt like I rambled on for quite a bit, so yeah. Cool.

02:03:22 - Anthony Campolo

I'm about to run this through AutoShow, and you're going to be able to read a summary of it where you sound like you knew exactly what you were talking about the whole time.

02:03:30 - Peter Pistorius

Awesome. That's what I love. AI makes me sound smart. Actually, I want to do a shout out for this one tool that I use. It's called Whisper Flow, I think. Oh, yeah.

02:03:41 - Anthony Campolo

Yeah. It uses Whisper.cpp under the hood.

02:03:44 - Peter Pistorius

So it's this really decent thing that you have on your computer that allows you to basically transcribe text. If you're using a Mac, you hold your function key and it picks up what you said and changes it into text. I don't type very fast. I've never been someone who can. What I realized is, when I type I sound stupid, but when I speak I sound less stupid. So this thing takes my voice and actually puts it into words, does all the spelling really well and proper grammar, and cleans it up for me. It's great. I really enjoy using it, and I enjoy communicating with people using my voice rather than my typing. So check that out.

02:04:28 - Dev Agrawal

Nice. I think I have the opposite problem. I feel like I sound smarter when I'm writing things down.

02:04:36 - Peter Pistorius

Nah, you are quite intimidating. I was so worried to come on the show, and I was like, damn, bro.

02:04:45 - Anthony Campolo

When I met.

02:04:46 - Peter Pistorius

Dev.

02:04:47 - Anthony Campolo

He was still a college student.

02:04:49 - Peter Pistorius

Even then, he was intimidating. I was like, whoa, this guy's smart.

02:04:55 - Dev Agrawal

I think I was a college student when Peter and I first met as well, at Jamstack Conf, the last one ever.

02:05:00 - Peter Pistorius

Yeah, yeah, yeah, yeah. I think I even gave you some swag, or I tried to convince you that Snaplet was awesome. And you were like, "Nah, dude, that thing's... I don't know what you're doing with that, but it's dumb." I was like, "Oh, shit." I actually couldn't sleep that night.

02:05:15 - Peter Pistorius

I was like, "Damn, he called my product stupid." No, I'm kidding.

02:05:16 - Peter Pistorius

[laughs]

02:05:21 - Anthony Campolo

He was like, "I love leaking all my customers' personal data."

02:05:25 - Dev Agrawal

I probably have a Snaplet sticker somewhere still.

02:05:29 - Peter Pistorius

Well, this [unclear] said "doing the weave." What does that mean?

02:05:36 - Anthony Campolo

I think this is something that they talk about with Trump doing the weave. He weaves around a conversation. I think that might be what he's referencing. I'm not 100% positive.

02:05:46 - Peter Pistorius

Oh, shit. This guy's comparing me to Trump.

02:05:50 - Anthony Campolo

I don't think he meant it as an insult.

02:05:55 - Peter Pistorius

I won't take it as an insult right now, this very moment. Cool, cool, cool, cool.

02:06:02 - Anthony Campolo

Cool, cool, cool, man. All right. AppFactory on X, that's how people can find you.

02:06:08 - Peter Pistorius

Yeah.

02:06:09 - Anthony Campolo

And then rw-sdk.com, those are the places.

02:06:13 - Peter Pistorius

Yes. And please star our GitHub repo. That's going to convert into sweet, sweet money at some point.

02:06:22 - Anthony Campolo

Yeah, let me do that. 766. All right. Everyone watching right now, go star it. Do it, do it now. All right. Yeah, we should call it here. You get to bed with your baby, and yeah, man, we'll be in touch.

02:06:42 - Peter Pistorius

Cool, cool, cool. Have a nice evening.

02:06:43 - Anthony Campolo

Bye bye, everyone. Thanks, everyone on the stream who was hanging out. Super fun.

On this pageJump to section