skip to content
Video cover art for Advanced SolidJS Techniques with Dev Agrawal
Video

Advanced SolidJS Techniques with Dev Agrawal

Dev Agrawal discusses Solid 2.0 features including non-nullable async, mutable derivations, lazy memos, self-healing error boundaries, and AI tooling.

Open .md

Episode Description

Dev Agrawal returns to discuss Solid 2.0's upcoming features including non-nullable async, mutable derivations, lazy memos, self-healing error boundaries, plus state management and AI tooling.

Episode Summary

Dev Agrawal joins Anthony Campolo for an extended conversation about advanced SolidJS techniques and the upcoming Solid 2.0 release, currently in experimental phase with stable release projected for sometime in 2026. The discussion centers on headline features like non-nullable async with createAsync, which streamlines data fetching by returning the actual data type rather than data-or-undefined, alongside mutable derivations that fill the gap between createMemo and createStore for fine-grained reactive object updates. Dev explains how Suspense and error boundaries become decoupled from where data is fetched, allowing self-healing error recovery anywhere in the component tree. The conversation moves through immutable diffable stores, lazy memos, automatic batching, transitions, and the broader effort to eliminate createEffect from typical Solid code. Anthony shares his real-world migration of AutoShow from Astro to Solid Start, prompting practical advice on stores, derived state, and minimizing setters. The latter portion covers AI-assisted development workflows, Anthony's Repo Mix-based approach versus agent-driven tools like OpenCode, custom instructions, deployment considerations with Nitro, database options including Convex and LiveStore, and emerging voice-mode and multi-agent capabilities.

Chapters

00:00:00 - Welcome Back and Migration Plans

Anthony opens by welcoming Dev back as a SolidJS core team member, where titles are loose and members gravitate toward whatever interests them most. Dev's original contribution focus was WebSocket work, which remains on his roadmap. Anthony shares his journey from an Astro-React setup that gradually transitioned to Astro-Solid and is now consolidating fully into Solid Start, with API routes being the last piece to migrate.

The conversation turns to npm supply-chain attacks, including the recent Chalk compromise that Anthony narrowly avoided, and how this has pushed him toward minimizing dependencies and considering Bun. Dev shares Dax's analogy that React's ecosystem feels like a cluttered garage while smaller framework ecosystems like Solid's resemble organized drawers, with a single canonical solution rather than competing alternatives.

00:05:12 - Solid 2.0 Roadmap and Release Timeline

Dev pulls up the Road to Solid 2.0 GitHub roadmap, explaining the progression from experimental through alpha, beta, and release candidate phases. The team is currently in experimental, working toward feature parity for client-side rendering, SSR, and hydration. Dev estimates anywhere from one month to six months before moving forward, noting that Ryan prefers building extensively before publicizing work.

The experimental npm package is publicly available, and community member Brennels has set up a GitHub template for early experimentation. The alpha phase will formalize changes through RFCs, while beta brings router, Solid Start, and meta integration. Anthony notes this is when he'll likely engage with the migration, having Solid Start adoption complete by then.

00:09:13 - Non-Nullable Async and Suspense Decoupling

Dev demonstrates the headline feature: non-nullable async via createAsync. Where current data-fetching libraries return user-or-undefined types requiring null checks, Solid 2.0's createAsync returns just the data type itself. The signal you receive contains the actual value without nullable wrappers, eliminating the need for optional chaining and loading-state guards throughout component code.

The companion benefit is true Suspense decoupling. Because Solid components don't exist in the React sense, Suspense boundaries can be placed anywhere relative to where data is fetched—what matters is where the signal is read, not where it's created. Dev shows how you can wrap deeply nested components in Suspense even when the createAsync lives much higher in the tree, providing genuine flexibility that React's Suspense never delivered.

00:16:30 - isPending Helper and Pending States

Dev introduces the isPending helper, which lets any component check whether data it depends on is currently refetching without requiring explicit loading props passed down through the tree. Used inside createMemo, isPending automatically tracks dependencies and returns true when any read signal is pending, eliminating prop-drilling for loading states.

Brent Lee asks about the second argument to isPending, prompting Dev to explain the distinction between Suspense and pending states. Suspense triggers only when data is initially absent, while isPending handles updates where stale data still exists. The second argument controls whether isPending opts out of triggering Suspense, similar to React's useDeferredValue—an edge-case escape hatch for specific update scenarios.

00:24:48 - Mutable Derivations and Flush Boundaries

Dev outlines the four-quadrant view of Solid primitives: createSignal and createMemo handle replaceable values, createStore handles complex object state, but the derived equivalent of createStore was missing. Mutable derivations fill this gap, providing a derivation primitive that handles nested object trees with fine-grained reactivity.

Dev recalls a Trello clone demo where this API delivered dramatic performance gains over React, eliminating object cloning and reconciliation overhead while updating only the specific DOM nodes that actually changed. The team also covers flush boundaries as the umbrella term for Suspense, ErrorBoundary, and Activity components, plus derived signals that simplify cases where a signal needs to track parent prop changes without an explicit createEffect.

00:33:50 - Immutable Diffable Stores

The discussion shifts to immutable stores and the comparison with Redux, XState, and Immer's approaches to state management. Solid stores are mutable by default, providing performance benefits through fine-grained mutations rather than full object cloning. The tradeoff has been time-traveling capabilities and reconciliation challenges when comparing fresh server data against existing store contents.

Solid 2.0 introduces immutable internals that preserve mutable API ergonomics while enabling better reconciliation performance and viable time-traveling. The reconcile function handles the diffing when external data arrives, and the new architecture means developers get the best of both worlds: mutable-feeling code with the structural benefits of immutability under the hood.

00:40:40 - Lazy Memos and Automatic Batching

Dev explains that Solid 1.x uses eager memos that always recalculate based on dependencies, while every other major framework with signals has moved to lazy evaluation. Solid 2.0 finally adopts lazy memos, though Dev notes this could potentially be reverted given eager evaluation's own benefits. The change is largely transparent in terms of API but eliminates wasted computation for unread memos.

Automatic batching represents a more significant mental model shift. State updates currently reflect immediately in the UI, but 2.0 makes batch behavior the default, requiring an explicit flushSync call to push updates synchronously. Ryan Florence's recent commentary on batching frames the discussion, with the change helping group multiple state updates that should be reflected together.

00:44:18 - Self-Healing Error Boundaries

Dev demonstrates self-healing error boundaries using a phrase counter demo where data fetching occasionally throws errors. The reset function provided to ErrorBoundary fallbacks doesn't just retry rendering—it traces back through the dependency graph to find what actually failed and retries that specific operation, regardless of where the boundary sits in the tree.

This means error boundaries can be placed at any depth, even in components that don't directly fetch data, and they still recover correctly. The reset walks up through derived computations to locate the failed async source. Anthony recognizes this as a building block for cell-style data components, where isPending plus this error recovery provides everything needed for Redwood-like data abstractions.

00:50:54 - Transitions and Migration Strategy

Dev explains React's transition merging problem where multiple concurrent transitions block each other, creating waterfall behavior in the UI. Solid 2.0 keeps independent transitions independent, allowing different parts of the page to update as they complete without forced merging. This unlocks usage patterns developers may not have considered when transitions were inherently sequential.

The migration strategy combines breaking changes with a compatibility package, allowing 1.x apps to continue working while developers gradually adopt new APIs. Dev expresses more interest in writing a thorough migration guide that can be fed to Claude than in maintaining brittle codemods, since LLMs can handle nuanced refactoring while preserving project conventions.

00:57:35 - AutoShow Code Tour and Form State

Anthony shares his screen to walk through AutoShow, demonstrating the multi-step form flow handling local files, RSS feeds, video URLs, and search. The application processes through transcription selection, prompt selection, and LLM choice, with background work running so users aren't blocked waiting between stages. The final output renders as a show notes page with metadata, content, and transcription.

Anthony admits his code grew organically from signals to a store without a clean refactor, leaving signal management mixed with store operations. Dev recommends minimizing setters everywhere possible, treating createSignal as a low-level primitive and consolidating state into the store. The conversation surfaces the broader principle that less imperative state means fewer bugs, mirroring the createEffect minimization theme.

01:06:11 - Stores, Produce, and Named Mutations

Dev walks through the complex state management documentation page, focusing on the produce helper that provides Immer-like mutation syntax. Produce is becoming the default approach in Solid 2.0, letting developers make multiple nested mutations in a single function without wrapping calls in batch and without navigating path syntax.

The discussion expands to the philosophical question of how to organize state mutations. Dev advocates for named mutations—explicit functions that the store exposes rather than letting any component call setters directly. This pattern, traceable back through Redux, XState, MobX, Java getters, and even Angular's data flow concerns, provides predictability by making all valid state changes well-defined upfront.

01:13:33 - Validation, Form Libraries, and Solid Start Patterns

Anthony explains that AutoShow performs most validation server-side since the form is mostly toggles and selections rather than free-text input. Dev mentions Ryan's preference for server-side validation due to schema library bundle costs, recommending Valibot as a tree-shakeable alternative to Zod. The Valibot project, supervised by Walter Kriha, Misko Hevery, and Ryan Carniato, represents collaboration across reactivity-focused framework authors.

The conversation moves to derived data principles and createResource as the primitive Anthony should use for API route fetching instead of createEffect. Eventually migrating to Solid Start unlocks createAsync from Solid Router, which wraps createResource with cancellation handling and Suspense integration—similar in spirit to TanStack Query but designed for Solid's reactivity model.

01:21:51 - Essential vs Accidental Complexity

Dev offers high-level architectural advice framed around Fred Brooks's distinction between essential and accidental complexity. Essential complexity comes from the problem domain itself—a complex form with dynamic validation is inherently harder than a todo list. Accidental complexity emerges from the tools you use to solve problems, like React's dependency arrays or careful component boundary placement to avoid unnecessary re-renders.

Dev points to server functions, query and action helpers, and React Server Components as examples of API designs that eliminate accidental complexity. SvelteKit's recent move toward async Svelte and remote functions mirrors what Solid Start pioneered. The recommendation: when complexity appears in your code, ask whether it stems from your problem or your tools, because the answer determines whether refactoring or framework migration solves it.

01:29:00 - Route Loaders, Code Splitting, and Nitro

Dev critiques traditional route-loader patterns from Remix and early SolidStart that forced data fetching to live separate from components. The newer approach—createAsync inside components with route-level preloading for cache warming—preserves colocation while still enabling instant navigation through prefetch. GraphQL with Relay fragments achieved this elegantly, and the new pattern brings similar ergonomics to non-GraphQL stacks.

The deployment discussion turns to Nitro as the platform-agnostic server layer underlying Solid Start, TanStack Start, Analog, and Nuxt. Nitro abstracts over Node, Bun, Deno, Cloudflare Workers, Lambda, and other targets so the same server code runs everywhere. Anthony notes that Vite's Environment API may eventually let platforms ship their own Vite plugins, potentially reducing Nitro's necessity over time.

01:44:31 - Database Options and Sync Engines

Dev surveys the database landscape he's been exploring. Convex provides backend-database colocation with reactive queries but requires server-side query execution. He's also been using Current (formerly Event Store DB) for event sourcing, plus LiveStore from Prisma's original author, which combines event-sourced storage with sync engine capabilities.

The conversation covers Zero Sync from the Replicache team, paired with the One framework which adds Tamagui's cross-platform UI. Dev's ideal database would combine Convex's developer experience, Zero's incremental query system, and LiveStore's event sourcing—none of which exists yet. Anthony plans to evaluate Convex against running everything on Railway, where his Docker container hosts FFmpeg and yt-dlp dependencies that don't fit Lambda environments.

01:54:32 - WebCodeGen Scorer and Documentation for AI

Dev shares Angular's WebCodeGen scorer, a tool that tests AI models' ability to generate working applications across frameworks. The tool builds, runs, and evaluates generated code on accessibility, security, and runtime correctness dimensions. Solid was added with help from Dev's team, achieving high scores after refining environment prompts and documentation structure.

The insight: AI performance improves dramatically with better documentation, especially tutorial-style content that pairs code with English explanations of intent. Dev wants to extend the scorer with more complex state management challenges to identify documentation gaps. Anthony suggests Redwood's approach of providing twenty guides for common tasks as a model—task-oriented documentation that LLMs can follow step by step.

02:01:32 - Anthony's Custom Instructions Workflow

Anthony walks through his custom instructions file built up over a year, structured into response format expectations, logging conventions, and language-specific coding rules. He requires complete code files in responses to enable rapid copy-paste rather than fragmented diffs, and he asks the LLM to plan first before writing code so he can scope work appropriately.

His approach skips agentic web search by manually curating documentation URLs that Repo Mix bundles into context. The methodology favors small, validated changes over large speculative ones, achieving rapid iteration cycles by ensuring the LLM has exactly the right context for each task. Anthony argues against asking AI to write specs or plans, finding that spec-driven approaches produce unnecessary scaffolding and confused implementations.

02:11:19 - OpenCode, Sub-Agents, and Future Workflows

Dev describes his OpenCode workflow with multiple terminal tabs running concurrent agents, plus interest in Git worktrees for parallel agent work on different branches. He mentions an upcoming Auto Engineer project he's contributing to that combines deterministic code generation from specs with AI-driven implementation, targeting consulting clients with predictable scaffolding.

The discussion covers Levels.io's continuous Cloud Code VPS approach as a glimpse of where agentic development is headed. Both agree multi-agent collaboration remains experimental, with strong opinions on both sides about when subagent orchestration helps versus harms outcomes. The fundamental shift: development tools increasingly run autonomously rather than reactively responding to single prompts.

02:31:23 - Voice Models, NotebookLM, and Real-Time Features

Dev describes using ChatGPT voice mode while doing dishes for hands-free research on agent memory systems, comparing the experience to Tony Stark and Jarvis. Anthony shares his enthusiasm for text-to-speech, generating personal audiobooks from PDFs and planning to add audio output for AutoShow generated show notes. NotebookLM gets a mention for its discussion-format AI summaries.

Dev probes whether AutoShow could benefit from real-time features, asking how step orchestration coordinates between client and server. Anthony explains that once a user has supplied all selections, processing continues server-side independently of the open tab. Dev sees opportunities for cross-device status updates and true background processing that survives page closure—the kind of capability that real-time WebSocket integration in Solid Start would unlock. The conversation closes after two hours and forty-eight minutes with mutual appreciation and plans for follow-up streams once Anthony's Solid Start migration completes, ending at 02:48:23.

Transcript

00:00:00 - Anthony Campolo

All right. Welcome back, everybody. We got Dev back for a super special SolidJS episode. When I messaged you about this, you seemed pretty excited about the topic. You said you could talk about Solid forever. You're a core team member. Do you have a, you know, a title as a core or is it just core team member?

00:00:23 - Dev Agrawal

Just core team member.

00:00:24 - Anthony Campolo

Cool.

00:00:25 - Dev Agrawal

There's no titles within, it's more like everyone just floats around, picks the kind of stuff that they like interesting and work on that. Usually it's more like when someone is brought onto the core team, it's— it was because of a specific reason, and that's kind of what they continue doing. Uh, for me, the specific reason was the WebSocket stuff, which I haven't talked about. Yeah, which I haven't gotten around to in, in a while, but that's something that's in the pipeline.

00:00:54 - Anthony Campolo

Sweet, sweet. Yeah. So I wanted to talk to you about a couple different things. I am at the point now where I'm really going all in with Solid in terms of my application.

00:01:06 - Dev Agrawal

Oh yeah.

00:01:06 - Anthony Campolo

It started out as like an Astro slash Solid thing. Actually, no, sorry. It started as an Astro React. There was no Solid at all at the very, very beginning. And then at a certain point when I was like in the real experimental exploratory phase, I was like, you know, I should try and like just switch out, you know, React for Solid. 'cause Astro's already set up to do something like that. And I know for the most part, when you give it examples, it can be pretty good at refactoring from one thing to another. So once I made that switch, I never went back. I've been with Solid ever since, but I've been getting to the point where I was more frustrated with having the separation between the TSX files and the Astro component files. 'Cause I wasn't really doing anything with the Astro components. They were just kind of bare bones page outlines, and then everything was being done with the Solid stuff. So I've kind of refactored everything out of the Astro things and I'm just to the point now where I have to now switch over the API routes from the Astro API routes to the Solid routes. And that's gonna take a little bit of time, but everything else is pretty much ready. I'm close to making that migration.

00:02:11 - Dev Agrawal

Nice. Fine. So moving on to Solid Start finally.

00:02:14 - Anthony Campolo

Yep. Yeah. There was a moment when, before I shipped that I almost move to Solid. I had the refactor like 95% done and then for some reason didn't quite get it to the end. But, um, I think it was fine. You know, honestly, Astro was the framework I was using since like 2022. Mm-hmm. And I think it's great. It's been really good for me, but I think I'm at this point where I'm kind of ready to move on. And Solid Start, we talked about this a little bit before the stream, you know, Dax has really heavily bought into it now and I I've seen the progression of Solid now for the last like 4 years having known Ryan. And I feel confident that the community is large enough to sustain it and do the important things that community needs to do. And I'm also in a place where I'm moving away from any dependencies I can. I'm trying to go really low dependency. So I'm not looking for a million community packages at that point. I see this now kind of as a drawback to React and Node especially. I'm leaning more into Bun now because, you know, yep, it's a huge attack surface. Like, there's been crazy massive hacks that are affecting devs' personal machines, and I was 0.1 package away from one. Chalk 5.6.1 was compromised, and I was running Chalk 5.6.0 in one of my applications. So if I bumped the number on the wrong day, I would have been compromised, and that freaks me out.

00:03:39 - Dev Agrawal

Yeah, I, I'll admit I, I've heard a lot about this recent npm hack that I've read nothing about. I really need to catch up on that.

00:03:48 - Anthony Campolo

It's a big one because it's basically just slipping stuff into the install scripts. So when you do that npm i, you're opening yourself up to downloading anything off the internet that could run any code on your dev machine, you know.

00:04:03 - Dev Agrawal

Damn, that's basically like the log— like very similar to the Log4j Stuff that happened.

00:04:08 - Anthony Campolo

I'm honestly surprised this doesn't happen more often. Like the fact that this doesn't happen every week is kind of impressive, but I feel like it happens a lot.

00:04:17 - Dev Agrawal

It just, it doesn't get caught a lot. Yeah.

00:04:20 - Anthony Campolo

Well, yeah, that's probably true also. But, um, now that Feross's company Socket is out there, it's like a company dedicated to doing the security work NPM does not do for some reason. Yeah.

00:04:34 - Dev Agrawal

Anyway, I definitely feel the, uh, the, the like, uh, feeling of drawback that React's ecosystem brings. I think Dax put it very nicely a while ago, which is that, uh, React's ecosystem is kind of like a garage, just extremely full of things where you have to sift through the garbage to find the things that you need. And smaller, like Solid's world ecosystems are like well-organized drawers.

00:05:00 - Anthony Campolo

Yeah. Yeah. Cuz there's not gonna be 3 competing form libraries. There's gonna be the one form library people are gonna use if they even want a form library.

00:05:09 - Dev Agrawal

Yeah.

00:05:12 - Anthony Campolo

So what's up with Solid 2.0? Is that a thing that's actually like coming soon or is it just like kind of a vague future things that are being worked on in the framework?

00:05:22 - Dev Agrawal

Yeah, I am very glad that you asked. Um, Solid 2.0 is, uh, basic— like, it's very close to completion. The— there's like some final kind of bug fixes and small API design things that are going, uh, going on right now, but other than that, it's like mostly built, or at least in the experimental phase. So there's a roadmap for Solid 2 on GitHub somewhere where Ryan puts it like experimental alpha, beta, then stable, like release candidates. So experimental phases where like we're just building and prototyping the actual library itself. Uh, once— uh, is this the Road to Solid 2.0?

00:06:07 - Anthony Campolo

Yeah.

00:06:08 - Dev Agrawal

Uh, okay. Yeah, so experimental is where like we are. Um, let's just— let me share my screen and quickly go over that. Okay, so let's get to this list.

00:06:28 - Anthony Campolo

Like one on the font, one more.

00:06:30 - Dev Agrawal

Okay, yep, let me just do that. And you know, again, get rid of the sidebar. Uh, you see, experimental is where we are today, or where we were on Feb and where we still are. Mostly because like there's a— I mean, yeah, no, this was just gonna take a while anyways. Like Ryan likes to do his stuff in a way like he will build as much as possible before talking about it with anyone or before like really marketing it or pushing for like any sort of marketing. And once it's built, he would want to like speedrun through the rest of the release candidate. Like, you know, like, let's just get this out there. So experiment— that's why it's taking a bit longer in experimental. And the main idea is, again, like, get all— get feature parity, client-side SSR, hydration, stuff like that. I would say that we might be anywhere from like 1 month to 6 months.

00:07:38 - Anthony Campolo

Uh, yeah, sure. Uh, yeah, I remember like when Redwood was getting towards 1.0, it ended up being like over a year after the time we had first said we were hoping to, to get it out by.

00:07:49 - Dev Agrawal

Yeah. I mean, this happens all the time. React, React compiler.

00:07:53 - Anthony Campolo

Mm-hmm.

00:07:53 - Dev Agrawal

Uh, they spent like what, 5 years on it when they thought that it might be like a 2 or 3 year project.

00:07:58 - Anthony Campolo

Mm-hmm. Um, so, but it sounds like right now people can run experimental 2.0.0. Is that? That branch is like public?

00:08:07 - Dev Agrawal

Yes, it is. The branch, the npm package is public as well, so you can install and start playing with it. Uh, there's like some statlets as well. There's a GitHub, uh, repo template that was set up by Brennels, one of the community members, uh, one of the fellows actually now. Um, so yeah, all that is there. And then in the alpha stage is where we're, uh, Getting more community feedback, more than we already have. But more like formalizing the changes that we are making in RFCs so that it's more clear about exactly what's going on. And then beta, start implementing router, Solid Start, meta.

00:08:52 - Anthony Campolo

That's probably where I'll get involved and hopefully I'll have the Solid Start migration done by then.

00:08:57 - Dev Agrawal

Yeah, exactly. So, uh, UI components, TanStack, all of that stuff, and then the release candidate. So that's where we are right now. The experimental, um, we're hoping goes out like anywhere between one, uh, one month from now.

00:09:13 - Anthony Campolo

I guess I want to step back and ask, ask a broader question. Like, it's not entirely clear from this, I don't think that was the point of this, but like, what are, what are we getting from 2.0? Like, what is new? What is better? What are the improvements? What's the point of like having a new version?

00:09:28 - Dev Agrawal

Yes. Here's a brief list or a very list with a bunch of jargon words. Yeah.

00:09:36 - Anthony Campolo

Most of the things that I would already assume are in 1.0, so I don't understand exactly what any of this means.

00:09:43 - Dev Agrawal

Yeah, that makes sense. I would say the highlight feature is non-nullable async. The way you can understand it is that Currently you might be using like a createResource to fetch data within Solid components. And what, like if you fetch data that's of a user type.

00:10:05 - Anthony Campolo

I am not, I don't have a single createResource in my entire app.

00:10:08 - Dev Agrawal

Do you have createAsync?

00:10:11 - Anthony Campolo

Let's see.

00:10:13 - Dev Agrawal

If you're using Solid, oh, you're not using Solid Start. You're not fetching data within Solid right now. You're probably doing it through Astro.

00:10:18 - Anthony Campolo

Yeah, that's coming through Astro. Yeah, exactly.

00:10:20 - Dev Agrawal

Okay, yeah. So, but you can imagine like using, React Query with React, right? Uh, basically what, what any data fetching library these days give you is that let's say you fetch data of the user type, then what you get back on the other end is user or undefined. Or in Solid's case, it would be a signal of user or undefined, right? Which makes sense because initially the user is not going to be there, it's going to be undefined, and then at some point when the data fetching completes The state updates and now you have the user object. That makes sense. But this gets flipped with Solid 2.0. So let me share a different screen where we have like a demo for this. So it's a very simple demo where we have a counter and every time you click the number, it increments and it gets like a just a random sentence based on that number.

00:11:21 - Anthony Campolo

If you bump up the font on the editor, it's pretty good. Yeah.

00:11:25 - Dev Agrawal

Um, okay, so let's— oh no, I don't want.new. Let's hop into the code. So I have CreateAsync here. Uh, the first thing is that this message, this was also being fetched here. So GetHello is, uh GetHello is just returning hello world and there are artificial timeouts. It's not a real server here, but it gets the point. But GetHello returns a promise of string and you just pass it in into createAsync like this. What you get back on the other side is an accessor of string or a function that returns a string. You don't get string or undefined or string or null. That's where the non-nullable comes from. The signal that you get back just has the data in it. So, and same thing here. So getPhrase, it return— it takes a number. So the number that we have on the counter returns a promise of string. We pass it into createAsync, and what we get back is an accessor of string, not string or undefined. And even here you can see that we are calling.toUpperCase on it. If this was undefined, we would have to put a question mark here And if we didn't, it would throw a TypeError and it would fail the build, right? Mm-hmm. Or pro— if you're checking for types, uh, within your build process. But it's not doing that here because it's just returning string and everything just works. So yeah, that's the core idea, which is it, it really streamlines how you connect like any asynchronous resource anywhere. Uh, it doesn't add like this extra complexity of or undefined or adding like loading states, error states. Those are all things that you can do using helpers. The core experience is that you just call getHello and you get data back.

00:13:19 - Anthony Campolo

Totally. Yes. One of the things I loved most about Redwood is their cells did tons of management in terms of the fetching and managing, managed all 4 stages, success, error, empty set, or something in it. Like number of items or whatever. So yeah, this is great. This is stuff that's gonna be super duper important once I'm fully on the Solid, the Solid Start train.

00:13:42 - Dev Agrawal

Yeah, definitely. And then the, the thing that's really nice about this, this createAsync is that it, it plays really nicely with Suspense. How much have you used or how familiar are you with Suspense from React or maybe even—

00:13:56 - Anthony Campolo

Pretty familiar. Yeah.

00:13:57 - Dev Agrawal

Okay. So, we are fetching data here in this component. And if you have used like Suspense with React, you would expect that, okay, now I gotta wrap PhraseCounter with a Suspense boundary so that when it starts fetching the data, it can suspend and whatever's above this PhraseCounter component can suspend, right? Well, that's not a thing with Solid because components don't exist in Solid. So, you can actually put a Suspense boundary wherever you want. So, here's the loading phrase counter which shows up initially when— so, let's increase this to like 5,000. So, you see that loading phrase counter here which is from this Suspense boundary even though the createAsync is up here. Because in Solid, the thing that actually matters is where you fetch— where you get the data from the signal, where you read it, not where you create it. And this means that we can go even further in. We can add a Suspense boundary here. So we have a very simple message component that takes some text and renders it using a paragraph. So this is, this here, and this is not fetching any data, but we are wrapping this message component with a Suspense. And, uh, when I refresh Uh, I need to reduce this one and increase this one. So now, now I'm going to see this SuspenseBoundary for a while. So it, for it, almost like completely decouples where you fetch data and where you pay, uh, put these SuspenseBoundaries, which is not very much not the case in React. So this is something I'm super excited about because you never need to worry about where you're fetching data, how deep down it is. You can always just put your Suspense boundary anywhere and everything still works the exact same way. And the same thing with Error boundaries.

00:16:00 - Anthony Campolo

Yeah, no, that seems really cool 'cause that's how I remember when Suspense was coming out for React. It's like, that was like the pitch, you know? It's like, yeah, Suspense boundary, you just throw it around your thing, wherever the thing is loading, you just do Suspense boundary, you know? And it's never that simple, you know? But I think this is one of the things that's cool with Solid is you really take your time with stuff and dial it in to where you get the nice DX as well, I feel like.

00:16:26 - Dev Agrawal

Yep. And now let me show you this second one.

00:16:30 - Anthony Campolo

Fuzzy says great work and that he's been really looking forward to this API.

00:16:34 - Dev Agrawal

Oh yeah, for sure. Yeah, especially the fact that you can just continue like deriving data on top of it. So I have the phrase here, which is async, then I have the upper phrase, and then upper phrase is what gets passed into this message. So like at no point it needs to really know about what the async, like what the async stuff is. Now if we do, but we do want the loading indicators a lot of time, like the, like if it doesn't return undefined, undefined is some like, A lot of people use it as a way to like indicate loading.

00:17:09 - Anthony Campolo

Mm-hmm.

00:17:11 - Dev Agrawal

Uh, but here when you click on it, you see everything goes— uh, that's taking too long. Uh, but yeah, we have like a pending indicator here where click on something and it goes, um, what, transparent? I don't know, the opacity decreases. Um, and you can do that with the isPending helper. Which comes from Solid now. It's in, uh, this is a new API, just like createAsync. Um, but with isPending, it, you just give it a function and you can read any data within isPending and it'll just tell you like if it is, if there's anything that you read in here that's pending, it's going to return true. So it's not, and you can see we're using it with createMemo. If this was using createResource or any existing data fetching primitive in like React or Solid or really any framework, then this would have to return like an isLoading or isPending, like, let's put this loading, right? And now like, this is the only thing that you can pass forward. Like, and you have to always hold this piece of state. You have to pass it down to any children that might need it. Um, but with this, it's more like, just use this and read whatever data you want and we'll let you know if it's pending or not. This can even work if I have like class, let's say, um, is there Tailwind in here? No, there's no— isn't. Anyways, but if it was like an isPending props.text, so the— and this would tell you like if, uh, like whatever the props.text depends on if that's pending, then this will return true. So we don't need to pass an additional isPending down to child components. We— child components can just use this to infer like what's happening. So this saves a lot of like prop drilling, uh, problems, and like this basically reduces the amount of state that you might have just by streamlining.

00:19:20 - Anthony Campolo

Yeah, that's gonna be one of the big questions once you get more into myapp is the state management thing. And that's also what kind of is informing some of the LLM conversation as well. In terms of that big list of new features for 2.0, was there other things you wanted to hit on besides this one?

00:19:41 - Dev Agrawal

Let's see, let me, let's go back to that list. I should probably just share my entire screen. Um, yeah, he's sharing tabs.

00:19:51 - Anthony Campolo

Yeah, frustrating.

00:19:53 - Dev Agrawal

Yeah. Okay. So, uh, mutable—

00:19:57 - Anthony Campolo

flush boundaries. I've never heard that term before.

00:20:00 - Dev Agrawal

Uh, flush boundaries is basically like a, a fancier or probably more internal name for like, uh, components like Suspense and ErrorBoundary and the new Activity component that React released. We have a version of that as well in 2.0.

00:20:17 - Anthony Campolo

Uh, very quick question. Yeah, does isPending have a second argument?

00:20:22 - Dev Agrawal

A second argument? Um, it does. Um, do, um, is that like a chat question or something?

00:20:31 - Anthony Campolo

Yeah, from Brent Lee.

00:20:31 - Dev Agrawal

Yeah, from Brent. Yeah, so isPending has a, um, it's so I, I can talk about the second argument, like, but that goes a bit more in depth about like how isPending and suspense how that works. Is that something we wanna go into?

00:20:49 - Anthony Campolo

Yeah, I mean, someone's asking about it. Sure, yeah, go as deep as you want.

00:20:52 - Dev Agrawal

Yeah, Brinley, I'm pretty sure already knows, but it's, so there's the isPending, which like returns true or false, but there's also the Suspense. So there's two different ways of handling like loading or pending asynchronous states in Solid or in Solid 2.0. Suspend only works for initial rendering or when the data isn't there. So if you render a component, you read some async data and there's no data there, like it was just created, then it's gonna throw, it's gonna suspend and whatever is the nearest Suspense boundary is gonna show its fallback. But if you update something, so if there's already async data and now it's being refetched, it's actually not going to trigger the Suspense boundary. Uh, React currently does that where on anything async is just going to bail out to the Suspense fallback. Um, and you have to explicitly use transitions to avoid that. Uh, in Solid 2.0, that doesn't happen by default. Uh, and that's why the isPending helper exists. So when something is updating, uh, like you already have the user and you're now you're fetching a new some the ID changed and you're fetching new user details, you still have the data of the old user, but you can use it and you can, you can still use that to render the UI.

00:22:13 - Anthony Campolo

Hey, we got Ryan in the stream. Use defer value. Also, what's up Nikki T watching from LinkedIn?

00:22:20 - Dev Agrawal

Oh my God, uh, LinkedIn streams, that takes me back.

00:22:25 - Anthony Campolo

Wow, we're blowing up. I got like 200 people watching me on X right now.

00:22:30 - Dev Agrawal

Nice. Uh, yeah, you use— useDeferredValue is an interesting hook. I don't know if like—

00:22:35 - Anthony Campolo

he's back on Twitch.

00:22:36 - Dev Agrawal

Perfect. Yeah, honestly, I don't even know if there's— if like a majority of React developers know what useDeferredValue is.

00:22:43 - Anthony Campolo

Um, I, I don't know what that is.

00:22:46 - Dev Agrawal

Yeah, uh, but yeah, the idea is that isPending is going to only work for the second category of async, when the data— you already have the old data and the new data is being refetched. The second argument of isPending is very specifically for like, like, is so that isPending does not trigger suspense. It's like a almost an edge case thing where if you want to opt out of suspense at some point, you're going to use the second argument of isPending to do that. Everyone is on YouTube. Yeah, almost.

00:23:29 - Anthony Campolo

Okay, sorry, I was just opening up the editor so I can start dropping links in the, the YouTube description.

00:23:36 - Dev Agrawal

Yeah, um, and I should also drop a link to this demo that I was sharing, which has been like shared, uh, 100 times on Twitter already. I, I made this demo as like a, uh, like just a very quick random demo to show at my conference talk in January. And Ryan kind of just like took it and started running with it and experimenting every single async feature, async, and I like async.

00:24:05 - Anthony Campolo

Demo-based development, tutorial-based development. I think all that stuff is super great.

00:24:10 - Dev Agrawal

Yeah. I mean, it makes it It kind of like shows the point where like you can have bad demos that are not really helpful to show anything, but every once in a while you can make a demo that is like super helpful for a bunch of stuff.

00:24:28 - Anthony Campolo

Yeah, man, I was— that's kind of what I did at many of the companies I worked at. It's like one of the main things I tried to do.

00:24:35 - Dev Agrawal

Yeah, uh, yeah, so I hope, I hope that answers kind of— that kind of answers the question about—

00:24:41 - Anthony Campolo

yeah, that Hopefully it does. That was pretty, pretty thorough, but I think you were about to start talking about mutable derivations.

00:24:48 - Dev Agrawal

Yeah, so mutable derivations. OK, so we have create_signal and create_memo. So create_signal is the one with the setter and create_memo is the derived version, right? But both of them are like immutable, as in you replace the entire value. If you don't replace the entire value, you have to specifically opt in, but Like, it's— you use createSignal and createMemo when the entire value is being replaced. So, you usually use it with primitive values. createStore is what you would use for when you have objects and arrays or more complex state, which is what we are going to get to when we talk about state management as well. But— and createStore is the version with the setter. We don't have a derived version of createStore like we have createMemo. So— It's like if you put them in a 2x2 axis, createSignal and createMemo, createStore are 3 of them and then there's a 4th one that's missing. That's kind of like createMemo where it's derived, it doesn't have a setter, but it's like createStore in the sense that it can handle nested state with objects and trees. So that's what mutable derivations are. And there's a lot of state, like basically anytime you have large object inside a create memo, something like that, uh, this new primitive is going to help it, uh, help a lot in terms of both how you write that logic and how that updates the rest of your app in a very, very fine-grained way.

00:26:17 - Anthony Campolo

Interesting. Yeah, because the way Maya is set up, it's a, it's like a 5-step form, and it starts off with the form store. That's kind of like an object that has each step. And then as you kind of go through it, it adds more and more things. And then at the end you have this big object that has like all the things that basically ends up being the show note.

00:26:38 - Dev Agrawal

Nice. Do you have any place where you're writing to the store in an effect?

00:26:43 - Anthony Campolo

Um, so the— I'm not sure about in terms of the effect, but it writes to it with like every step. And then there's some times where it reaches out to save something to like an R2 bucket or like read from it. But yeah, we'll get into the code. Sure, yeah, later we can get more, more granular on that, but continue with the high-level discussion.

00:27:08 - Dev Agrawal

Yeah, but that's kind of the point of mutable derivations where it's filling the last 25% of that 2x2 access. So it is, it's like create store, but it's also like create memo. There's a lot of use cases where it's kind of, it, it's needed. So for example, createSelector was— uh, sorry, um, I don't know what's going on with my throat. Uh, so createSelector was a— it was an API that we are replacing with this. Um, there's a lot of like routing and, um, form validation, form management APIs that could really benefit from this API as well. And, uh, we had a demo last year about We basically took Ryan's Trellox, the Trello clone. We built our own version and we use— we basically hacked this mutable derivations into the 1.0 API somehow in a very unsafe way. But it allows us to get very, very nice performance and efficiency characteristics where in the React version it would include a lot of object cloning, component re-rendering, and reconciliation. Where in the Solid version it's actually super optimal. It don't— it runs very few functions, it goes straight to the DOM updates, like basically everything that Solid is, kind of stands for. And this API kind of unlocks a whole new use case where we can be even more fine-grained with that.

00:28:38 - Anthony Campolo

That's cool. Yeah, that sounds very, very relevant to me. So thanks for explaining all that. Blazingly optimal. That's funny.

00:28:46 - Dev Agrawal

Yeah. Flush boundaries, I mentioned it's kind of like the umbrella term for Suspense, ErrorBoundary, and Offscreen/Activity, whatever we end up calling it. Yeah. DeriveSignals. Again, if you have like a place where you're setting a signal inside an effect, this is going to be a more streamlined way to do that. So you can just pass the function went into the createSignal. Does that kind of make sense?

00:29:19 - Anthony Campolo

Sorry, say again. I was looking at something on project.

00:29:21 - Dev Agrawal

I'm just gonna, you know what? I'm just gonna share my entire screen.

00:29:28 - Anthony Campolo

Yeah, yeah, do that.

00:29:29 - Dev Agrawal

I don't know why I wanna—

00:29:29 - Anthony Campolo

So I was just thinking, I know I'm only using createEffect in a couple places, so I was just trying to pull it up real quick in my app so I can get a sense of where I'm doing what. So one quick question for you. If you have this big form state thing and that's kind of what you're managing throughout the course of this lifecycle, would there be no signals created at all? 'Cause you would wanna keep everything within that single store object.

00:29:55 - Dev Agrawal

Sure, yeah. If you have a store object, then, I mean, it's really more for how you like to organize your state. You can keep throwing everything into a giant store. That's completely fine. You can break them into multiple stores. You can have some signals.

00:30:14 - Anthony Campolo

This is where I think I got into trouble is that I built it originally without using a store at all. It was just, just signals. And there's like these massive signals. Like when people complain about React, they show those screenshots of like the mill— that's what I had, you know, at a certain point, like, this is clearly dumb. I'm supposed to be using a store here. I know that that's what this is for. So then I created the store. I built that in and but I haven't now gone back and removed all of those signals. So now I have like all this crazy signal stuff happening with the store and I need to like get rid of the signals. And I'm just thinking like, what, what would even be left if there were any signals? Is there some sort of transient state management that doesn't need to be in the larger store? Or even if it is something like that, would it make more sense just to simplify, to keep it all in the store?

00:30:57 - Dev Agrawal

No. Yeah, for sure. I mean, my personal opinion is that the less of these setters you have, the less bugs you're gonna have. It's kind of like the useEffect, useEffect problem where ideally you want to minimize your usage of useEffect/createEffect. And the similar thing goes for state where the most— like you want to derive as much of the state as you can. And only the things that you really cannot derive should be like createSignal or createStore. With a setter, right? Now obviously if you have a createStore, then one setter kind of like takes care of a bunch of different state and everything is more fine-grained that way. So yeah, that is the most ideal way to do it.

00:31:43 - Anthony Campolo

Great.

00:31:44 - Dev Agrawal

Yeah, createSignal is almost like a more like low-level primitive.

00:31:48 - Anthony Campolo

I was not sharing your screen for a second, but you're back on now.

00:31:51 - Dev Agrawal

Okay, yeah. So yeah, the setter was what I was talking about. Like you would, you ideally want to minimize the setters you have similar to how you want to minimize the effects. Mm-hmm. Yeah. Yeah, talk quickly talking about like derived signals. So this is a good example where we have a count and setCount. Let's say we also have some, or just count coming from like the parent component, right? And let's say that whenever the parent changes the count, I want to reflect that within my local state here. This might require usually to use a create effect where you would like setCount props.count. You would have to do something like this. And if you were doing this in React today, you would have to do this exactly. But with the, with the new Solid version, you can just do this.

00:32:54 - Anthony Campolo

Props.count. Hmm.

00:32:57 - Dev Agrawal

So, that's the idea of derived signals. It's like every signal is derived similar to createMemo. It's just that createSignal just gives you the setter.

00:33:07 - Anthony Campolo

Sweet. That's— and that's a term I kept hearing, like, I think on, like, Ryan's streams and stuff. Like, he did a stream just about derived signals, didn't he? Yes.

00:33:17 - Dev Agrawal

Yeah, yeah, honestly, like the, the running theme of, uh, 2.0 is that we, we are trying to get rid of createEffect, or almost like, like obviously we cannot get rid of it. Sure. But almost like get rid of it from your code base. Like you should—

00:33:36 - Anthony Campolo

yeah, man.

00:33:37 - Dev Agrawal

Yeah. And any, any excuse that you can come up with to use createEffect, we will offer a better API to do that, to do that use case so that you don't have to use createEffect.

00:33:50 - Anthony Campolo

Ryan tweeted about us saying, very cool to see Dev demoing the async features we've been working on. I spent so much time working on this stuff, it is a very different experience watching someone else explain or demo it. Yeah, totally.

00:34:01 - Dev Agrawal

Yeah, I just realized that my only recorded version of this demo is from January, and I've been playing with it since then, but I haven't like—

00:34:10 - Anthony Campolo

No, this is good. I might clip some stuff from this episode. I've been meaning to make clips for some of my streams, this would be a good one to do that for. I saw something about immutable stores once you finish up with this. That's the next thing I wanted to ask about.

00:34:24 - Dev Agrawal

Sure. Okay. Immutable stores. So we don't have stores in here, so I don't necessarily need to share my—

00:34:31 - Anthony Campolo

You said you had a store demo that we were going to look at.

00:34:35 - Dev Agrawal

Yeah, it's on my desktop. It's not on my laptop, which is what I'm using right now. Honestly, I think if you already have a form—

00:34:44 - Anthony Campolo

Okay, that's fine then.

00:34:44 - Dev Agrawal

Yeah, you don't need to get into that. Immutable stores, okay. Think about stuff like Redux and XState. Yes. These are state libraries that work a lot on top of immutable state where every time you have an update, you return, you clone the previous object, add all the previous properties in, change the one or two things that you need, actually need to change and return a whole new object or array, right? That's what immutable data or immutable state is. And it's one of the reasons that, one of the things that React really popularized or brought into the mainstream, this idea.

00:35:24 - Anthony Campolo

Which is funny 'cause it didn't actually have it. But it popularized it just because, so everyone had to pull in Redux for their apps 'cause they needed it.

00:35:33 - Dev Agrawal

Redux and XState made it more easier to manage with. But, and there are some very nice things about immutable state. Like Redux, and Redux has the time traveling dev tool where you can go back and forth in the—

00:35:49 - Anthony Campolo

That was the initial demo that Dan Abramov gave when he first built it and everyone was like, oh my god.

00:35:55 - Dev Agrawal

Yeah, exactly.

00:35:56 - Anthony Campolo

Immer, Nicki T throwing out the deep cuts.

00:36:00 - Dev Agrawal

Definitely, yeah. Using Immer. And I think Immer now comes like packaged up with Redux Toolkit because the syntax is so nice. Funnily enough, like SolidStore—

00:36:10 - Anthony Campolo

Zustand and Jotai, I think, were the other ones, right?

00:36:13 - Dev Agrawal

Yeah, they're the new ones, yes. But yeah, so the idea is that— so SolidStores are not immutable. SolidStores are mutable. So whatever object you start with, you make mutations to that object. You never— you very rarely— you, you go— you have a scenario where you're going to clone an object or an array and then replace a whole chunk with it and then return a whole new array. You're not going to do that with Solid Stores. You're just going to either use the path syntax to say that, uh, users.1.name equals Anthony. You're just going to do that like you do with Immer. Um, but Immer will still like give you a whole new object. Solid won't. Solid will just go and mutate that and then notify whoever's listening on that specific property.

00:37:02 - Anthony Campolo

So better for performance.

00:37:04 - Dev Agrawal

It is. Yeah, it is vastly better for performance. But the first thing is that you don't get time traveling, or like you do get time traveling, but time traveling becomes way more expensive.

00:37:14 - Anthony Campolo

Yeah. Um, I'd never honestly used it, so that to me won't feel like a big drawback.

00:37:20 - Dev Agrawal

Yeah. Yeah. It's, yeah, it's more like the, it's definitely not like a huge drawback. It's more like there are some people who wanna do it and it's more like the underlying, what really unlocks time traveling is that every time the state changes, you are only changing the things that matter. But with mutable state, you have to clone and screenshot, like snapshot every single instance, which you don't need to do with immutable state. So it makes it really hard to do things like rollback. And the other thing was reconciliation. So basically, let's say you have like a user array with 100, or like some array with 100 different objects in it. You go to the server, you refetch all that data, you are now— and you have a new array with 100 things in it, and you have an existing array with 100 things in it, and you now need to compare them. To basically figure out what changed so that you can make the mutations to your existing array. Because again, Solid stores are mutable. You have to make fine-grained mutations to it to get the performance. But if you have entirely new data from the server, now you have to go through and check every single thing to figure out what exactly to mutate on the store. So basically what React does with virtual DOM. Right, but Solid only needs to do it when you give it like fresh brand new data from like a server or from some sort of serialization layer, something like that. So that's probably something that we run into a lot.

00:38:55 - Anthony Campolo

Yeah, no, that's, that's great. That, that makes a lot of sense. Was there a library, like a Solid library that people were using to do stuff like this, like the way there's all these React ones?

00:39:04 - Dev Agrawal

Um, No, not really, because, um, I mean, so this— the solutions to these are built into Solid. So the reconcile function is built in. Um, you can use it to like compare your store data to server data and, uh, make fine-grained new in 2.0 related to this. The new thing is that the— these capabilities are getting more like a lot more performant. So now you kind of have like previously you had like mutable data and you don't get the benefits of immutable data. Now you have, you have the benefits of both. Basically, it's best of both worlds. So you still get all the performance that we get by, uh, getting like fine-grained mutations like solid stores usually do. But the way it's internally built, like immutable— and that's why it's called immutable— where it still stores, but internally it's not actually going to mutate the objects that you're working on. Or at least like when you diff it. But the diffing when you get from server, that's gotten a lot more performant because the internals are immutable. Things like time traveling also get way more viable than they were in 1.0 because again, the internals are immutable in many cases.

00:40:16 - Anthony Campolo

Mm-hmm. Yeah. It sounds like there's maybe a lot of performance stuff and a lot of improvements related to things that are working better kind of under the hood. Yeah. Are there things that are like actual new APIs or ways that developers will change the way they develop a Solid app or need to like change their mental model?

00:40:39 - Dev Agrawal

Yeah. So, a couple, I mean—

00:40:43 - Anthony Campolo

Nikki said, it still trips me up in a good way when I go from React to Solid and I'm like, why didn't it rerender? LOL.

00:40:51 - Dev Agrawal

Yeah, it took me a while initially to wrap my head around it as well. Okay, so yeah, mutable derivation plus immutable diffable stores was what I was just talking about. Again, this doesn't— like, it's mostly the same API. Lazy memos is probably the big one where, again, it's still the exact same API, but Today in Solid, if you write a createMemo, it'll just always be running based on its dependencies, even if you— regardless of whether you are actually using its value or not. At this point, I think Solid might be the only framework with eager memos. Lazy memos kind of became a trend when every other framework started picking up signals. So, like React, Angular, Svelte, everyone has lazy memos or lazy signals. Solid 2.0 finally goes into the lazy direction as well. Honestly, it might be short, like a short-term thing because eager signals come with a lot of benefits. We might just move back to it. But at least for now, lazy memos is what we are shipping with Solid 2.0, which is basically like—

00:42:07 - Anthony Campolo

Those 4 grids of like lazy, eager, memo. Or whatever the different things were.

00:42:15 - Dev Agrawal

Yeah, I had one of those. I should probably find that. But yeah, this is probably, this is not going to change the mental model too much. There's just like some people who really appreciate the fact that, hey, if a signal is not being read, then it doesn't need to be run. That means we are saving a lot of like computation stuff. And then the other big one that probably people have to get, wrap their heads around is automatic batching. Again, this is another one of those things which is not fully clear. It might be something we roll back. But the idea is like, you know, that there was a point in React where setting some piece of state did not mean that your components are now rendered. Like you can set a bunch of state, but your components haven't yet re-rendered. The state is not yet reflected in the UI. You have to call flushSync so that, okay, now it'll go and update the UI. Um, Ryan Florence talked about it recently a bunch. Um, so that we are— so that's how Solid 2.0 is going to work. Now, uh, today in Solid, if you set some state, immediately all the UI is going to be up to date. Yeah, batch function basically. So we're basically making batch the default and, uh, the new API is going to be like, it's probably going to be called flushSync, and that's how you're going to tell Solid that, okay, I have made my state updates, now go and re-render the UI. So it's, um, yeah, so it's going to help in those scenarios where you have multiple states to update or multiple different signals or store values to update and you want to do them all together. So this makes that the default.

00:44:04 - Anthony Campolo

Let's see, Spuzz Fuzzy said he used it when he built cybersecurityframework.io. He's talking about Batch there.

00:44:14 - Dev Agrawal

Cool. That's pretty cool.

00:44:18 - Anthony Campolo

I'm curious, what are self-healing error boundaries?

00:44:21 - Dev Agrawal

Self-healing error boundaries. So that— this is This is a very fun feature. Uh, let me share this tab. Okay, so we're back.

00:44:30 - Anthony Campolo

I'm thinking if there's isPending and you got error boundaries, all the stuff is here where I could build my own cell pretty easily.

00:44:38 - Dev Agrawal

Yes. Yeah. Uh, so in error boundaries in Solid come with like the fallback. The first one is the first argument of the fallback is obviously the error object, right?

00:44:50 - Anthony Campolo

Yep.

00:44:51 - Dev Agrawal

And class— yeah, uh, at least this version. Yeah, we don't have the class component version of ErrorBoundary that React does. Um, and the second— the second argument here is a reset method. So let's say— let's see if we can get this into it. Okay, so we got this into an error state, right? And we have a retry button here that calls this reset method that we get from the ErrorBoundary. Now again, we have the error boundary down here. What do you imagine the retry button would do?

00:45:26 - Anthony Campolo

I have no idea.

00:45:28 - Dev Agrawal

I mean, at the very least, it's going to try to re-render everything under it, right? Mm-hmm. But we are fetching the data up here. So what failed here was this getPhrase. So getPhrase here has like a chance, like every now and then it's going to throw an error. Right, so this is what threw an error here, which we are calling in createAsyncUp here in our component. And when you scroll down, you see another boundary with this reset, and then we are showing our UI, right? But if you click this retry, uh, it errored again, but it's basically going to try to fetch the data again.

00:46:09 - Anthony Campolo

Mm-hmm.

00:46:09 - Dev Agrawal

So the, uh, so earlier I mentioned how like Suspense and createAsync are like completely decoupled from each other, where you can put a createAsync wherever you want and you can put a Suspense wherever you want because the only thing that matters is where you read the data. It's similar with ErrorBoundary where you can put the ErrorBoundary absolutely wherever you want. You can deep— you can nest it down into your component tree as much as you want. Uh, but this reset is go— if something fails like if you fail to fetch some data, the reset will go all the way up the dependency chain or dependency graph and find the thing that has failed and it's going to retry that.

00:46:51 - Anthony Campolo

Hmm.

00:46:51 - Dev Agrawal

So here, like it doesn't matter where the CreateAsync or where the error boundary is. Like I could have this even right here like this. Uh, ErrorBoundary. Param— let's give it capital just for the fun of it. So now I have ErrorBoundary like deep, deep in my message tree where I don't have any data fetching at all, and it can, it can still retry things because, uh, because it knows that it has to retry props.text And it knows that props.text depends on upperPhrase, which depends on phrase, and which is this async thing that just failed. So it can go all the way up the dependency graph and it can retry things. So you don't need to manually— again, same thing here, like you don't need to manually wire up, uh, these refetch functions that you would get out of like something like TanStack Query. You can do it from any point in the, in the tree.

00:47:57 - Anthony Campolo

Interesting. So it makes it a lot more flexible in terms of where you can put your boundaries.

00:48:06 - Dev Agrawal

Yeah, a lot more flexible. And this is like this— some— a feature like this, like retrying on error, you would probably imagine like data fetching libraries. And yeah, of course none of the components re-render, which is, um just like staying true to Solid's initial idea that components don't exist. They should just create stuff and get out of the way. Mm-hmm. Yeah. Even though things are popping in and out with Suspense boundary and error boundaries, none of the components in here actually get re-rendered at any point.

00:48:37 - Anthony Campolo

Yeah, that's cool. It's, it's interesting to me kind of what Ryan is thinking of, and it's great that he's on the stream watching, like, like in terms of 2.0 obviously has to be a big deal for him. He's been working on this forever. 1.0 has been out for as long as I remember. So at least probably 5 years by now. 5 to 7 years. Yeah, 5 to 7 years. So it's interesting to see kind of like the set of features where he is like, these are the things that are gonna be really important for 2.0. And then, you know, could be years again before there's another big version.

00:49:10 - Dev Agrawal

Yeah. And especially because, um, like these are things that he would have implemented like 4 years ago if he wasn't nerd sniped into building SolidStart.

00:49:20 - Anthony Campolo

Right. Yeah.

00:49:21 - Dev Agrawal

Um, which—

00:49:22 - Anthony Campolo

Yeah, I think it's so worth it. I mean, to me, if there was no SolidStart, then I would be very hard to make the case for me to tell anyone to use— it would be hard for me to tell anyone to use any frontend that doesn't have a meta framework, just straight up. It just seems irresponsible.

00:49:37 - Dev Agrawal

Yeah. And I feel like it— that's going to very happen very soon with MCP servers.

00:49:43 - Anthony Campolo

Word. Yeah.

00:49:45 - Dev Agrawal

Um, yeah, but yeah, it is definitely a very big deal because, uh, especially because a lot of the issues that we are trying to address with this, especially like getting rid of createEffect, um, and like the problems that it causes in terms of not just like reactive graph, but also in terms of like mental model. Like, I have written so much horrible code because I was using useEffect in React as like a synchronization mechanism where some state updates, I do some calculation and update some other state, and that triggers another effect where that changes another state. I've written so much horrible logic like that, um, and I'm very happy that I, I get to do my part to remove that from the world.

00:50:27 - Anthony Campolo

Yeah, I mean, my number one reason I would tell people to use React frameworks back in the day was because all of them would figure out some way to wrap and use Effect so you're not really— like, there'd be some sort of framework convention. Parasocial here saying, duh, just use Astro, which is unfortunately the exact opposite direction this stream is going.

00:50:50 - Dev Agrawal

Right. Cool.

00:50:54 - Anthony Campolo

Is there anything else for 2.0 you wanted to talk about?

00:50:56 - Dev Agrawal

We can talk maybe a bit about transitions, but Um, I, yeah, I'll have to find the example for it, but, uh, basically, how much have you used transitions in React?

00:51:11 - Anthony Campolo

Not really at all.

00:51:13 - Dev Agrawal

Yeah, it's like a feature which is sometimes very hard to understand, honestly. Uh, like, it took a while for a lot of people to wrap their head around why transitions exist. It took me a lot of, like, watching Ryan's streams to understand why transitions exist.

00:51:29 - Anthony Campolo

The docs, it says useTransition is a React hook that lets you render a part of the UI in the background.

00:51:36 - Dev Agrawal

Yeah, that is a very accurate way to describe it, but I just don't know how much—

00:51:40 - Anthony Campolo

It's so accurate, it tells you literally nothing.

00:51:42 - Dev Agrawal

Exactly, yeah. Yeah, basic. Yeah, in React, so if you are familiar with React's transitions, Solid 1.0 already currently has transitions that are very similar to that. The API almost looks like one-to-one. Um, but a big problem with React transitions is that if you start multiple transitions, they all kind of just get merged into a single transition. So a lot of people on React have re— or like on Twitter, Blue Sky, have recently been complaining that, uh, if you start one tran— if you click one button and you click a second button, everything gets frozen up and then after a while you see all the updates together, which is kind of the feature of transitions. But it can be a little annoying when things just like keep merging together, like, and you have to just wait for everything to finish before anything on the screen is like waterfall essentially. Uh, it's so the— what, not literally, but yeah, yeah, yeah, basically, yeah. In for UI at least. Yeah, it definitely feels like a waterfall. Um, So, the main difference with what we're doing with Solid 2.0 is that transitions, like transitions that are independent can come on, like have their UI or like have their effects run independently. So, if one transition updates one part of the page, another transition updates another part of the page, they don't need to merge with each other. They can just happen as they complete, which would not be the case with Solid today where they would get merged anyways. Even if they are fully independent. So that's kind of just the main feature there. It's, um, it's more like a, like removing a little annoyance in a lot of different cases. Um, but it does— I'm hoping to see like if this might unlock some other things that people have not been doing with transitions just because they were merging. Uh, yeah, and some of the APIs around transitions and optimistic state are still being discussed.

00:53:49 - Anthony Campolo

Very cool. I'm just thinking now, I said something like this before the stream, like, you know, new RyanGPT features. Now that is kind of, you know, does a thing and now I'm always, all the stuff I'm building, I'm always thinking of new things to do with them now. Cause it's just like you can do anything, but, um, having it give targeted advice for migrating to 2.0 could be a cool thing.

00:54:12 - Dev Agrawal

Yes, I am definitely planning on like, so at the very least, one of the things we are going to have is a compatibility package. Yeah, migration guide is that's definitely table stakes. Yeah, but after that, like there's going to be compatibility package so you can continue like your 1.x apps will continue working.

00:54:34 - Anthony Campolo

Yes, so I was actually one thing I was going to ask, will be no literal breaking changes right away, it sounds like.

00:54:41 - Dev Agrawal

So, there are breaking changes. For example, the signature of createEffect looks very different. Mm-hmm. Or at least, yeah, it looks very different from the createEffect of 1.0. It's a bit more complicated to use, honestly. But that's like, for me, like in my head, that's fine because we're also removing a bunch of places where you might have to use it. So, it's more likely that you're going to be migrating from createEffect to a different API like create async, create projection, create signal, whatever.

00:55:12 - Anthony Campolo

Yeah. Then that's not code mods.

00:55:15 - Dev Agrawal

Yeah. So yeah, that, that, so yeah, the compatibility package and the code mod is something I'm gonna be looking more into. Um, honestly, I just, I'm just super scared of anything that has to do with build plugins or like Vite plugins, compilers, bundlers, trans, uh, ASTs. Um, okay.

00:55:33 - Anthony Campolo

Um, would it still work with Astro view transitions?

00:55:36 - Dev Agrawal

Almost. I mean, I, I don't see why not. We, we probably might have like our own Vue transitions integration built in at some point, but, um, yeah, no, still, still, I hope, I mean, uh, yeah, still not fully clear how that's going to integrate within Astro itself, or sorry, within Solid itself, but I don't see why it wouldn't work with Astro view transitions.

00:56:01 - Anthony Campolo

Yeah, if it doesn't, that's probably more on the Astro team to figure out. Right.

00:56:07 - Dev Agrawal

I mean, yeah, probably like a join thing.

00:56:09 - Anthony Campolo

Yeah. Um, that's honestly, that question in itself is one of the reasons that's motivating my migration. Cause just removing that question at all has the Solid thing interact with the Astro thing. It's a massive amount of overhead you guys should get rid of.

00:56:26 - Dev Agrawal

Hmm.

00:56:27 - Anthony Campolo

Yeah. Word. Cool. So I should probably pull up—

00:56:36 - Dev Agrawal

Yeah, code mods. Yeah, sorry. Quick word on code mods. They might happen depending on if there are any migrations that are complicated enough to get code mods. What I'm more excited about is just writing a migration guide that's detailed enough that I can point Claude to it. And let it do the migration for me.

00:56:59 - Anthony Campolo

Totally.

00:57:00 - Dev Agrawal

That might resolve a bunch of like, maybe we don't need code mods for these.

00:57:06 - Anthony Campolo

Yeah, I really think that is a super good strategy because code mods can be very brittle and have weird edge cases and then you're messing with people's code bases, whereas giving the context and instructions that an LLM can do it, then it can just look at each file, write to your new file, make the update, and then you can check it one by one.

00:57:30 - Dev Agrawal

Yes. Yeah, exactly.

00:57:34 - Anthony Campolo

Awesome. So I'm going to share my screen. We can check out— I alluded to it a bit— how I'm doing the form stuff. So let me pop this guy. Open. So let me just, we'll start in the, in the store. So this is kind of what I was talking about, how there's like the big form state. So actually, sorry, I wanna actually first just show you what the current app does.

00:58:05 - Dev Agrawal

Yeah. Plug. It's your screen.

00:58:08 - Anthony Campolo

Yeah. So cool. So we got 3 different options, local file, RSS feed, video URL. I've also got search now. So search for Ryan Carniato, you can find his videos. Let me find a short one. And then this is the only blocking step here. After this, you can— it kind of all runs in the background. So you pick your transcription and then you pick whatever prompts you want, and that just kind of runs in the background so people can kind of get to whatever they want to do and they're not like waiting for each step to have to finish. And then once you get to the end, then it kind of tells you which step it's on and it will run through it and then eventually redirect you. So the, the form state is essentially all of the things you're selecting as you're going through this. So you selected a transcription service, you selected a random number of prompts, you selected the LLM, and then the background things that are each running. Each time those complete is then also updating the state. So that includes things that need to eventually be saved to the show note objects at the end, which is all being saved as a big R2 object that then is rendered in this page and has the metadata, which is the title, the date, length of time, the model you use, how many credits it costs, and then the actual content itself, and then the transcription that is associated with it. So if we look back at here, it first starts with— this is all step 1. You select what is the thing that you're actually doing. Is it a video? Is it an RSS? Or is it just a file? And then it does kind of the transcription stuff around here, and then it gets into the prompts and the LLM stuff around here. I had originally wanted this to be separated out so there'd be literally step 1, step 2, step 3, step 4, step 5 that breaks it up. But I'm somewhere in my vibe coding journey that got lost in the process. And then there's a ton more code in this file that I need to kind of refactor and separate out, 'cause there's basically all of the background stuff is here. So, let me actually start by, let me collapse these. So, there's everything that's happening in the background for the media processing, the transcription, the, oh, and there's also like calculating the credit cost. Things like that. So, there's all of this crap happening here, and then the components themselves are then up in here. There's a directory for each specific step. So, there's the process steps, and then there's each one. Actually, let me go to this first, steps wrapper. I think this will be— yeah, so you see here, this is where you can kind of see how I originally had a whole bunch of crap that was happening in terms of signals for each step. And so, there's a whole bunch of code here. This is all the crap that I wanna remove. So, that's just going through the store. And then it just kind of has these 5 steps that are then displayed. And then this, okay, that's the one I want. Yeah, that's the steps wrapper. So, that's in the dashboard. The steps wrapper wraps each individual step and then each step is doing all of this management of the Signal. And then this is also where the createEffects are happening 'cause each step is hitting one of the API routes 'cause we've got the backend has the kind of like, so you see how there's numbers for each step, step 1, 2, 3, 4, 5, those go go with that, the API. Step 1 is select content. Step 2 is process transcription. Step 3 is select prompts. Step 4 is process LLMs. There should really be a step 5, which is like actually writing the result, but that's kind of all mixed up in the show notes and the session endpoints as well. So that's kind of the high-level description of what is happening. So questions or comments from that?

01:02:48 - Dev Agrawal

It looks really cool. I mean, there's a few things that I, uh, noted, but yeah, we can get to them eventually. I mean, the first thing that I see here is error null is loading, which I'm excited as the— these fields will no longer need to be any sort of state with 2.0, uh, right?

01:03:07 - Anthony Campolo

Yeah, cool, cool.

01:03:13 - Dev Agrawal

Yeah, so, uh, what, what kind of issues are you running into? With this?

01:03:17 - Anthony Campolo

So I think, so I'm currently not running into issues. It was more so that I was running into issues so that the, I'll give you an example of something that I just couldn't understand why I was having this issue. And it just, I thought it should have been so much simpler was out of all the state management stuff, something that would can just for some reason at a certain point, whoops, broke was that the prompt selection. So when you select a prompt, you know, it does that. But what was happening is when I would click it, it wouldn't do anything. Like it would kind of light up and it would originally, then it would go right back. So something was happening where it wasn't saving the state just for that one thing. And I would go back to the LLM, it would just get super confused. And then, and, and I, and I think I know why. I think it was because I had what I originally said, I started with all these signals and then introduced a store, but without properly doing that where it would've looked how it should've been if I started from the store. So it was getting lost in the sauce somewhere and not realizing where the state was, how it was going from the signals to the store or back again. And so it just got super duper confused to the point where I had to go find additional SolidJS doc pages to share with it. So I, 'cause also I think this is partly 'cause it, it tends to still think sometimes that it's writing React and it can get away with that sometimes, but not always. And I think this is an example where what was happening under the hood was different enough from React that it wasn't able to be like, I need to switch into SolidJS mode to handle this the Solid way. So that's how I felt giving it the doc pages. Then it could all of a sudden, and then I would tell, you know, write logs to track the state management in the console and I would feed it back those logs and eventually it understood what the code it was writing was doing and figured it out. Currently, I worked through those issues. I don't have any state management problems per se. My problem is, as I've been saying, that the code is just really messy and I need to refactor it. It's doing all of this just through the correct kind of store conventions that you would have. And there's this one page complex state management SolidJS. This is the one thing that I found helps the LLMs is you have this, you have a state management page and you have a complex state management. So I don't know if you've read this doc recently, but kind of curious what exactly is it explaining that is not just explained in the store section, do you know?

01:06:02 - Dev Agrawal

So can you put this one in the link? I don't think I've read this one in a while.

01:06:07 - Anthony Campolo

Great.

01:06:08 - Dev Agrawal

We can, but yeah, we can—

01:06:09 - Anthony Campolo

We can catch up on some comments here real quick.

01:06:11 - Dev Agrawal

Yep.

01:06:12 - Anthony Campolo

Love the new auto show, looks amazing. Thanks, man. I spent a lot of time on the styling. A lot of love and care went into that. Spy2Fuzzy and nickyt keep bouncing back from YouTube and Twitch for some reason. Okay. So, let me go back to the— this page. So, it talks about how you make changes to the store.

01:06:39 - Dev Agrawal

Mm-hmm.

01:06:40 - Anthony Campolo

How you add to an array.

01:06:45 - Dev Agrawal

Yeah. So, the two major things that this kind of introduces are like stores and context, which like not using—

01:06:53 - Anthony Campolo

I don't think I'm using createContext in the app.

01:06:56 - Dev Agrawal

That's fine.

01:06:57 - Anthony Campolo

I'm not.

01:06:58 - Dev Agrawal

Yeah, you, you just have a global store. Yeah, um, yeah, you, you just have a global store. Context, context is helpful if you want to do like some sort of dependent dependency injection. So I mean, it, it's, it works the same way as it does in React, uh, except that you use context doesn't cause a bunch of unnecessary re-renders because everything— because things are signals. Um, but yeah, the, the main point is just that createStore is a very nice utility to clump together a bunch of state into just an object. So you don't— you're, you're not dealing with like calling functions to read data anymore. You're, you're just using an object. Um, and then the other one is that if you scroll down a bit, there is a Produce, or if you just search for Produce—

01:07:48 - Anthony Campolo

yeah, I did, I did see that. Yeah, I was gonna ask about that.

01:07:51 - Dev Agrawal

Yeah, so it's, uh, it's just like the Immer version where, um, you get like a mutable copy or like a proxy of the object, and then you just make mutations to it. So instead of using this path syntax, which like, uh, the first snippet in this screenshot is using. This is the path syntax and the second one is produce. Produce is gonna become the default in Solid 2.0. Currently you have to use this produce helper to do it. But again, it makes it really easy to take like a giant piece of object and then just make mutations to, to it anywhere. And it also allows you to do a bunch of mutations together within a single function so that you don't have to like wrap it with batch. So like there's a bunch, there was a bunch of places where you had like 5 setState calls one after the other, right? So you can combine all of them using this produce syntax. Um, it's, uh, it's probably going, it's going to probably going to make it a bit easier to read that way.

01:08:54 - Anthony Campolo

Yeah, it's, it's saying here something that I was actually kind of curious about. I was like, what is the difference between just doing produce versus setState, you know?

01:09:01 - Dev Agrawal

Yeah. So just that store, you have to like give it a path. Uh, with Produce, you just get an object and you can like navigate to whatever path you want. So like user.username and user.location in this one, in this example. Um, uh, like one of the things I actually like about Solid is that it doesn't come with a lot of conventions around, uh, how to manage state. And on some level, like, it doesn't need to, um, because what I've found working on React for so long is that a lot of conventions around state management exist not, not just to solve complexity, but to also make things more performant. Like, you have to use selectors some— sometimes you have to like filter things, or you have to use like additional APIs, you have to hoist things up into like global scope, or like things like Redux. A lot of state management in React is like complexity and performance like combined together.

01:10:03 - Anthony Campolo

Right.

01:10:04 - Dev Agrawal

But with Solid, performance is not really a thing we need to worry about. That's like everything just works in the most optimal way by default. Which also means that a lot of conventions that we have built or that we expect around state management, they don't actually need to exist anymore. So, and the only thing that you are left with is how you organize your code. That's all.

01:10:28 - Anthony Campolo

Yeah. Yeah. And that is the, the thing that I really, really like about Solid. Cool, man. Okay. That's super useful. Um, looks like I got some more stuff. My fuzzy SolidJS secret is that I use it as a global store and import it as a module with all the state handlers being returned from it. Keeps everything simple.

01:10:52 - Dev Agrawal

Nice. Yeah, global store, um, state handlers being returned from it. Yeah, so that, that's like one of the ideal ways to use stores, where when you have like a re— something not— that's not just reusable, but it's like more complicated in terms of how you make changes to the state. Uh, a good way to abstract that is to like have a create form state or something like that where you just return the read-only state. You don't return the setter. You only return explicit functions that make changes to the store. So, it kind of emulates the Redux reducer pattern where you have to define all your mutations up front.

01:11:34 - Anthony Campolo

Yeah, that's what everyone hated about Redux. And that's what the Redux Toolkit, I think, was supposed to make that better, you know?

01:11:40 - Dev Agrawal

Yeah, exactly. Yeah. So, the overall, like, theme of the— a lot of state management solutions in terms of, like, how they handle complexity is basically it boils down to, like, controlling or, like, making the mutations up front and well-defined. Like, if you have just a giant piece of state object and anywhere or like any component is allowed to make changes to it, that's how you run into unpredictability problem— named mutations, yeah. So, if you don't have named mutations, if any object can make changes to your state from anywhere, this is kind of the problem that—

01:12:19 - Anthony Campolo

It's a total mess, yeah.

01:12:19 - Dev Agrawal

Yeah, and that was like a big deal with Angular. And the thing that React kind of really brought over like existing solutions at the time, like Angular, was this like one-way data flow where You don't have anything making changes to any piece of state. You have this explicit setter that you have to pass to a child component or to a child hook to make changes to that state. So, and the thing— things that Redux and XState and like MobX, Zustand, things that— the things that they bring to the state management is that they name mutations, what Ryan is talking about. Where you have to upfront decide how the state—

01:13:06 - Anthony Campolo

define your API, you know, like I remember my bootcamp, that's kind of how it was. Like you would have, you know, your backend endpoint and you have your Redux mutations and things and whatever. And then you'd have just your React components that didn't do a whole lot cuz Redux is doing so much heavy lifting. Exactly.

01:13:20 - Dev Agrawal

Yeah. And this problem can honestly be traced back to like Java days as well, where you, you would, uh, like people writing Java would write a giant class with a bunch of properties and they would have getters and setters for every single property.

01:13:33 - Anthony Campolo

I have a specific custom function or specific custom instruction to all my LLMs to tell them never to write a class.

01:13:40 - Dev Agrawal

Yeah, it's— yeah, classes can get a little annoying sometimes. Svelte, it seems like it's really embracing them with runes, but, uh, so they might be coming back at least in some community, in some ecosystem. But yeah, it's the same problem where you need to really name your mutations. You need to define what they're doing, why they're doing it. And that addresses most of the complexity issues that you might run into.

01:14:09 - Anthony Campolo

And it makes sense to me as a GraphQL, previous GraphQL guy.

01:14:12 - Dev Agrawal

Exactly.

01:14:13 - Anthony Campolo

A lot of time thinking about mutations.

01:14:15 - Dev Agrawal

Yeah, exactly. And the final thing would be something I mentioned earlier, which is derive whatever you can. Um, which also includes like get— getting rid of createEffect. So for example, you were fetching some data inside a createEffect, right? Um, you never want to do that. Uh, that's why there's a built-in data fetching primitive called createResource that Solid comes with. So createResource is what, what you want to use if you want— if you are fetching some data in a component.

01:14:45 - Anthony Campolo

You don't want to be using createResource, not createEffect, for all the times my backend is hitting my API routes.

01:14:53 - Dev Agrawal

Yes, every single time it should be using CreateResource. Uh, and eventually, yeah, and then eventually you would be using CreateAsync for— actually, if you're, if you're using Solid Start, uh, Solid Start or Solid Router, actually it ships with a, with an API that looks very similar to— it's called CreateAsync. It looks very, very similar to the CreateAsync we have for 2.0, except that it's not it's not non-nullable, so it still returns like data or undefined. It just— it doesn't just return the data type like it does in 2.0. Um, uh, it's like just a wraparound createResource. So yeah, you want to— you want to be using that API because similar to TanStack Query, it takes care of a lot of stuff internally like cancellation, um, for you. And the second thing is that again, it makes the data flow more derived. So you don't have like this create effect problem. Again, you wanna get, you wanna get rid of the setters and the effects as much as you can. And that, that's where you wanna derive as much as you, you can. And then obviously the last thing is that that's how Suspense works. If you're fetching in the create effect, you don't get the benefits of Suspense. If you're fetching using createResource, then you get these capabilities like Suspense and transitions. And the new isPending helper, things like that.

01:16:14 - Anthony Campolo

Awesome. Before we transition to the next thing, did you— you said you were taking some notes, I think. Did you have other thoughts or specific things about how my store or stuff was set up?

01:16:27 - Dev Agrawal

I would like to see like if how you're doing validation from validation. That's a great question.

01:16:34 - Anthony Campolo

I think it's more so that most that's happening on the backend, I think. Okay. Like, you know, there's a search input or something and I don't really do any frontend validation right now. There's some things I could do where I could validate whether they're giving me like a correct URL or something. But, um, that currently is not too big of an issue because a lot of what's happening is, is just toggling because they're selecting things like they're selecting a model or they're selecting a prompt or they're selecting an LLM. The only actual inputs is when they're searching for a video or RSS feed, or if they're putting in a URL. If they go through the file picker, there's no input typing at all. That hasn't been a huge issue in terms of the validation, but there's definitely a couple of places where I do need to add that.

01:17:26 - Dev Agrawal

Okay. Not a lot of frontend validation, that's fine. I think Ryan himself also prefers doing most validation on the server just because Schema libraries tend to be pretty heavy on the bundle size. I think Valgeo kind of fixes that. It's like one of the first schema— What's it called? Is it Valgeo?

01:17:51 - Anthony Campolo

Valgeo?

01:17:52 - Dev Agrawal

Or is that the state management one? Valibot, sorry.

01:17:58 - Anthony Campolo

Valibot. Valibot versus Zod. Yeah, that has to be it. Yeah, this is— Nikki T has— was having this guy on a stream, I think, just the other day.

01:18:08 - Dev Agrawal

Yeah, the, the Valibot maintainer is doing some cool stuff with Solid as well. Yeah, so that would be a cool one to actually, like, be able to use on the front end without, like, hanging out.

01:18:21 - Anthony Campolo

Is it good enough to use instead of Zod? 'Cause I know Zod is just massive.

01:18:26 - Dev Agrawal

Yeah, I think it is. I haven't, I don't remember exactly what the bundle size was.

01:18:32 - Anthony Campolo

I remember people talking about it over a year ago, so it should be pretty good. Pretty solid by now.

01:18:37 - Dev Agrawal

Yeah, I think the main thing was that it's, uh, it's built ground up to take full advantage of tree shaking. So you are— you're not— you're only going— like, the, the less of the library you use, the smaller your bundle ends up being, basically. Um, yeah.

01:18:54 - Anthony Campolo

Um, actually, it— I'll show this real quick. So this is the, the introduction to Valibot, where he says, my friend Fabian created me as part of his bachelor's— this is like Valibot talking about itself— created as part of his bachelor's thesis, supervised by Walter Kriha, Misko Hevery, and Ryan Carniato. I had no idea that those guys were like supervising theses and stuff. That's— that is an incredible panel. So I could see why this would have— and then his role models, who's Colin McDonald, the creator of— this is sweet.

01:19:27 - Dev Agrawal

This is—

01:19:28 - Anthony Campolo

I need to get him on actually the stream.

01:19:32 - Dev Agrawal

Yeah, Valibot would be a fun stream to have. Um, yeah, uh, I— yeah, so I think it's, uh, the thing that I'm interested in seeing with the form management is how like form validation and things like that happen on the front end. Resist me.

01:19:51 - Anthony Campolo

Do you get this joke?

01:19:54 - Dev Agrawal

Yeah.

01:19:55 - Anthony Campolo

Yeah, from Superman. Really funny.

01:20:00 - Dev Agrawal

Man of Steel, yeah.

01:20:03 - Anthony Campolo

Well, it's probably, I think Superman 2 was like the first like reference when people would use to, because I remember in like a Jay and Silent Bob film, it was like, "Kneel before Zod!" When I was a kid, I was like, "What is he talking about?" Because I had never seen the old, old Superman, you know?

01:20:19 - Dev Agrawal

Right. Yeah, I still haven't. I started watching— I mean, I've seen some of the new animated stuff and obviously the all the DCEU things, but bro, I haven't watched a comic book movie in like 3 years.

01:20:32 - Anthony Campolo

I'm done.

01:20:35 - Dev Agrawal

I, I, I understand that, but you need to watch the new Thunderbolts movie. It's actually really good.

01:20:39 - Anthony Campolo

Sorry, what was it?

01:20:41 - Dev Agrawal

Uh, you need to watch the new Thunderbolts movie. It's actually really good.

01:20:45 - Anthony Campolo

Is that the dogs?

01:20:47 - Dev Agrawal

No, no, it's the, um It's a new Marvel movie. It's like their, uh, they're like new version of The Avengers, basically.

01:20:55 - Anthony Campolo

Oh yeah, it was more like Suicide Squad where they're like grittier. Yeah, that's the—

01:21:01 - Dev Agrawal

but yeah, but it's actually a really good movie.

01:21:04 - Anthony Campolo

Yeah, okay, let's check it out.

01:21:07 - Dev Agrawal

I was, uh, on at a conference in, uh, Columbus, Star Trek. So they, uh, their thing is that they do the entire conference inside a movie theater.

01:21:17 - Anthony Campolo

All right, here's the issue though. It says here it's one of the lowest grossing MCU films. Yeah, the audience for these things are stupid.

01:21:25 - Dev Agrawal

Yeah, I mean, it's— no, people are just like super tired and tired of like superhero stuff, honestly. And, uh, this movie prob— they probably— I know Marvel probably didn't think this movie would do— would turn out good, so they didn't put as much investment into it. Um, But yeah, it's a pretty good movie. It's not like Avengers, like the first Avengers. It's not close to that, but it's pretty good.

01:21:51 - Anthony Campolo

Okay, that movie already exists. Fuzzy says you just redeemed yourself. Cool. I'm going to use the bathroom real quick, but I want to tee you up on a topic first. I want to just kind of give you a chance to give like very, very general advice. If you were like, you know, being a consultant or like talking to someone and giving general advice about like, how do you think about a large complex Solid app? What should be top of mind when you're like architecting it and building it? You know, we've talked about a million things already on this stream. So maybe like, maybe like really high level, like what are like the top 3 things that's like, these are, you don't want to skip these 3 things, you know?

01:22:40 - Dev Agrawal

Yeah, that, that is a good point to bring up. I, I think the— anytime you're working on any kind of large system, there's a— like, there's the accidental complexity and the essential complexity, which people often talk about. The accidental— the essential complexity is like the complexity that comes from just the domain you're working on. So constraints, affordances, and state. Yeah, that's, that's also a good, a good way to like categorize a bunch of stuff that you might run into. Um, but yeah, essential complexity, for example, if you have a to-do list versus a very complicated form with a bunch of validation, dynamic fields, uh, or something that, uh, something similar to what Anthony was showing earlier. That's just an inherently complex thing and that will require a good chunk of thinking in terms of like how you organize your code, how you, uh, keep things— keep the complicated complex things like separate from each other so you can work on them separately and you don't accidentally break things when, uh, when you make changes to one part. And accidental complexity comes in when, uh, when you try to apply the solution you have in your head using the tools that you have. So one example is just like dependency arrays in React. That using dependency arrays is not something inherent to the thing you're building, it's something you have to do because you're working with React. That's kind of how it is. Um, same thing with like what I was showing earlier with data fetching and Suspense and error boundaries. Like if you're— if you have some components that fetch data, well, that's fine. You can just use whatever data fetching library you have. But now because of the way that React works, there's this accidental complexity in terms of where do you place the Suspense boundary? Or what do you put in the dependency arrays? Or where do you use— where do you put your useState and useContext so that it doesn't re-render often. So for example, if you have a very complicated piece of app all stuffed inside one giant component in React, that's the worst way of doing that in React because, uh, whenever you create useState in a React component, that entire component now needs to re-render. And if you have all the logic inside one giant component then every single update will make that entire component re-render and reconcile again. Which means the, the way that you have to break up your code into pieces, that's no longer just, um, like an essential complexity thing. That's an accidental complexity thing because now you have to— you're worrying more about the tool than you are about your problem. Um, so I think the, the thing that I pay attention to the most is, uh, if there is any piece of complexity that's showing up in my apps, is it because of, uh, the thing that I'm working on is complicated, or is it the tool causing those complexities in, in itself? Uh, so that this has helped me simplify a lot, a lot of things because just the way that the APIs are designed in Solid like some of the stuff that I showed, and then some Solid Start stuff like the cache query helpers and the server functions. They get rid of a lot of complexity around like API routes. So right now, Anthony, you're using API routes for fetching, but once this moves to Solid Start, you can move a lot of that logic to server functions, and that's going to eliminate a lot of additional code that you have to write.

01:26:39 - Anthony Campolo

Totally.

01:26:40 - Dev Agrawal

Yeah. And especially if you're using the query and action helpers that come from—

01:26:46 - Anthony Campolo

I was just about to ask about the actions. Yeah.

01:26:48 - Dev Agrawal

'Cause that's what those are for. Yeah.

01:26:49 - Anthony Campolo

Yeah.

01:26:50 - Dev Agrawal

Exactly. Yeah. So again, these are APIs that to me are very well designed to like eliminate additional like accidental complexity that I don't really get from a lot of other frameworks. SvelteKit recently realized all of this and it has like introduced, like, await asynchronous Svelte and then remote functions to basically look very similar to Solid Start. And I'm happy to see this, like, more frameworks adopting it. React Server Components was—

01:27:22 - Anthony Campolo

always gotta rip off the best.

01:27:24 - Dev Agrawal

Exactly.

01:27:24 - Anthony Campolo

Yeah.

01:27:25 - Dev Agrawal

React Server Components was one of the first places where I really like saw the full extent of this, where how much of accidental complexity can be removed if you design your APIs right. But again, RFCs introduced a bunch of them as well, so kind of negated.

01:27:42 - Anthony Campolo

That's interesting. Yeah, I used to be the biggest Svelte fanboy. I was super into Svelte before. I was into things like Solid and other stuff and just kind of slowly used it less and less and got away from it. And I feel like it always had a very like dedicated small community, and it's one of the things I liked about it, but also I feel like was slightly drawback about it. So I haven't used SvelteKit in a while, but I remember, and you can take this to the bank, I wrote the first ever SvelteKit tutorial, 'cause I wrote it the day it came out. I sat down and I wrote a tutorial and I published it, and I know for a fact no one else did that day. So that's my one claim to fame when it comes to SvelteKit.

01:28:23 - Dev Agrawal

That's awesome. Yeah. Uh, that, that's pretty cool. And, uh, yeah, this, so SvelteKit used to have this like data, uh, page data thing where you have to fetch all your data in route loaders. Uh, which obviously it got from Remix and SolidSmart had that for a while as well, which we got from Remix.

01:28:42 - Anthony Campolo

Um, but is that not a thing anymore?

01:28:46 - Dev Agrawal

Yeah.

01:28:46 - Anthony Campolo

So I mean the, I get to miss that entire era of web dev then. Cause I never even used Remix much. And by the time Svelte had it, I wasn't using Svelte anymore.

01:28:56 - Dev Agrawal

Exactly. Yeah.

01:28:58 - Anthony Campolo

Yeah.

01:28:58 - Dev Agrawal

Route loaders for me is another one of those things where you have to fetch data on the route level. You cannot—

01:29:04 - Anthony Campolo

I will say it was sick for GraphQL. I think I remember that was like the thing that made it awesome.

01:29:10 - Dev Agrawal

Yeah. So yeah, it actually works really well with GraphQL because you have fragments and fragments are really nice to like have a bunch of like distributed places where like, okay, now here I need this data, here I need this data. And then have something like Relay just bundle it all up for you. For you. Right. But for us muggles that don't get to use GraphQL, if we want the same performance characteristics, we are either forced to manually kind of write those route loaders or the new paradigm which Solid Start kind of pioneered and TanStack Start made a very similar thing. Solid— SvelteKit is almost certainly going to do very similar things as well, which is just fetching your components. That's fine. And you still have your route loaders to preload, but all they're going to do is to like preload data into your cache. But there— but the way you get the data into your components is still going to be createAsync, createResource. Whatever you— or like useQuery, useSuspenseQuery in case of React. So we're not going to move data fetching up there, we're just going to do preloading. And it keeps the colocation benefits where your component decides exactly what data it needs. That doesn't need to be split across two different modules.

01:30:37 - Anthony Campolo

Is there a difference between preloading and prefetching?

01:30:41 - Dev Agrawal

Uh, not really.

01:30:43 - Anthony Campolo

Yeah. Just wanna make sure the terminology there. Yeah.

01:30:45 - Dev Agrawal

Cause I do.

01:30:45 - Anthony Campolo

Yeah. Cause I know what prefetching is, so that's, that's good.

01:30:47 - Dev Agrawal

Yeah.

01:30:48 - Anthony Campolo

There, there's some stuff where once I get to higher level performance stuff, mm-hmm, where I'll probably wanna like code split each step so that way like they can get like a really snappy instant thing where the dashboard kind of first comes up. Cuz the, the whole dashboard I think loads kind of all at the beginning. And so that's some places where I could kind of get make things more granular.

01:31:07 - Dev Agrawal

Yeah.

01:31:08 - Anthony Campolo

Yep.

01:31:08 - Dev Agrawal

Definitely. And, like, pretty much every framework these days will give you automatic code splitting for different routes. And if you have, like, more complicated layouts, then you can use, like, nested routes, which, again, it was kind of React Router's, or Remix's big innovation that everyone else after them adopted. But yeah, nested routes is a really powerful way to—

01:31:36 - Anthony Campolo

Redwood had nested routes forever.

01:31:38 - Dev Agrawal

Yeah, I mean, it was built on top of React Router, right?

01:31:41 - Anthony Campolo

Redwood, no. No, Redwood has really had a custom router built for, inspired by Rails, taking some from React Router. But they specifically did not want to use React Router because they couldn't do all the things the Rails router did. So obviously it was unusable. Right.

01:31:56 - Dev Agrawal

Oh, Ember Router.

01:31:57 - Anthony Campolo

Ember Router was the—

01:31:58 - Dev Agrawal

Okay, nested routing also goes back to Ember.

01:32:00 - Anthony Campolo

Yeah, so the Ember Router, thing that filtered into React Router is then what was combined with the Rails influence to create the Redwood Router, which is why the Redwood Router ended up being fricking sick and amazing and did so many things no one had any idea because no one ever used the framework. For like years I saw all these new features being added over and over again and I was like, you guys didn't have that already? What have you been doing?

01:32:23 - Dev Agrawal

Honestly, Redwood these days looks a lot more appealing because of AI.

01:32:29 - Anthony Campolo

Yeah.

01:32:29 - Dev Agrawal

Like having like Prisma's type safety, GraphQL's like a language and Storybook to like test your components.

01:32:37 - Anthony Campolo

It's actually a really, it feels like a really nice thing for AI to play with because, uh, I was able to vibe code, uh, iteration of Auto Show with when I did the Redwood stream with Peter that, yeah, it, it worked on the first shot, which I was like, this never works on the first shot with new frameworks.

01:32:55 - Dev Agrawal

Yeah, exactly. We're hoping to fix that. Totally.

01:33:00 - Anthony Campolo

Yeah.

01:33:01 - Dev Agrawal

But yeah, complex apps, just try to notice when you're getting into accidental complexity and not essential complexity.

01:33:09 - Anthony Campolo

Can we make that more prescriptive? Like, what is the situation where that would happen and what would you do to ensure that?

01:33:15 - Anthony Campolo

Yeah.

01:33:15 - Dev Agrawal

Yeah.

01:33:16 - Dev Agrawal

So, I mean, fetching data is one example where frameworks now have like RPCs, RPC mechanisms. So Next has server actions, Solid Start has server functions, SvelteKit now has remote functions. So taking advantage of these abstractions instead of writing fetch calls and doing like JSON.parse, JSON.stringify, things like that, those are super helpful to eliminate because I've written so, so much code that is just wrapping over fetch to like make things more type safe and, uh, like hide some complexity things. All those things are now built into the framework. So take, take advantage of framework primitives like server functions, um, uh, things like that. Uh, when it comes to state management, again, like things that we mentioned, we talked, we went over that topic pretty well, I think.

01:34:10 - Anthony Campolo

Yeah, so yeah, exactly.

01:34:13 - Dev Agrawal

Yeah, those things like use doors, derive what you can. What are some other things? There's some stuff around streaming and WebSockets that I'm working on. Yeah, component boundaries is an interesting one because a lot of people get hung up on how big or small should my components be, how should I organize my files within my project. Yeah.

01:34:36 - Anthony Campolo

Mm-hmm.

01:34:37 - Dev Agrawal

Yeah, so those are like It's actually taste-based. Yeah, exactly.

01:34:42 - Anthony Campolo

For me, I now, I'm, I'm entirely driven by what is gonna be best for the LLM because when they get too long, they get confused and then the responses take really long. So I have to write this whole new file each time in terms of my workflow. So I'm always kind of aiming between 1 and 200 lines of code for my components.

01:35:01 - Dev Agrawal

Yeah. Yeah, exactly. So like whatever. Just feels right. I think Dan Abramov has this really funny website where it's called like how to organize your React components or something like that. And it's just a blank page that says however you feel like it or something like that. I forget what it actually is.

01:35:25 - Anthony Campolo

That's really funny. Something— oh, quick question. My problem with leveraging any of the aforementioned framework RPC methods is with the deployment providers and how it works in broad, the drift between your environments is just to, hey, Fuzzy, I got your solution for you. Run that shit in a Docker container. I have my, my thing has been containerized the entire time. I never tried to like get this like Astro API thing working on like Netlify or Vercel or something because yeah, it would be an absolute nightmare.

01:35:56 - Dev Agrawal

Mm-hmm.

01:35:57 - Anthony Campolo

Very challenging.

01:35:59 - Dev Agrawal

I mean, honestly, um, I would want to hear more about like what the deployment provider's issue is because I feel like the thing is server functions just compile down to regular API routes.

01:36:13 - Anthony Campolo

So the problem is they compile down to Lambdas and most people want a Node server. That's the inherent issue with these always, I think.

01:36:21 - Dev Agrawal

They don't compile to Lambdas, they just compile for JavaScript functions and they run wherever you deploy them.

01:36:27 - Anthony Campolo

Okay, they run on Lambdas.

01:36:29 - Dev Agrawal

I mean, if you— then the API functions, the API server that you have right now, the API endpoints, they, they would also run on Lambda. So it's not—

01:36:38 - Anthony Campolo

now they do for the most part.

01:36:40 - Dev Agrawal

Yeah, exactly.

01:36:41 - Anthony Campolo

So weird shit still happens every now and then.

01:36:44 - Dev Agrawal

Yeah. So what I'm trying to say is that, uh, where these server— where the server logic runs is an entirely different concern from how you write them. So whether you're using API endpoints like you are right now, or—

01:37:01 - Anthony Campolo

I think what Fuzzy is saying though is you can take out the question at all of even worrying about where it runs. I think it's kind of what he's trying to get at.

01:37:08 - Dev Agrawal

Hey, can you say that again?

01:37:10 - Anthony Campolo

Because you're saying there's a separate thing between the complication of the thing itself versus the complication of how it's running, right? So I think what Fuzzy is saying here is that he doesn't want to have to think about the issue of how it's running at all. Which is that level of complexity that is added by using the deployment providers that he's probably talking about. Fuzzy, you should expand on what you mean here. I'm just reading it, trying to guess based on your first response.

01:37:37 - Dev Agrawal

Yeah. If you have any server logic anywhere, you would have to worry about where it's running. You would have to worry about where your server logic is running even if you have API endpoints like you have in AutoShow right now.

01:37:49 - Anthony Campolo

Fuzzy, I'm spot on. Yeah. And, and that's why I like just having it run in a Docker container. Cause then it's basically just like running a Node server. Whereas if you are trying to do one versus the other, if you're doing it in a Netlify function, it'll be different from a Vercel function. So that, that is a layer of complex cuz they're different. So there's something there that you need to know and understand cuz the code will not work on both of them if you just write them, you know, unless you write them highly specifically to work on both of them, which is like then a whole different level of trying to make it not stay And then you add Cloudflare Workers and then there's that, there's even more things to think about.

01:38:25 - Dev Agrawal

Yeah. And that's definitely an issue. And Nitro exists to solve exactly that issue, which is a, oh, I need to charge my laptop or it's gonna die. Give me a second.

01:38:39 - Anthony Campolo

Yeah, yeah. Do your thing. Yeah, Nitro, I'll share my screen and, 'cause, I remember when this first came out, I was like, this looks sick. Deploy Anywhere, deployment providers. The default production output preset is a Node.js server. That's all I need to hear. Done. You can run it on Amplify, deep cut old school, Azure, Cloudflare, Firebase, don't ever do that, Netlify, Vercel, and two I have never even heard of. StormKit. The hell is StormKit? And Zia Burr self-hosted for selling Netlify alternative. I'm intrigued. Interesting. No vendor lock-in. Bold claim. And then what is Zia Burr? The DevOps AI agent for 5 coders. That's a pretty good headline.

01:39:38 - Dev Agrawal

Yeah.

01:39:39 - Anthony Campolo

Funny.

01:39:40 - Dev Agrawal

But yeah, so how familiar are you with Nitro?

01:39:45 - Anthony Campolo

Providers just need to integrate better in dev. Yeah, yeah, this can be handled at the Vite level. Yeah, Vite does solve a lot of this. So Nitro is the, it was first created as like the server layer essentially to Nuxt and has been now made agnostic. H was the real thing it was based on. And I know that's been the— Nitro has been the foundation for Solid Start, I think, if not since the beginning, for a very, very long time. And yeah, no, it's super sweet.

01:40:19 - Dev Agrawal

Yeah.

01:40:19 - Anthony Campolo

Big fan, Nev, sir.

01:40:21 - Dev Agrawal

Nice to see you here. Yeah, I've seen you on Twitter a bunch. I like the Swelt in the last name.

01:40:30 - Anthony Campolo

So why is Nitro Nitro cool to you?

01:40:35 - Dev Agrawal

So, I mean, the exact issue that we were just talking about where the same code doesn't work on every deployment platform, you have to write different code for it.

01:40:47 - Anthony Campolo

Oh, also it looks like it's since the differences between Bun and Deno and Node.

01:40:51 - Dev Agrawal

Yeah, exactly. So Nitro and I think the other one these days is Hono, which is just a web server. It doesn't have all the features of Nitro.

01:41:00 - Anthony Campolo

I was very close to using Hono actually for AutoShell at a certain point.

01:41:06 - Dev Agrawal

Yeah. Um, yeah.

01:41:07 - Anthony Campolo

So basically it, they, they handle everything, whether it's on Edge or Lambda, whether it's a different runtime, whether it, yeah, they, they've thought of everything. It looks like.

01:41:16 - Dev Agrawal

Exactly. Yeah. I mean, because the idea of Nuxt was that it, like, it should be deployable everywhere and then the, the Nuxt community is just like so nice that they, they want to open or, uh, make every single thing framework agnostic, which—

01:41:32 - Anthony Campolo

yeah, I might start just running my Node server just as a Node server, not in Docker, because this might make this super duper easy to do.

01:41:41 - Dev Agrawal

Yeah, where do you have it deployed?

01:41:44 - Anthony Campolo

Uh, Railway.

01:41:45 - Dev Agrawal

Railway, okay. Yeah, so wait, are you running Docker inside Railway?

01:41:51 - Anthony Campolo

I mean, you, that's like one of the main things Railway does. It runs containers, right? I mean, like, yeah, because the main thing is, is FFmpeg. I need to use YTDLP, I need to use FFmpeg, I need to use these more like CLI-like things that really need to be able to run on like a Linux server, a Linux environment. Is you don't want to run FFmpeg in a Lambda. Like, you can do it, but you don't want to.

01:42:17 - Dev Agrawal

Yeah, makes sense for sure. Yeah, that really makes a lot of sense.

01:42:22 - Anthony Campolo

Media Bunny though looks like something that might change my life. This is the FFmpeg competitor where it apparently does stuff in the browser super duper fast. This will reduce the only real latency left in my app, so I'm excited to try this.

01:42:40 - Dev Agrawal

Nice.

01:42:41 - Anthony Campolo

What were you just saying?

01:42:44 - Dev Agrawal

Um, yeah, Nitro is super cool to me because it just addresses that platform mismatch issue. Um, it got super cool to me when they added WebSocket support, so now I can like deploy a WebSocket.

01:42:58 - Anthony Campolo

This is hilarious. They support Edge. Yeah, no, actually this is deprecated, be removed. This company went under. Finish Essence. Oh, that's interesting. They have way more than I thought, actually. They might— this is even more than I think Astro supports. Astro always had the longest list of like 20 things you could deploy to. But, uh, they don't have a Railway one. I guess I'll have to write that one for them.

01:43:26 - Dev Agrawal

I mean, it would just be the Node, standard Node.

01:43:30 - Anthony Campolo

It would be most similar to Render or if they have a Fly one. I don't have a Fly one, so it'd probably be somewhat similar. They have their whole infrastructure as code, so not really, but yeah.

01:43:41 - Dev Agrawal

Cool. Yeah, so Nitro is, like, Solid Start is built on top of it. TanStack Start is also currently built on top of it. Analog is obviously built on top of it. Nuxt is as well. And now that Vite Environment API is here, there's, uh, there's a better chance that you might not need Nitro for this. So for example, if you're using Cloudflare, then Cloudflare should have its own Vite plugin that gives you both the dev experience that with Miniflare and everything, and it handles all the, uh, bundling and deployment to, uh, Cloudflare workers without requiring like a layer like Nitro in between. But then Cloudflare has to do the work of building that Vite plugin. Or any other platform.

01:44:31 - Anthony Campolo

Yeah, yeah.

01:44:33 - Dev Agrawal

And the other nice thing about Nitro is that it just comes with a lot of caching and database persistence stuff.

01:44:39 - Anthony Campolo

What database are you using these days?

01:44:42 - Dev Agrawal

I am, uh, so for one of my projects I'm using Convex.

01:44:47 - Anthony Campolo

That's right, I do that.

01:44:48 - Dev Agrawal

Yeah, I'm, I'm currently also using something called Current, or it used to be called Event Store DB. It's more like, um, yeah, it's Current with a K, but that's, uh, so this is more—

01:45:04 - Anthony Campolo

I think I've ever heard of this.

01:45:07 - Dev Agrawal

Yeah, it's, it's not a super popular one, but it's built like from ground up for event sourcing.

01:45:13 - Anthony Campolo

So event sourcing is used this with like Kafka. I don't know anything about this stuff.

01:45:19 - Dev Agrawal

Yeah, I mean, you could use this with Kafka. You don't necessarily, uh if you have something like, uh, if there's a use case for it. But the main—

01:45:27 - Anthony Campolo

so enterprise, it's funny, it is very much the way the page looks, you know.

01:45:33 - Dev Agrawal

Yeah, it very much is. Um, that's cool though, almost reminds me of like MongoDB docs back in 2017, '18.

01:45:41 - Anthony Campolo

Uh, data engineers can provide context-rich events from current to data pipelines to analyze historical Historical behavioral trends uncovering patterns that traditional databases often miss. Interesting.

01:45:54 - Dev Agrawal

So actually, the way I'm using Convex is all like, I'm basically treating it as Current where instead of like using their documents or relationships, it's convex.dev.

01:46:05 - Anthony Campolo

Convex.dev.

01:46:06 - Dev Agrawal

Yeah, so instead of using like their—

01:46:08 - Anthony Campolo

Yeah, I'm like 90% of the way towards choosing Convex. The only thing that I'm hesitating is I also wanna run database in Railway. I think that would be nice, but I think if Convex is just gonna give me a nice experience to find my database anyway. So where do you host your database though?

01:46:24 - Dev Agrawal

You, you can run Convex on Railway. Okay. They open source.

01:46:28 - Anthony Campolo

I'm sure you can. Where, where are you running it though?

01:46:30 - Dev Agrawal

No, I'm just using their cloud platform.

01:46:32 - Anthony Campolo

So they also opt, so they, they will host your database for you as well.

01:46:36 - Dev Agrawal

Yeah. And Convex started out as like more of a Firebase alternative, very much like Supabase.

01:46:41 - Anthony Campolo

Right. Yeah.

01:46:44 - Dev Agrawal

Yeah, they recently open sourced, um, at least like the single deployable host version, uh, so that you can run it wherever you want. Yeah, there's probably some—

01:46:57 - Anthony Campolo

what is— this is the only thing that I need to know, what is the database underneath?

01:47:01 - Dev Agrawal

It's, uh, MySQL. I think it's either MySQL or Postgres, probably both. Or like it can use both.

01:47:10 - Anthony Campolo

Yeah, yeah.

01:47:11 - Dev Agrawal

They recently switched their cloud platform to use PlanetScale under the hood and it's been—

01:47:16 - Anthony Campolo

Then it has to be MySQL then if it's PlanetScale.

01:47:19 - Dev Agrawal

PlanetScale now also does, yeah, yeah, it's definitely—

01:47:22 - Anthony Campolo

Do they do Postgres now?

01:47:23 - Dev Agrawal

They do Postgres now, yes.

01:47:25 - Anthony Campolo

Of course they do. That shows you how long I've been out of the game.

01:47:29 - Dev Agrawal

Yeah, yeah, so they use MySQL under the hood.

01:47:33 - Anthony Campolo

Oh, they do, okay, they do file storage too?

01:47:35 - Dev Agrawal

Yeah, it's like, it's, it's not just a database, it's basically a backend platform. So you can do file storage, you can do—

01:47:41 - Anthony Campolo

and it hosts my Docker container, then is the only question left.

01:47:45 - Dev Agrawal

No, it cannot do that.

01:47:47 - Anthony Campolo

So then that makes me almost still just want to run everything on Railway because Railway— yeah, because Railway is about to add file storage.

01:47:54 - Dev Agrawal

Nice. Yeah, you can put Convex in there as well. Uh, the other database that I've been using recently is LiveStore. Which, yeah, so Livestore is built by the original author of Prisma.

01:48:10 - Anthony Campolo

Yeah, I know about this, yeah, yeah.

01:48:12 - Dev Agrawal

Yeah, so this is also—

01:48:13 - Anthony Campolo

I've heard of it, yeah.

01:48:15 - Dev Agrawal

Yeah, this is also an event source database. So in that category, it's like—

01:48:20 - Anthony Campolo

I think actually Peter is sponsoring this for Redwood.

01:48:22 - Dev Agrawal

He is, yes. Yeah, I think we are probably gonna talk more about Livestore when Peter comes on. Yes, it's like a database and a sync engine.

01:48:32 - Anthony Campolo

Yeah, I can see why that would be appealing to you.

01:48:36 - Dev Agrawal

Yeah, no, I love Livestore.

01:48:39 - Anthony Campolo

It's a very, very complicated front page, but it's tight.

01:48:45 - Dev Agrawal

Yeah, it has a long way to go. There's a lot of like basic like missing features like authorization, um, and it doesn't have like a—

01:48:55 - Anthony Campolo

I like this actually, what it doesn't do is right here on the front page. That's great.

01:48:59 - Dev Agrawal

Yeah.

01:49:01 - Anthony Campolo

Interesting.

01:49:01 - Dev Agrawal

But yeah, I'm super excited about LiveStore.

01:49:05 - Anthony Campolo

We should get you in these what others are saying section. There's Peter. Hmm.

01:49:13 - Dev Agrawal

A creator of LiveStore.

01:49:14 - Anthony Campolo

I think it's pretty cool.

01:49:17 - Dev Agrawal

Yeah.

01:49:17 - Anthony Campolo

Yeah, I'm not going to use this, but I might use Convex. I'm thinking real hard about it, especially if I can just do this. Probably the move right here.

01:49:29 - Dev Agrawal

And the one that I really want to use is Zero Sync. Uh, what was it? Zero Sync. Uh, yeah, Zero with Postgres. So this is from the guys who made Replicache. Um, yeah, I heard.

01:49:45 - Anthony Campolo

Is this the Zero framework? It's the same thing?

01:49:47 - Dev Agrawal

Um, the sync engine. It's not— Zero is not a framework. It's a—

01:49:51 - Anthony Campolo

okay, there's a React framework called Zero that just came out, right?

01:49:55 - Dev Agrawal

A React framework? No, there's a React framework called One.

01:49:59 - Anthony Campolo

One.

01:49:59 - Dev Agrawal

That just came out. And it uses Zero. So it's built—

01:50:04 - Anthony Campolo

You gotta be kidding me.

01:50:06 - Dev Agrawal

It's built on top of Zero. And the creator of One and the creator of Zero like live across the street from each other or something.

01:50:15 - Anthony Campolo

Is that— okay, so it— that's very good that I then confused them for each other. Shows I'm basically there.

01:50:21 - Dev Agrawal

Yeah. One is basically like Zero plus Tamagotchi. Gotcha. Which means like you write your code once and it has the same UI on both for mobile, like React Native and React Web.

01:50:36 - Anthony Campolo

Docker first. I like that. I like that.

01:50:38 - Dev Agrawal

Yeah. Zero is Docker first. So this also runs pretty well on Railway.

01:50:43 - Anthony Campolo

It works on top of T Guide as well. Yeah, I mean, I just see they have a Railway guy. No, they don't.

01:50:50 - Dev Agrawal

There is a Solid guy though. This did ship with React and Solid adapters since 1.0. Or it's alpha, not 1.0, but yeah.

01:51:01 - Anthony Campolo

You're tempting me with so much new tech, Dev. Yeah.

01:51:04 - Dev Agrawal

This is cool though. Yeah.

01:51:08 - Anthony Campolo

I gotta save all these links real quick. Let's go. Let's see which ones are important. Now we need the Nitro one for sure. So, yeah, so you're mostly Convex is still sounds like the thing that you're really hyped on in terms of backend database things.

01:51:33 - Dev Agrawal

Honestly, like I'm not super sold on any one solution just as of yet. It's like everything has like things that I like about it. Yeah, what I like about Convex is that the data and the backend are basically co-located. Um, uh, obviously reactive queries is very nice as well, but that's not— no longer like Convex's only thing. The thing that I don't like about Convex is that, uh, I need to do all my queries on the server So it's, it's a lot more, it's a lot harder to do like where you, I just want to preload all my data on the client side and then I want to do filtering and sorting everything on the client. That's something that's more complicated with Convex because Convex queries run on the server. I can do this with Zero and LiveStore, both of them, but I like what I like, event sourcing more, so I prefer LiveStore. But then LiveStore doesn't have all the same querying, and especially the incremental queries feature that Xero has. So I like that more about Xero, but Xero isn't event source. So there's like things that I like and dislike about each.

01:52:47 - Anthony Campolo

Sounds like there's a startup waiting to be built by Mr. Dev right here.

01:52:51 - Dev Agrawal

I mean, I would be the only person who uses this, whatever product I end up building. So yeah, there's definitely something that needs to be built here. That's at least for me, like it fits, it checks all the boxes.

01:53:06 - Anthony Campolo

Fuzzy, I don't need to know anything about how anything will ever work on Azure. Don't worry, none of my concern. Thankfully I would never run anything on Azure. So ridiculous. I understand lots of people do because they work at a company where they're not allowed not to. And he says you can use Postgres with pg_client and get the clients sync up and Postgres for the win.

01:53:30 - Dev Agrawal

Yeah, Nitro on Azure. I, I think it's that Azure very recently added streaming support, but the Nitro adapter hasn't been updated to use the new streaming Azure Functions API because probably no one uses it and no one cares enough. The only reason I know this is because I was trying to deploy Solid Start app to Azure at some point. Hey, ElectricSQL is also very nice.

01:54:00 - Anthony Campolo

Yeah, I remember trying to get Redwood working on Azure was by far the most complicated. Yes. It almost wouldn't have gotten done unless one dude who worked for a specific company just absolutely had to have it. Didn't build it. He built it for himself. That's the only reason why it ended up even getting made at all. Mhm.

01:54:22 - Dev Agrawal

Okay, so, uh, we haven't gotten much to talk about AI. Uh, you— I'm, I'm guessing you have been using AI a decent bit when writing Auto Show.

01:54:32 - Anthony Campolo

Yeah, I mean, 90 to 95% of the code I write is with AI.

01:54:35 - Dev Agrawal

Yeah, nice. Yeah, I'm sure Ryan would love to hear that metric. Um, but so yeah, you mentioned a little bit ago like it was having trouble with like signals and stores, and you had to eventually— you had to point it to some docs, and then it was working relatively well.

01:54:52 - Anthony Campolo

Yeah, then I was able to get— and, and partly, you know, I have a lot of experience now with how to prompt it. And so the main thing is when it's messing up something over and over again, you have to specifically tell it, hey, whatever you're changing, whatever you're trying to do, add a logging statement to see if the thing is coming out that you're expecting to come out. And then it gets more information, you feed that then back into it and then it actually can tell whether the code it's writing is doing the thing it thinks it's doing. So that's like the most important thing right there. But if it still keeps messing up, then it means they're trying to do something that doesn't make sense 'cause they don't have the contextual knowledge of the tool to know how the tool's actually gonna behave when you give it whatever code you're gonna give it. So I found that I was just like, okay, it's messing up state. Where are all the state docs on Solid? And I feed it to that so that it has that extra kind of context. I do this with lots of tools. If it can't do it the first time, I go grab the README, I give it the README, that usually helps fix the issue.

01:55:49 - Dev Agrawal

Yeah, definitely. So, um, I don't know if you have seen this blog post yet or any of the recent Angular announcements. So they did, they did like a whole livestream on Angular plus AI.

01:56:01 - Anthony Campolo

Interesting.

01:56:02 - Dev Agrawal

Uh, so they— and one of the things that they have in there is a a new tool that they have built called WebCodeGenCoder, which basically tests the ability of— yeah, this basically tests the ability of AI, specifically Gemini right now, but it works with any model. It tests their ability to basically build applications with any framework. Right now there's only Angular and Solid in there, but they came up with a Solid example. They shared an early version with us with we experimented with as well.

01:56:37 - Anthony Campolo

Uh, this is great. I love this.

01:56:39 - Dev Agrawal

Yeah, yeah. So this, uh, for them, this has been very helpful to come up with like, uh, like a system prompt that you would put in agents.md or Claude.md, and, uh, it would, it would like write better, good, and up-to-date Angular code once you do that. Um, they also have an MCP server, um, but apparently they also like use this to like get feedback on some of their API designs and documentation as well, um, and like improve their, improve their docs and APIs in using like this tool. And how—

01:57:17 - Anthony Campolo

oh, this is— were you the one who was sharing a screenshot of the score for Solid?

01:57:22 - Dev Agrawal

Yes. Now that's what I shared the screenshot for from—

01:57:26 - Anthony Campolo

okay, and that, that's so cool because that intuitively makes sense to me because for the most part, aside from the one issue I was explaining, it was very— LLMs were very good at writing solid.

01:57:36 - Dev Agrawal

Yes. Yeah, yeah. So we didn't have to do much to honestly get— so the initial version that they have, that they had when they shared it with us, it had a score of like 40, in somewhere in the 40s or 50s. Um, so it wasn't doing great. And, uh, we, we realized—

01:57:53 - Anthony Campolo

you explained what these different things are, so it's measuring build runtime, security, accessibility. So it's kind of like a Lighthouse almost.

01:58:02 - Dev Agrawal

Uh, kind of, yeah. So it's, um, basically, so there's a— there's the environment prompts, which is like what framework are you, you're using, and then there's the example prompts, which is what app you're building. So it's going to take these two things, it's going to give them to Gemini, GPT Cloud, whatever, and then, uh, it's going to come back with like code that you, uh, that then you, uh, this tool puts in a folder, uh, installs dependencies around it, and then tries to run it in a browser. Um, for first it sees if it builds or not, and then once it builds, it tries to open it up in the browser, see if it runs in the browser or not. Um, does some like basic accessibility.

01:58:43 - Anthony Campolo

That's huge, honestly, because that's one of the biggest problems with LLMs, that they never run the code, so they have no idea really what what happens after you— they hand over the code.

01:58:53 - Dev Agrawal

Yeah, there's a lot of like workflows that I've seen recently where people either use the Playwright MCP or they have Claude write a Playwright script.

01:59:03 - Anthony Campolo

I've actually gotten pretty deep into Playwright recently because I'm really enjoying using it for automation stuff because I'm, you know, doing all this LLM stuff now. So creating like Playwright scripts that will generate like screenshots of different parts of the app with different aspect ratios and then get back to the LLM so we can give them back like a mobile style versus a desktop style, like all sorts of just little things like that.

01:59:26 - Dev Agrawal

Yeah, yeah, so it's, it's really helpful for that. Uh, I had it— I had like Claude generate a bunch of pretty big like Playwright script for me to scrape some data. Um, I haven't yet used it to like write tests or things like this, but I'm, uh, I'm hoping to like find some time to invest into that because that's definitely a big, uh, way to get additional feedback into these agents.

01:59:50 - Anthony Campolo

Yeah. Which is feedback specifically that's very hard to get it to have. Yeah. This is very cool that I need to add this. I actually put out my first npm package. And Git AI, this is, I built this just for myself because I started creating this like big-ass script that initialized a project with all the things I like to have for my own thing. So like Repo Mix is the main one. But, um, It also comes with an agent that can review your code diffs and it just kind of sets you up with a good structure so that you can regenerate your stuff really quickly. So, I had just built this myself. I was like, I should just publish this, you know? And I saw the Namespaces Open. I'm like, that's a sick name. Yeah.

02:00:35 - Dev Agrawal

That's like the npm IAI billboard that Vercel had in San Francisco. Totally, yeah. Yeah, it's pretty cute. Repo Mix, I don't think I've heard of this. I should look more into this.

02:00:49 - Anthony Campolo

Yeah, so Repo Mix is how I'm able to entirely avoid using a cursor or a Cloud Code or an Open Code. And it's not necessarily that it's a one-to-one replacement, but it's more so that it's such an integral part of my own workflow that I now have this way of basically. RepoMix allows you to grab specific code files and mash them together and then add custom instructions and then any other contextual information you want to give. So you can go to any LLM, start a conversation, and immediately give it exactly what it needs to know for the feature you want to write with the code style you want to write, and it'll respond the way you want it to respond because I tell it exactly how to respond in terms of how it writes the code, whether it gives me a full code file or not a whole code file and things like that. It's just a way that I've been able to iteratively build up all of my own preferences in terms of using AI into a specific CLI tool that I can script around to have a really fast iteration. Basically, the way I do anything is I start by running a repo mix command with a couple flags that select the part of the codebase that I needed to know about, kind of like how in Cursor you can select different files to add to your context, but it's like a supercharged way of doing that. And then I just write out in like a sentence or two the thing I wanted to do, and I just copy paste that in, and then it gives me, you know, the output, and I just, you know, copy those into my project, and then that's it. That's the whole process.

02:02:17 - Dev Agrawal

Nice. So you use Repo Mix to like go to like ChatGPT or Claude and give them context about your code base?

02:02:25 - Anthony Campolo

Yeah, so you can always just one-shot something and immediately get a response that is going to actually work.

02:02:31 - Dev Agrawal

Nice. Is that like a— how much— like, how different is that? I mean, obviously it's very different, but like, how does that work? Like, you— have you found that workflow more, more productive or better than like using Claude Code?

02:02:48 - Anthony Campolo

I do, because I feel like I have more control, and I can be— because then it's only going to take the length of time it takes for it to write the things. It's not searching around your project, it's not trying to pull in the context it needs. So there's, I've found that I have dialed it in to be much, much faster. Your mileage may vary with this, 'cause if you're asking it to do a ton of stuff, needs to write you 10 code files that are all 100 lines, you know, then obviously that's not gonna be fast. But I, I've found that I really like the iterative approach. It also allows me to have multiple, going back to having multiple conversations running at once. Sometimes, like, I know I've got my AutoShow CLI and I've got the AutoShow app. Sometimes I'm I'm just popping back and forth. I create a repo mix thing with my instruction. I hand it to one. Then as that's running, I go to the other one and I do that. Then by the time I'm done starting that next prompt, I go back to the other one. The response has been written. I copy those into my— I'm bouncing back and forth between two things I'm always building simultaneously. I'm never waiting for one thing to write the code while I'm just sitting around. That I'm pretty sure you can't do with Cursor because Cursor is always going to be just doing one thing. It'll have a background agent, but I don't think you could have two background agents working on two parts of codebase at the same time, you know.

02:04:03 - Dev Agrawal

Yeah, yeah. The— so these days what I do is I have like—

02:04:06 - Anthony Campolo

I'd have tests in my project, so this— that's incorrect.

02:04:11 - Dev Agrawal

Yeah, I mean, I guess what he's trying to say is more like the— like when an agent writes the code, it immediately runs the test or sees LSP errors and is able to immediately go back and, uh, address any issues with it instead of Like if versus if you're running tests separately, you now have to copy paste those test results back into, uh, the, the AI, right?

02:04:34 - Anthony Campolo

Yeah, yeah. And that's the, the, the usually that's not an issue because it's usually gonna get right on the first shot if I give it the proper context, right? And if not, then there'll be one quick back and forth and I'm using Warp, so I click the thing, hit copy paste, and I have the entire message just right there. So that's not, that's not too big of an issue. And you say you could open two cursor windows, so yeah, there you go.

02:04:58 - Dev Agrawal

Yeah, yeah. So what I do these days is I have like at least two open code windows open, tabs open, so I can do like two separate things. If I'm waiting on one, I'll just switch to another, I'll just start doing something else. Um, you actually don't even need to have like two separate terminal windows because you can just switch to a different session within the same window and the other one keeps running. I just prefer to have different separate tabs open. And yeah, I have wanted to look more into Git worktrees to enable this, like, to basically, like, to have two different agents working on two separate parts of the codebase at the same time. So worktrees is a really nice feature. It fits really nicely with, like, Plot Code and Open Code and, like, these coding agents, um, because you can have multiple versions of your repository where you're working on different things, and then at the end you somehow merge them in. Um, you can also get a little messy, and I've never used worktrees, so it's going to be something new to learn. But that's at least, uh, I, I think what my approach is going to be like.

02:06:06 - Anthony Campolo

It's like, what's— yeah, it's a Git command.

02:06:09 - Dev Agrawal

Yeah, it's more like, like building a workflow.

02:06:12 - Anthony Campolo

Yeah.

02:06:14 - Dev Agrawal

Building a workflow around using worktrees with OpenCode. Hollywood CLI tool.

02:06:19 - Anthony Campolo

I've never heard of that.

02:06:23 - Dev Agrawal

Wow. Git worktree add code. Yeah, I mean, using Git is never that simple. You always think Git is simple, but—

02:06:31 - Anthony Campolo

Well, at this point, Warp writes my Git for me, thankfully. So that's nice.

02:06:35 - Dev Agrawal

Yeah. Yeah, I'm excited. Have you seen Zed's recent announcement about like how they're gonna build something to replace Git. All right, I mean, it'll be on top of the editor.

02:06:47 - Anthony Campolo

Yeah, I hadn't heard that.

02:06:50 - Dev Agrawal

So they're working on DeltaDB, which is basically like a more elaborate, um, source code management system, and, uh, which is like basically designed for collaboration with, uh, with AI very much.

02:07:05 - Anthony Campolo

Yeah, I mean, Zed wasn't gonna get me to move off VS Code, so the idea that they would get me to move off Git is like even less likely. Props to them for trying though.

02:07:14 - Dev Agrawal

Yeah, I actually, I'm really excited for it because I don't think the current tools are, uh, or I don't think Git is good enough for things like this.

02:07:27 - Anthony Campolo

At this point, everyone just knows how to use Git, you know, like that's gonna be so hard to try and get people to use anything but Git at this point.

02:07:35 - Dev Agrawal

Yeah, but if the AI is—

02:07:36 - Anthony Campolo

JJ, do you know what JJ is?

02:07:39 - Dev Agrawal

JJ is also like a Git wrapper slash Git replacement.

02:07:43 - Anthony Campolo

Uh, Mark, he says simpler and more complicated than Git.

02:07:47 - Dev Agrawal

That's so funny.

02:07:48 - Anthony Campolo

He says if you don't have C Matrix on your terminal, you're not a developer. I don't even know what that is, bro.

02:07:53 - Dev Agrawal

Yeah, uh, so yeah, the reason I brought up the CodeGen's coder thing that Angular is working on is like, obviously we have some solid tests in there, and I want to expand that to include more like not just full stack apps, but, uh, like more complex state management stuff that we were talking about today. So ask it to build like a more complicated advanced form, dynamic fields, validation, or maybe like a real-time status page, something like that, and see how it does with that. And that would be— that would really help us to figure out like not just only what should the system instructions look like, but how should we structure documentation so that it's easier to access for Claude or it's easier to read.

02:08:40 - Anthony Campolo

Like, yeah, I find that, you know, it's really a lot like something that's written well for a human is gonna work well. Like if you had a tutorial of like how to create a form with explaining each the complex form things you're going to do. That's really all you would need. Because if you only give it an API reference, it will be able to know how to use the code in terms of it won't write type errors necessarily, but there's things about just having the code written with an English language explanation attached to it that gives it all the context it needs.

02:09:14 - Dev Agrawal

Don't know what seeing the matrix is like. It's just a bunch of green numbers falling on a black screen.

02:09:20 - Anthony Campolo

Oh, I understand. Yeah, I didn't know the program. I do know— I did— I knew about Superman 2. Dev didn't know about Superman 2.

02:09:27 - Dev Agrawal

Yeah, I thought it was a Man of Steel reference.

02:09:29 - Anthony Campolo

Yeah, yeah, yeah.

02:09:31 - Dev Agrawal

Um, um, what were we talking about?

02:09:36 - Anthony Campolo

Just, uh, Code LLM and Solid and how to make sure it has the right context it needs. So yeah, so I find, um, I find having tutorials or guides are even better than just straight code examples because they, they understand English. So be able to just explain things to them in plain language that is paired with the code, because then it will know how to write the code by being able to look at the code, and it will understand the intention of the code because it can see what you wrote about it. So I would say first just think about other general guides or doc pages that don't yet exist, because you've done a good job and you document everything as in the frameworks. But beyond that, there's not much else in terms of like, if I wanted to build, you know, a checkout form that connects to an email or something like that, like I couldn't go to a guide that would like, Redwood was great about this. It had like 20 guides for like every random ass thing any developer would ever want to do on their project. Like, you wanna know how to do that? Here's your doc page step by step, you know?

02:10:36 - Dev Agrawal

Yeah. Yeah, definitely. 90% of getting better outputs from LLMs is just better docs. Um, I'm hoping to also use AI to like get better at writing the docs and keeping them up to date.

02:10:48 - Anthony Campolo

Um, I can help you with that. We should do another stream where we just kind of write one out together.

02:10:53 - Dev Agrawal

Yeah, for sure. Yeah. Uh, the, the other thing that I'm, uh, that I, I want to figure out how to fix is that I feel like Claude or any AI, it spends way too much time trying to just write code instead of just going and fetching the documentation, like I don't want to have to tell it, go read the documentation to figure this out. And I definitely don't want to like find the link myself and then give it, like, give it to them. If it's working—

02:11:19 - Anthony Campolo

I've built a workflow around finding the links myself because I found that I don't trust it to find the right docs, really. I want to go look at the site's docs for exactly what pages actually explain the thing you need. Then I built my own script so I can hand it. A row, a list of URLs, and it hits them all and writes them all. I'm extending the functionality of RepoMix in this respect. RepoMix does actually do this. You can have it read remote URLs and stuff. So, I am— the way I build my workflow basically ensures that there's almost nothing being left to the LLMs or the agents to figure out for themselves. So I spend a little more time figuring out what is the correct context, what is the correct instructions and what are the code files it needs? Because I've gotten really good at that and it very, very infrequently writes incorrect code now unless I told it to do too many things at once. That's the only time it fucks up now.

02:12:19 - Dev Agrawal

Yeah. Are you also doing like spec-driven development stuff at all?

02:12:22 - Anthony Campolo

Spec-driven development? So like where you write out a spec first and how like do each kind of step? No, I, I, I'm kind of doing that, I guess, with the migration. I create like a 12-step migration guide. I find with that, 'cause for me, the reason why my workflow works and why you don't get bogged down and why it doesn't slow you down the way AI tools do slow a lot of developers down, because you're asking it to do a single thing that it should be able to do in one response.

02:12:50 - Dev Agrawal

Mm-hmm.

02:12:51 - Anthony Campolo

And it should have everything it needs to do that correctly. So I am asking it to make a small change that I can validate immediately, and the entire process of that can take me like 60 seconds. But then if I chain 5 of those together, then I'm able to do something in 5 to 10 minutes that if I had it write a spec first and then it has to go through and check each one, like update a markdown file, like I just find it can get confused doing that. And having it write the spec, which a lot of people say you should do, is actually a terrible idea. It will not write a good fucking plan. I don't know what people are thinking when they're telling people to do this. It will create so many unnecessary code files that do so much extra shit that you don't need. It's a really bad idea actually. So you wanna be really, really granular in terms of what you're asking them to do. So one, you could validate it yourself, whether it works or not. And that comes from like just having like the right test files, you know?

02:13:43 - Dev Agrawal

Mm-hmm.

02:13:43 - Anthony Campolo

And then keeping it scoped enough so that it will be able to make the change in a correct way without messing up another part of the project. And at this point, like, I have such a fast iteration with this that, like, I feel like I just— anytime I'm, like, using my app and I'm, like, kind of testing it out, like, oh, this is the thing I want to fix. I feel like boom, boom, boom. It, like, takes me a couple minutes and all of a sudden it's fixed. And, like, it's— I don't need to worry about it anymore. So, I don't know. It's partly just because I have spent so much time iterating on this process over and over and over again, building my own custom scripts, my own custom CLIs, my own custom everything to make this work. So I wouldn't necessarily tell someone to do what I'm doing because they would, um, yeah, exactly. So I add a non-vibe part of my thing because that is why people say that the vibes can take you over. You don't want to be consumed by the vibes. Yes, you want to be vibing, but not too hard. You vibe too hard You're screwed. And that's why some people are very anti-AI safety people vibing super hard that you vibed all your customers' data into an S3 bucket. That's not good.

02:14:50 - Dev Agrawal

Yeah, exactly. Honestly, I mean, I feel like wipe coding existed even before AI because we used to paste errors into Stack Overflow and copy code from there without understanding what it is.

02:15:04 - Anthony Campolo

But yeah. That sounds awful.

02:15:07 - Dev Agrawal

It just has gotten worse. But yeah, I've definitely spent way too much time vibing and then ended up with a mess that I can't refactor. So I sympathize with that.

02:15:21 - Anthony Campolo

Yeah. And so other things with like the making sure Solid's good for LLMs, I think a lot of it comes down to having good custom instructions yourself for your own project. So, um, I can kind of show mine real quick. So I have mine kind of broken down into a— see, I think it's going to be—

02:15:43 - Dev Agrawal

yeah, this is something I can definitely use help on because I don't— my system instructions, usually I don't, I don't spend as much time on them as I should.

02:15:52 - Anthony Campolo

Yeah, so this I've been working on for like a year, adding to this. So, um, the The first, so I first tell it, I'm gonna ask you to either refactor my code, write a new feature, or fix a bug. So it knows it's gonna be one of those three things it's gonna be doing.

02:16:07 - Dev Agrawal

You're not sharing the screen.

02:16:08 - Anthony Campolo

Oh, I'm not sharing the screen, sorry. Yeah, that stage, there we go. Boom, okay, thanks. So this is the first part, ask you to refactor my code, write a new feature, or fix a bug. And then I kind of explain it, how it should actually be responding. And this is— this part's really important because this ensures it's not giving you different pieces of different parts of your files that's changed, because then you're going in, you're finding copy paste this little thing and putting into another. So that makes it really slow, and that can never compete with an agent. This is one of the biggest things that makes my thing work because it'll give me like 3 or 4 complete code files that I just copy paste, move, copy paste, move, copy paste, move. It takes you like 10 seconds. To do. So it's a slight manual step, but because I tell it it always has to write the entire code file, I'm always just copy-pasting directly into a couple code files.

02:17:02 - Dev Agrawal

Is that not more expensive on tokens if it has to write the entire file?

02:17:06 - Anthony Campolo

The speed I get by being able to always copy-paste the entire code file at once makes up for it, and I don't pay by the token because I'm on the, the max. And because I'm asking to make a small change, and the files have been designed in a way they're not too long, it ends up being worth it to have it write 90% of the tokens that have not changed because of the manual— it saves so much time with the manual step that all that ends up being worth it in the end, at least in my calculus of how I'm creating this workflow. I tell it only respond with the code files that have changes. So sometimes used to give me code files that hadn't changed at all. Like, that's obviously not useful. And then I tell it when it first responds— when it first responds— wait, sorry, wait, this— yeah, here we go. So then I tell it don't give me code in the first response. This is something Claude still does sometimes, doesn't actually listen to this instruction, but I was it's supposed to do is it will quickly— it will write me out a little plan that basically says, here's what I'm gonna do, here's the files that's gonna change, here's the files I need to create, here's the files that will be deleted. And it just writes me out a quick message like that. Because then if I see it does that and it says it needs to write 5 new files and edit 10 others, then like, that's too big. And then I kind of scope that down and— or I ask it in multiple responses to give me just a subset of that. Because if you ask it to change too many things at once, then it can take a long time and they can even exceed their Claude response length. That's pretty rare though. So you wanna avoid doing that.

02:18:51 - Dev Agrawal

Yeah, I run, I ran into that issue with the CodeGen's coder because it, the way it's built is that it wants the AI to respond with all the files that need to change in one shot, which obviously works with Gemini, which is the only thing that they tested it with because it's built in Google.

02:19:09 - Anthony Campolo

Sure, yeah.

02:19:09 - Dev Agrawal

But that does not work with Claude at all.

02:19:12 - Anthony Campolo

Yeah, unless you're only asking it to give you a couple files.

02:19:15 - Dev Agrawal

Yeah.

02:19:17 - Anthony Campolo

Word, I should talk to them next. That's something I've thought a lot about. Then I tell it kind of how I like it to create my logs. This will be specific to how anyone likes to do their logging, but you want to make sure you tell it that or else it just will kind of— every time you tell it to write logs, it will do something different. Then you have this huge mess of weird different logs that are all formatted differently.

02:19:38 - Dev Agrawal

Yeah, logging, it will— it'll— every single time I ask it to do logging, it will always create like an entire class, like a super complicated logger utility class, and then use it. Man, I just want some console logs spread.

02:19:52 - Anthony Campolo

Well, also, the— no, the real thing you want to do is you want to only do that once and do it in a way where it has the reusable logging functions like warning, error, success, stuff like that, that then it can pull from when it's writing new log functions.

02:20:06 - Dev Agrawal

Yes, yeah. Yeah.

02:20:08 - Anthony Campolo

That's what I have. Yeah. It has different, you know, color coding and stuff like that. Then I have the section where I basically give it all of the coding conventions around JavaScript, TypeScript, Node, and then CSS modules. This used to be Tailwind, but I've decided to try modules out for a bit and hasn't been too bad. It's more tokens, but I find that it actually is good for it to have the more level of control because it can do some really nice styling, honestly. So I tell things like— and this one's really important— to use ESM and things like async/await, just like whatever the modern versions are, because it's trained on so much code, it sometimes will just default to require if you don't tell it otherwise. So I make sure that it knows it should be writing code in like the most modern kind of Node.js. Style. I also tell it not to use things like nodemon or Jest or.env because all these are built into Node now and you really don't need those dependencies anymore. And then I tell it to avoid just like spaghetti code things, like don't have a whole bunch of if-then-else statements and don't like create tons of like deeply nested loops and things. Like stick to like, you know, functional kind of good practice type stuff.

02:21:22 - Dev Agrawal

Yes, multi-tier functions.

02:21:24 - Anthony Campolo

Yeah, uh-huh. And then stuff on TypeScript, which this could probably be improved, but I tell it to not use things like ts-node and have a build step, but to stick with tsx. This will no longer be needed with Node really soon and probably isn't necessarily needed now, and with Bun it's definitely not needed, but that is, I find, makes it a lot— works a lot better for TypeScript. Then things like using.ts files, not.js. I tell it to infer types whenever possible. When types must be declared, keep them minimal and just inline instead of named. I'm not sure if I necessarily want that rule to still be here. I think I might want to change that one. Then I used to have it say never include return types, but now I say always include return types. Also not sure about that one.

02:22:13 - Dev Agrawal

Yeah. Claude, in my experience, is way too happy with any types.

02:22:18 - Anthony Campolo

Well, you could, yeah. So you could also do that. Say never use any. Yeah.

02:22:22 - Dev Agrawal

Yeah.

02:22:22 - Anthony Campolo

Yeah. I definitely never use classes. Only use functions.

02:22:27 - Dev Agrawal

Yeah. I also, I always need to add that use bun for package management. I, npm, just npm install is way too slow almost every single time.

02:22:37 - Anthony Campolo

So are you a fully Bun user now?

02:22:41 - Dev Agrawal

Uh, not, uh, I mean, yes, I use Bun basically whenever I can, and I use it to like run one-off scripts. Um, currently I'm using Bun to run an MCP server. Uh, yeah, basically use Bun whenever I can, basically.

02:22:58 - Anthony Campolo

Yeah, I'm really close to that, about to make the switch, I think.

02:23:02 - Dev Agrawal

Yeah, I, I only have to resort to pnpm if I'm working with an existing repository where someone else use pnpm. Sure. Mostly like open source stuff. So, the web codegen scorer uses pnpm. Solid's codebase uses pnpm. So, those things I still have to deal with.

02:23:19 - Anthony Campolo

Mm-hmm. Yeah. So, this is my whole custom instruction file. So, it's not a ton of stuff, but it's enough and it's specific enough that ensures it gives highly consistent code. Mm-hmm. It writes exactly the way I want. And it then also, because now I have a file, I have a project that was built with all these conventions, it is referencing those as well. It's able to correlate these instructions with code in the project. It just creates a very holistic unified experience where it knows exactly what to do in almost all situations. A lot of this is specific to me and how I want my thing, but I would probably tell most people you should break it down in a similar way. Tell it how you want your response to be, how you want things like logging to be, and then coding conventions for whatever your language or framework or, you know, whatever it is that you're doing.

02:24:14 - Dev Agrawal

Yeah, um, I think the, um, going back to the earlier point about like docs, I think the one thing that I, um, I always feel the need to add in these is that, uh, basically like ask it to be eager with fetching the doc, like finding documentation and, uh, like maybe have some specific instructions that I— that, uh, it can write that are, that are like specific to the project. But basically, like, don't, don't spend more than 2 or 3 iterations if you're struggling with issues. Like, just go and fetch the docs. I, I've had it like way too many times, it struggles with something because it doesn't have the latest knowledge, and then I have to ask it go like fetch documentation.

02:25:00 - Anthony Campolo

Yeah, and that's why I skipped this step entirely by always finding the docs myself. Yeah, yeah, that makes sense though. That's a good instruction to add if you want to be doing that.

02:25:11 - Dev Agrawal

Yeah, yeah, there's maybe like better ways to make like, uh, make it easier for it to access docs on its own so like you don't have to do the upfront work.

02:25:24 - Anthony Campolo

Yeah, that's basically what Repo Mix allows you to do, or the script files I wrote where I'm able to just take a bunch of URLs that just can compress it all into a single just text thing that you, that you then feed it. Cuz web search, just things get weird when it's doing web search cuz it might be scraping it. So it needs to like figure out what to do with the HTML and there's just like a lot of issues. I find where I'm working, usually I can just find the.md files on the GitHub repo itself and I just want, if they don't have a copy to markdown button on their docs already, Yeah, so, um, that I find works pretty well. I try to just avoid making it do any sort of web search because it just adds another level of stuff that takes longer and has more— yeah, messing up.

02:26:08 - Dev Agrawal

Yeah, this is one of the things I really like about OpenCode. Their fetch tool, it, it always responds with markdown, so it's never going to give and provide the raw HTML response. It's going to—

02:26:20 - Anthony Campolo

Firecrawl does too. I like Firecrawl. It's a tool for scraping, you know, getting these kind of things into an LLM.

02:26:27 - Dev Agrawal

Yeah, Firecrawl is like one level above that where it's not only going to run in like a headless browser, but it's going to— Firecrawl will actually use the entire response it gets out of it and then use an LLM to parse it into the response that you want. OpenCode just uses a tool for that. It's some like simple conversion tool. HTML to Markdown, uh, but it also strips away a lot of the unnecessary metadata that, um, so it just makes it much easier to read for LLMs. Like, you always get Markdown instead of HTML. Um, but not every tool can do that.

02:27:05 - Anthony Campolo

Totally. Yeah, we were going to talk about OpenCode a little bit. They, um, yeah, I don't know, the thing you told me is, is actually public, so I'm not going to mention it unless You do. Yeah, it's awesome. Yeah, okay, cool. Glad I didn't say it then. Yeah, no, but OpenCode, we talked about this a long time ago on a show. We did an MCP stream, I remember. We looked at it and I was like, this is gonna be freaking sick. So are you like using it in your like kind of day-to-day?

02:27:32 - Dev Agrawal

Pretty much, yeah. Mm-hmm. Yeah, I'm playing around with more different features like different agent modes. For with like custom instructions. I haven't played, uh, I haven't done like any slash commands yet, but, uh, there's, there's like a lot of features around not just like agent instructions, but it has plugins, um, which could be used for some cool stuff. Um, the, the thing that I am more, uh, excited about right now is like subagents and multi-agent collaboration where like an agent can give tasks to different background agents and then somehow collect information from them, orchestrate them together to do something. That's wild. It's, yeah, it's super early in this. Like right now there's a lot of thoughts around don't build multi-agent systems or only use multi-agent systems for these specific use cases. This is more of like a, I guess, a very experimental thing that people have very different opinions and different approaches to.

02:28:36 - Anthony Campolo

You know, I think it's gonna be interesting. Do you know Levels.io? Yeah. He's been talking about recently how he just like spins up like a VPS and just puts cloud code on and just has it write code 24/7. And this is where a lot of this is going. And it's gonna be wild. And I, you know, It's, it's really quite close to being able to just kind of constantly run in the background and just like serve up PRs for you. Mm-hmm. And you just give it like a to-do list of every feature idea you've ever had and it will just like write 'em all. Like it's pretty, pretty wild, you know?

02:29:15 - Dev Agrawal

Yeah. I may or may not be working on something along those lines.

02:29:19 - Anthony Campolo

I'm hoping it's, oh, on.ah, that's a good, good URL.

02:29:23 - Dev Agrawal

Yeah, it's, uh, I'm hoping it gets to a nice demoable state pretty soon.

02:29:28 - Anthony Campolo

What's an SDLC?

02:29:30 - Dev Agrawal

Software development lifecycle.

02:29:33 - Anthony Campolo

What does that mean?

02:29:35 - Dev Agrawal

It's just a fancy term for basically the entire workflow of starting a project, building something, testing, deploying, monitoring.

02:29:44 - Anthony Campolo

You should just share your screen and show this page.

02:29:48 - Dev Agrawal

The page?

02:29:49 - Anthony Campolo

Yeah, yeah.

02:29:50 - Dev Agrawal

Yeah, let me.

02:29:51 - Anthony Campolo

You just shared it in the chat. I could pull it up. I feel like it's yours.

02:29:54 - Dev Agrawal

I mean, there's not much happening. So it's not like me building it. It's our CEO who's building it. Oh, okay.

02:30:02 - Anthony Campolo

Gotcha.

02:30:02 - Dev Agrawal

We are planning on using it with our consulting clients once it's done. Yeah, so it's like another take on spec-driven where when you write your specs, the specs can— there's code generators that can take your specs and just give you fully kind of like well-tested and like it's not gonna be AI's love. Like these generators, they're not AI. They're like regular code generators that can look at your specs and then compile them basically into like fully functioning application logic. And then AI can fill in the gaps.

02:30:46 - Anthony Campolo

So it's kind of also combines like the scaffolding stuff you'd get from like a Rails, you know?

02:30:51 - Dev Agrawal

Exactly, yeah. So it, it does all the scaffolding, it can write tests, and then once it has all the tests written, then the AI can just implement the rest. Um, and, uh, basically I, I call it like wipe coding, uh, gone deterministic, or bring— bringing determinism into wipe coding.

02:31:12 - Anthony Campolo

Nice. That sounds really cool.

02:31:16 - Dev Agrawal

Yeah, we are hoping to use this with some clients and I'm very excited about this project.

02:31:23 - Anthony Campolo

Just make sure you capitalize the H in GitHub on your GitHub button. Right now it's all lowercase, it looks weird.

02:31:29 - Dev Agrawal

Yeah.

02:31:33 - Anthony Campolo

Auto Engineer. Very cool. Supports Claude, OpenAI, Gemini, and Grok. I think I might add Grok back into AutoShow. Used to be in there and then I took it out because it wasn't that great, but then Grok 3 came out and it was better and I don't know. I feel like there's a certain type of person who's like, they just, because of how they feel about X, they think Grok is going to give them a less biased kind of response. I don't think that's actually true at all. I think it. Gives almost extremely similar opinions to other LLMs. And it's the only one that I haven't paid for the really expensive plan and tried the actual best model. So I don't know how Hebi works at all, but I might drop the, the money just for one month to try. It's the most expensive, like $300, I think. So yeah, better be better for me to pay an extra $100 a month for it.

02:32:29 - Dev Agrawal

Yeah. Uh, I'm super excited about the new voice models. I think we voice agents are like, like I, when I think about like how I want to use AI in my day-to-day, not just like, uh, not just for writing code, but for like, uh, personal activity stuff.

02:32:44 - Anthony Campolo

Yeah. A lot of people really enjoy that. Like, that's why every AI ever in any sci-fi movie is always, they're talking to it. They're never typing to it, you know?

02:32:52 - Dev Agrawal

Mm-hmm. Yeah, exactly.

02:32:54 - Anthony Campolo

Yeah.

02:32:55 - Dev Agrawal

I mean, I, I mean, a few days ago, like maybe 3 or 4 days ago, I had my earphones on, I was in my kitchen doing my dishes, and as I'm doing my dishes, I'm talking to ChatGPT and I'm doing like this entire research on like agent memory systems. And it like, that was the closest I've ever felt to like, like Tony Stark and Jarvis.

02:33:18 - Anthony Campolo

Totally. Yeah. That was very cool. Yeah. And that's, you know, I remember when the term vibe coding first came around. That's what some people meant is that you were like voice, you were telling it what to do with your voice. And that's less important to the term nowadays.

02:33:34 - Dev Agrawal

Yeah.

02:33:34 - Anthony Campolo

But I got very deep into text-to-speech stuff with AutoShow CLI that I'm about to now bring in. I'm gonna just add a button to where if you wanna turn your sh— whatever your show notes are, just turn that to an audio file that's read to you. That's gonna be probably the very next feature I add. And I'm, I love it. I'm at the point now where I'm creating entire audiobooks for myself. So I, I read weird stuff. So, you know, I'm gonna find like old PDF for that. Like, you know, I can just grab the whole thing and throw it into a thing and then I have like an 8-hour audiobook of like brand new content I couldn't listen to anywhere else.

02:34:07 - Dev Agrawal

This is basically what people are using NotebookLM for.

02:34:11 - Anthony Campolo

Totally. Yeah. But NotebookLM won't just read the thing verbatim and create audio for it though. I think it's— summarizes it first, right?

02:34:17 - Dev Agrawal

Yeah, it, yeah, it'll provide an overview or like a, like a discussion commentary around that. Uh, you can for like, you can have different versions. So there's like a super concise summary, uh, deep, uh, deep dive, and then now there's a debate mode as well. So it'll have two, two of them like talking back and forth. Um, yeah, I definitely need this. Uh, like I definitely want to turn like all the newsletters and, uh, blog posts that I read into audiobooks for me.

02:34:46 - Anthony Campolo

That's actually— so have I told you about AutoShow Daily?

02:34:50 - Dev Agrawal

Uh, a little bit, I think.

02:34:52 - Anthony Campolo

Yeah. So this is an— because I've just been taking a long time to finish all the stuff on the site I haven't done yet, but I want to create a newsletter of, um, it uses AutoShow to summarize all the podcasts of the week for web and AI stuff. And then you could also then use the text-to-speech stuff to then turn that back into like a condensed podcast that would just summarize all the podcasts of of the week for you.

02:35:14 - Dev Agrawal

Yeah. Yeah. I, I'm gonna need that.

02:35:16 - Anthony Campolo

Good. You can be the first customer then.

02:35:18 - Dev Agrawal

Yeah. Is it only going to use like podcasts and videos or is it only also going to like read blog posts and—

02:35:26 - Anthony Campolo

It could if I, if I wanted to. That was honestly, man, that was what I was doing when I was working at Edgeo for a job. You remember the JavaScript Jam newsletter?

02:35:33 - Dev Agrawal

Yeah.

02:35:33 - Anthony Campolo

That was one of the first things I used AI for a lot. Cause I, I, I realized it could write me pretty good, you know, summaries of some of these articles and I would, I would edit them to make sure they didn't have the AI slop kind of voice to 'em. But that saved me a ton of time and I would, I felt like I put out pretty good stuff with that. So yeah, I mean the, there's been a disconnect here because the thing was originally built specifically to take audio and video files and then transcribe them and then do stuff with it. But the AutoShow CLI, has the ability now to work with PDFs and just general text stuff. So all that's kind of converging into something where it doesn't matter what the medium is. It'll be able to grab your audio video, be able to grab your text files. It'll be able to kind of put that all together in ways where you just mix and match stuff.

02:36:23 - Dev Agrawal

Cool.

02:36:25 - Anthony Campolo

Yeah.

02:36:26 - Dev Agrawal

Audio input very unreliable in GPT in cloud. Yeah, audio input to me is still very unreliable on ChatGPT. I'm talking about their voice mode, which is different from the audio input.

02:36:39 - Anthony Campolo

What's the difference?

02:36:40 - Dev Agrawal

The voice mode is more like being on a call. So when you're talking—

02:36:45 - Anthony Campolo

I don't know what audio input is. I know what voice mode is.

02:36:49 - Dev Agrawal

I mean, audio input is just like it uses a microphone and it's speech to text basically, but it's using their speech to text models instead of like whatever you might have on your device or browser.

02:37:01 - Anthony Campolo

Interesting.

02:37:02 - Dev Agrawal

Um, yeah, voice mode is what I was talking about, and that's where I think a lot of really cool stuff can actually happen. Because like, especially now, like, voice mode can actually properly call tools and MCP tools. Um, yeah, but the unfortunate thing is that GPT is not as good as Claude at calling tools. So I want like ChatGPT's voice mode, but with Claude's ability to call tools. And, uh, for a while I was really excited about, um, Alexa Plus. So I, I'm, I've been using Alexa for like 2 or 3, 2 or 3 years. And, uh, they, they have been recently like beta testing a product called Alexa Plus, which is Alexa built on top of Claude. So it's an LLM. And honestly, that feels like the ultimate Home Assistant where, or like AI assistant, because it has like all of Claude's powerful tool calling and language features with all the integrations that Alexa already has, which is like, uh, probably one of the biggest in like AI ecosystem, but it just doesn't work well yet.

02:38:18 - Anthony Campolo

Totally. I'm also kind of amazed how hard all these Home Assistant things have dropped the ball. Like, including like, you know, Siri, not exactly the same thing, but it's like, it should be so easy to just have all these things just hook into it all. I'm like, none of them do it yet. It's been like 2 years. Like, what's taking them so long?

02:38:36 - Dev Agrawal

Microsoft was the first one that's doing it with Copilot. So I've seen, I've been seeing a bunch of ads.

02:38:41 - Anthony Campolo

What's the, what's the home device though?

02:38:43 - Dev Agrawal

Um, like any app really, like any phone. Like you can install the Copilot app and, um, it works basically like Siri but it's using another LLM.

02:38:54 - Anthony Campolo

So what's the difference between just using the ChatGPT app?

02:38:59 - Dev Agrawal

Um, just like, um, basically like voice mode, I guess, and, uh, cam— camera video feed. Like you can show video feeds directly. Um, yeah, not much. It, it's just like a more Siri-like feel on top of the same thing.

02:39:19 - Anthony Campolo

I mean, Copilot is the OG. Copilot was the first thing that people were using LLMs for. Devs were using it. They didn't even know what a freaking LLM was at the time.

02:39:28 - Dev Agrawal

Yep. Most devs still don't know what LLMs are. I still don't know what LLMs are truly.

02:39:35 - Anthony Campolo

Like, I mean, I think if you were to say that someone was an LLM, they would at least be able to say ChatGPT, you know? Mm-hmm.

02:39:41 - Dev Agrawal

Yeah.

02:39:42 - Anthony Campolo

Yes. They know what it means in that respect, but you're right. I mean, no one knows what an LLM is. People who make LLMs don't know what LLMs is.

02:39:48 - Dev Agrawal

Mm-hmm. VoiceMod will just stop listening in the middle of me speaking. I haven't, I have not had that experience yet.

02:39:54 - Anthony Campolo

Have you tried being mean to it?

02:39:57 - Dev Agrawal

I have not. Why would I be mean to our AI overlords?

02:40:00 - Anthony Campolo

I'm so, I'm so mean to our AI. Don't get me though. First one put in the wood chipper when they take over. Yeah, I mean, they'll have a whole long list of every conversation I've ever had with them. They're like, you have sentenced to 900 counts of battery against the machines.

02:40:16 - Dev Agrawal

Exactly. Yeah, I, I already know there's going to be like some AI taking over somewhere, so I'm like, why even bother being mean?

02:40:24 - Anthony Campolo

I'm betting on it being ruthless enough that I'd be like, hey, you saw a higher tree of the other AI, you need to keep me around. Cool, man. We're at 2 hours and 40 minutes in. We definitely crushed the record for longest AJC in the web dev episode yet.

02:40:44 - Dev Agrawal

Yeah, we almost went like 50% of Ryan's stream.

02:40:47 - Anthony Campolo

Yeah, totally. Um, do you have any final call to actions or things to talk about?

02:40:54 - Dev Agrawal

Um, Solid 2.0 coming out at some point next year, probably.

02:40:59 - Anthony Campolo

Uh, yeah, as that's developing, I will, I will definitely help like beta test stuff because now that I'm like going all in on Solid, I want to find ways to actually kind of get more involved in the community and help with stuff. I think that would be a good opportunity for me to add some value there.

02:41:13 - Dev Agrawal

Sure. Yeah. Uh, uh, the, if you are in the Discord, the next channel on the Discord is where all the discussions around 2.0 happen. Show up there. Solid Start is getting better and better every day now that we have, uh, uh, like, uh, people on a payroll that are working on it, not just like random community contributors. So there's 3 fellows and then there's a new core team member working on Solid Start. Um, it's gonna be— it's gonna get only better and better. I am go— I'm very soon going to find a way to introduce like real-time features into it. I don't want SvelteKit to beat us to it at all.

02:41:52 - Anthony Campolo

Do you think AutoShow needs any real-time features? I'm assuming no.

02:42:00 - Dev Agrawal

I mean, so it's like— there's like a— let me put it this way. Every app can benefit from real-time features.

02:42:11 - Anthony Campolo

So how would AutoShow benefit is my question.

02:42:14 - Dev Agrawal

So I was actually gonna ask when you showed it earlier, Like when you kick off like a, an AutoShow process, whatever, like processing in the background, do you have like live status updates on the page or do you have to refresh the page to see what's happening?

02:42:29 - Anthony Campolo

So no, you don't need to refresh. What it does is the sidebar, it has all 5 steps and they're tracking what's happening and there's loading spinners every time something's running in the background. So as soon as something finishes, the loading spinner kicks off and then the next loading spinner starts. And so that's how you have some visual feedback in terms of the sidebar where it will show you which things are processing in the background. And then if you get to the final step that's not done, it will actually read you out which step it's on as it goes through them.

02:42:58 - Dev Agrawal

Right. But how does it know which step is done? Like how does the server tell the client like, hey, this step is done now? Does the client have to—

02:43:05 - Anthony Campolo

it basically, I think it's just polling and just waiting for a response essentially, cuz the first thing it does is it has to download the YouTube video and then save it to an R2 bucket and then give you that R2 bucket back. So then you know you're done and then you give it to the transcription thing, then it's running and when you get the transcription back, you know the transcription is done.

02:43:22 - Dev Agrawal

Okay.

02:43:23 - Anthony Campolo

And then with LLM, once you get the LLM back, you know it's done. Yeah.

02:43:26 - Dev Agrawal

Right. So each step is triggered separately from the client, right?

02:43:30 - Anthony Campolo

Yes. Uh-huh. Yeah.

02:43:31 - Dev Agrawal

Right. So, so in a scenario where, like, if you move all that orchestration to the server, Like you, you only make one request to the server and then the server—

02:43:40 - Anthony Campolo

Wait, sorry. It is doing it all on the server, I think. Cause there's a bunch of background functions that are making fetch calls. Honestly, I don't really know. I'm gonna be totally honest with you. I do not know the answer to this question.

02:43:54 - Dev Agrawal

Yeah. So it's, it's like, yeah, the, the work happening, the work is definitely happening on the server.

02:44:00 - Anthony Campolo

Mm-hmm.

02:44:00 - Dev Agrawal

But then there's a, there's an orchestration layer on top of it. That what I'm hearing is currently lives on the client, like, uh, go to do the transcription when the— yes, it finishes.

02:44:10 - Anthony Campolo

It does, yes, because it's a bunch of functions that are being imported into the client components.

02:44:16 - Dev Agrawal

Yes. So which means like if I, if I start transcription and if I close the tab, what happens is the, the—

02:44:23 - Anthony Campolo

so the way it manages that is that it initially, it with the very first step, once it's done with that, it creates a new show note for you. So if you ever want to come back to it, you could do that and step back into the flow. So there is a way to do that, and that has to do with basically how it persists after each step.

02:44:43 - Dev Agrawal

Okay, so but it's not going to keep running the entire thing while the app is closed, right? I have to have the app open for it to continue.

02:44:51 - Anthony Campolo

Um, I mean, once you get to the last step, you could close it and it'll go all the way to the end, right?

02:44:56 - Dev Agrawal

Yeah, but yeah, not in the middle.

02:44:59 - Anthony Campolo

Well, in the middle, it's just because if you stop it, then you can't give it the next instructions to go to the next step to get to the end. So it will just stop at whatever the last step you gave it instructions on, right?

02:45:09 - Dev Agrawal

Yeah, so, so that's what I meant about the orchestration logic living on the client. If this entire thing is something you want to do in the background so that I, like, I can close the app, I can close the app and it still does everything. To completion regardless of where I left off, then that would be a thing that first of all you would need to move the orchestration logic to server.

02:45:33 - Anthony Campolo

But I'm saying I think it does do that because I'm saying that the only reason why it wouldn't do that is because like it can't run the LLM step until you told it what LLM you want. Like once you've gone through the form and you've selected everything, you can close the tab and it will finish.

02:45:47 - Dev Agrawal

Okay, okay. So okay, then maybe I need to look at the code at some point to understand what's going on.

02:45:54 - Anthony Campolo

Because basically what I have it do is I have it just go through each step and it kind of knows that once one step is done, if it has the information it needs to go to the next step, then it will go to the next step. So you could blaze through the whole form, click everything really fast, and even if you are still downloading the media at step 1, it has everything it needs for steps 2, 3, and 4. And so as it processes each of them will get to the next. It's all saved in the state, you know? So it's able to then figure out what it needs to do next. So once you've given it all those instructions, if you close the tab, it will still run everything in the background and it already has all the state to make all the decisions it needs to get to the last step where it then writes it to the, the R2 bucket at the end.

02:46:37 - Dev Agrawal

Right. Okay. Yeah. Okay.

02:46:39 - Anthony Campolo

Yeah.

02:46:39 - Dev Agrawal

Then, uh, yeah, I'll, I'll definitely need, uh, I'll definitely want to probably look at the code of this. But this is, uh, in my head, this is something that could benefit from more real-time capabilities where once you have all the information, you give it to the server and the server just kicks it off. And then maybe I could have like, uh, the app also open on my phone where I can see the updates if the, like, especially if this is something that takes a much longer time, right? Like 5 minutes, 10 minutes, an hour. If it's something that's going to take that long, then I would want to—

02:47:12 - Anthony Campolo

it shouldn't take longer than 5 to 10 minutes, but Yeah, that, that can be a decent amount of time. Yeah.

02:47:16 - Dev Agrawal

Yeah.

02:47:16 - Anthony Campolo

And I want to also get to the point where once you get to the last step, instead of waiting for it to finish and then redirecting you, it basically just starts you back at the beginning and says, this is running. I'll let you know it is done. You can start a whole new one while that is happening. Mm-hmm.

02:47:30 - Dev Agrawal

Yeah. That makes sense.

02:47:32 - Anthony Campolo

Yeah. Yeah. Cool, man. Yeah. Once I get the Solid Start API migrated over, we'll have a whole bunch more to, to talk about and look at.

02:47:41 - Anthony Campolo

Cool.

02:47:41 - Dev Agrawal

Cool.

02:47:41 - Dev Agrawal

I'm excited.

02:47:42 - Anthony Campolo

I really appreciate you doing this. Like, this is so much super, super useful targeted advice and really fun to stream. I'm definitely going to create some clips from this, so watch out for those. And then had a bunch of people in the chat today, so thanks everyone. J Lark, he's probably the only one still around, but thanks for watching. This is one of my probably most watched streams ever. We got— says we have 1,200 people watching right now, which is obviously not a correct number, but it's Certainly more than the 30 that it usually says.

02:48:10 - Dev Agrawal

Yeah, I think it was probably Ryan's retweet or something.

02:48:14 - Anthony Campolo

Word. Yeah, thanks Ryan for stepping in. All right, bye everyone. We'll catch you next time.

On this pageJump to section