skip to content
Podcast cover art for Tape.sh with Danny Choudhury
Podcast

Tape.sh with Danny Choudhury

Danny Choudhury discusses building Tape with RedwoodJS, his journey into programming, and the nuances of pre-rendering versus SSR and SSG.

Open .md

Episode Description

Danny Choudhury discusses building Tape with RedwoodJS, his journey into programming, and the nuances of pre-rendering versus SSR and SSG.

Episode Summary

In this episode of FSJam, Danny Choudhury, a London-based developer and Redwood core team member, joins to talk about his background in engineering, his path into JavaScript through Angular 1, and how he came to build his screen-sharing product Tape on top of RedwoodJS. Danny explains how Redwood's cells feature and its extensibility—tested by writing custom GitHub auth in just a few days—convinced him the framework was the right fit. He walks through Tape's two forms: a CLI tool that simplifies mobile screen recording into a single command and a macOS app designed around minimal friction, contrasting its philosophy with more feature-rich competitors like Loom. The conversation shifts to technical choices, including why Danny initially picked Ant Design for speed and later began migrating to Tailwind for better bundle sizes and flexibility. The hosts and Danny then spend significant time unpacking the terminology around SSR, SSG, and pre-rendering, with Danny clarifying that Redwood's approach renders pages at build time in a Node environment and then hydrates them client-side, distinguishing it from purely static generation tools like Gatsby. They discuss why pre-rendering is opt-in in Redwood, the challenges of universal module compatibility, perceived performance as a design principle, and how tightly coupled infrastructure like Vercel enables features such as incremental static regeneration that framework-agnostic approaches can't easily replicate.

Chapters

00:00:00 - Introduction and Danny's Background

The episode opens with a lighthearted exchange about the overloaded SSG acronym before the hosts introduce Danny Choudhury, a London-based JavaScript developer with roughly a decade of experience across web and mobile. Danny describes his current work on Tape, his consulting in the React Native space, and his previous software development management roles.

Danny shares how he got into programming through a university course blending electronic and computer engineering, recalling a pivotal afternoon where a PhD student walked him through the basics of conditionals and loops. He describes graduating in 2012 just as Angular 1 was taking off, which drew him into JavaScript and the web ecosystem, and how his appreciation for simplicity has grown through years of working in teams on large, fragile codebases.

00:07:58 - Discovering RedwoodJS and Building Tape

Danny recounts how he and a co-founder set out in early 2020 to build creative products, starting with a travel app that quickly lost relevance when the pandemic hit. The process of sharing screenshots and animations during remote collaboration sparked the idea for Tape, a tool focused on making visual communication effortless. When evaluating frameworks, Redwood's cells feature immediately appealed to Danny because it eliminated the repetitive boilerplate of writing data-fetching loaders.

To test whether Redwood would create too much lock-in, Danny used a litmus test: writing custom GitHub authentication in just a few days on a framework that didn't yet officially support auth. The ease of that exercise convinced him Redwood was simple and extensible enough to commit to. He also highlights the welcoming community around the framework, from early interactions with David Price and Peter to eventually demoing Tape for Tom Preston-Werner, and how that sense of belonging reinforced his decision.

00:18:51 - Tape's Product Philosophy and the CLI

The conversation turns to what Tape actually does and how it fits alongside competitors like Loom and QuickTime. Danny explains Tape's CLI, which is fully open source and wraps existing mobile development tools like ADB and xcrun into simple one-line commands. Rather than inventing new capabilities, the CLI reduces friction so developers can record a screen, generate a GIF, and get a shareable link copied to their clipboard almost instantly.

Danny draws an analogy to how Slack didn't replace email's functionality but lowered communication barriers. The macOS app follows the same principle—two clicks or a keyboard shortcut to capture and share, with no complex configuration. The hosts discuss how this aligns with a keyboard-first, minimal-interaction philosophy, and Danny emphasizes that Tape intentionally avoids becoming a powerful, feature-heavy tool in favor of doing one thing extremely well.

00:25:14 - UI Choices: Ant Design, Tailwind, and Solo Founder Realities

Danny explains his choice of Ant Design as Tape's initial UI library, driven by the pragmatic need for a component-rich toolkit when building alone. Features like copy-to-clipboard as a simple prop saved significant development time, but large bundle sizes eventually became a problem. He began incrementally introducing Tailwind CSS, finding its syntax more intuitive and its utility-class approach better suited to someone who identifies more with the data side of front-end development than the design side.

The discussion broadens into the realities of being a solo technical founder after Danny's co-founder departed. Chris draws a parallel to his own experience, describing the mental mapping required to hold an entire application in your head and the importance of moving fast even at the cost of breaking things. Danny shares how he manages motivation by alternating between frustrating tasks and energizing ones, such as contributing fixes to Redwood when a stubborn UI bug is draining his drive.

00:32:46 - Pre-Rendering, SSR, and SSG Explained

The hosts ask Danny to clarify the confusing terminology landscape around SSR, SSG, and pre-rendering. Danny traces the history from the original meaning of SSR—rendering React in a Node environment via Express—through Next.js introducing SSG as build-time server rendering and incremental static regeneration as a runtime refresh mechanism. He distinguishes purely static tools like Gatsby and Jekyll, which produce unchanging HTML, from Redwood's pre-rendering approach, which generates HTML at build time that then hydrates into a dynamic React application on the client side.

The conversation explores why this matters for user experience beyond SEO, drawing on Apple's early iPhone technique of displaying a skeleton PNG while apps loaded. Danny references a 140-millisecond interaction threshold from Netflix engineering as a guiding principle, while Anthony highlights the concept of perceived performance—managing user psychology rather than raw speed. They also discuss how Next.js achieves incremental regeneration through tight coupling with Vercel's infrastructure, a capability that doesn't easily transfer to platforms like Netlify or Cloudflare.

00:49:01 - Opt-In Pre-Rendering and Closing Thoughts

Chris asks why Redwood doesn't simply pre-render every page by default, as Gatsby does. Danny explains that Redwood and Gatsby serve different purposes—Redwood targets dynamic applications while Gatsby excels at content sites—and that opt-in pre-rendering avoids forcing developers to deal with browser-only library compatibility issues on pages where pre-rendering adds no value. He recommends pre-rendering landing and about pages while leaving dashboard-style pages to render only their skeleton frames.

Danny floats the idea that React Server Components might eventually be the better solution for pre-rendering dynamic data like pricing plans, though nothing is officially decided. The episode wraps with the hosts thanking Danny for his contributions to both the Redwood framework and its community, and Danny offers an FSJam discount code for Tape. Anthony closes by appreciating Danny's storytelling approach to technical topics and the depth of the conversation.

Transcript

00:00:00 - Christopher Burns

I was pretty adamant that it was SSG, not SSR.

00:00:06 - Anthony Campolo

That is not an acronym we are allowed to use if we are going to use SSG for server side generation. Something has gone terribly wrong in the world because that acronym is already being used.

00:00:27 - Christopher Burns

Welcome back to FSJam. This week we have a special guest, a fellow Brit and application maker, part of the Redwood Core team, Danny Choudhury. Welcome to the podcast. So let's get to it.

00:00:45 - Anthony Campolo

You say hello.

00:00:46 - Danny Choudhury

Oh, cool. Yeah, hello.

00:00:49 - Anthony Campolo

As Chris said, you are on the core Redwood team. So we've gotten to know each other a little bit through working on that. You've got this really cool application you're building with Redwood called Tape, and you're working on some really cool stuff with pre-rendering. I know you've done work, and I think you've helped out with auth and things like that, at least in terms of giving feedback and helping work all that out.

There's a lot of things I'd really like to get into. But before we get into any of that, let's first get who you are and what you do. If there's anything else you want to say about your company that I haven't already mentioned, and then we'll get into your background and all that stuff.

00:01:25 - Danny Choudhury

Cool. So first, thank you both for having me. You should always say that on a podcast when you go on.

A bit about me. I'm here in London in the UK, and I've been doing JavaScript development across both mobile and web for quite a while now. Maybe nine or ten years. I need to double-check. Right now, I've been working on my own product, tape.sh. But before that I went into more software roles, the SDM (Software Development Manager) roles in my previous two roles, and before that I did a bit of web and mobile development as well.

00:02:04 - Anthony Campolo

Would SDM be kind of like a PM here?

00:02:06 - Danny Choudhury

No. So SDM or SDMs, I think they're Amazon terms, to be honest. This is technical management. Normally SDMs are in charge of one team, one software development team. Senior SDMs can have multiple teams that they're managing. That's the sort of role that I had.

I'm also consulting at the moment as well, and I have been for the past few years, mostly in the React Native space. So my role varies quite a lot. Sometimes it's more technical, as in hands-on writing code. Other times, as you spend time working somewhere, you move up eventually. I've always ended up in these software management roles, but with a strong focus on the technical aspects, if that makes sense.

00:02:52 - Christopher Burns

If you love trains like Joe Biden, Danny worked at Eurostar, and if you didn't know what Eurostar is, it's the now controversial connection between Britain and France. But most people use it to just go to Disneyland Paris.

00:03:10 - Danny Choudhury

Actually, Eurostar holds a special place for me because that's where I first used React. It kind of opened my eyes to what was possible with React. It's also where I first did server-side rendering with React. Before React, it was very, very difficult to achieve that sort of thing. A special time for my career. I think you already mentioned it. It is controversial.

In fact, when I worked at Eurostar, I was surrounded by all of these cosmopolitan European and London types, and I count myself as one of them. And that's when Brexit happened. Wow. That was an experience.

00:03:50 - Christopher Burns

Wow. Without going too technical, I would say if you've never read about the story of how the Eurotunnel was made, it's a great example of engineering between France and Britain. What they actually did was dig a tunnel from both sides and then met with, I think, millimeter precision around 2005. So way before computers did everything.

00:04:21 - Anthony Campolo

Before we could measure things.

00:04:23 - Christopher Burns

Exactly.

00:04:23 - Danny Choudhury

Nice. I didn't know that.

00:04:25 - Christopher Burns

Yeah. Worth a documentary. I think there's tons of them on YouTube.

00:04:29 - Anthony Campolo

So I'm curious. Danny, how did you first get into programming? Did you have more of a formal CS background, or does it sound like you started more in the web area? I'm curious how you found your way into that and what your first programming languages were or stuff like that.

00:04:43 - Danny Choudhury

This stuff is a little bit fuzzy for me because it feels like a long time ago now. But I got into programming, properly into programming, at university. My background is halfway electronic engineering and computer engineering, but as I went through the course, I realized I wasn't very good at the electronic and the electrical side. I really started liking the programming side and the computing side, and that's how I got into it.

Of course, I started learning C++ and the more hardcore languages, getting really into the standard data structures, Big-O optimization, that sort of thing. But one of the things I particularly remember is my first ever coding test at university. It was to write a recursive function calculating factorials, and I remember getting a C in it. That was a hallmark of how I got into programming. I thought it wasn't going to be for me. I thought it was too difficult, but I had this amazing PhD student who was helping us out in the labs and guiding us through it.

[00:05:56] He spent an afternoon, a couple of hours, walking me through how if statements work, how for loops work, and really getting into the basics of it. The next day I found that I could code. It was literally that pivotal moment. I needed someone to get me through that initial hump, and after that, it all came naturally. You get more geeky about it, and you feel more confident about your abilities.

That's my background in computing. And how I got into the web space was, as you've heard, my computing education was very formal. It was very hardcore computing, hardcore languages. Just as I graduated in 2012, Angular 1 was getting big, and that's how I got into the JavaScript space. I found that it was so cool that you could do real programming, if you want, in JavaScript. Very interesting concepts such as MVC. All of that was new to me.

00:06:56 - Anthony Campolo

It had dependency injection and that kind of stuff. I could see how, at the time, you would have seen that as more quote-unquote real programming than the types of JavaScript things that were available before.

00:07:06 - Danny Choudhury

Exactly. And of course, since then, my view of things has evolved a little bit. I'm a big fan of simplicity, so anything that you can take one look at and understand is of higher value to me.

00:07:21 - Anthony Campolo

Yeah. And it just felt that way.

00:07:22 - Danny Choudhury

I haven't yet, no.

00:07:24 - Anthony Campolo

Based on just that statement alone, you would probably like Svelte.

00:07:27 - Danny Choudhury

Yeah. I mean, I think it happens as you mature a little bit, but also when you've been in teams and you've built huge projects where things are kind of at the brink of crumbling and you have to bring it back. That's when you start to really appreciate simplicity. That's why that's my number one principle. You know, the KISS principle. Keep it simple, stupid, I think, but there's a nicer way of saying it. I don't know which one it is. I just say KISS.

00:07:58 - Anthony Campolo

Keep it simple, silly. Yeah, we're in a camp, so I'm good at these think-of-something-nice-off-the-top-of-my-head type situations. And then how did you first hear about Redwood and what made you think it was interesting and worth investing your time and eventually your company's technology in it?

00:08:16 - Danny Choudhury

So let me give you a little bit of background on how I got started with Tape at the beginning of 2020, I think. I'd left my job at this fintech, where I was managing multiple web and mobile teams, and the exposure there was fantastic. It was building a white-label mobile banking app, and then also web tools and SDKs for our clients to interact with the APIs for the banking system.

As time went on, I realized I wanted to do something more creative. I had an amazing team. The exposure was fantastic, but I started realizing I wanted to build something of my own, try to own the process from the beginning to the end. So that's how I started with a good friend of mine to take a few months out, start building stuff we thought was cool, and see if we can make a product out of it. Our first product that we built was a travel app. That was just as the pandemic hit. Quickly we realized, hey, we're going to lose motivation. There's no point in doing this.

[00:09:20] But in the process of doing that, we realized that as we're building the mobile app, we're sharing a lot of screenshots. We're sharing a lot of animations, just trying to communicate with each other remotely to get the idea across better. And that's where the idea of Tape came from.

The idea is that whenever you're working with someone, and it's not limited to mobile development anymore, but when you're collaborating, it's just easier to get the point across when you show someone what you mean rather than have to write long emails or long Slack messages to tell them what you mean.

At this point, we started looking at how to build this. We figured out the client side part of it, but we didn't know how we want to host it. I'd built with Next before, I'd built with Express before on the server side, but we came across Redwood somehow. It seemed like a really interesting tool, but what sold me initially to try it was cells.

[00:10:23] One of my pet peeves is I really, really dislike writing loaders. I think it's so painful to do something so simple. I really dislike having those if statements to say if fetch is still in progress, or if the data has come back and it's null, that sort of thing. I really dislike writing it because you have to write it so many times over and over again.

00:10:48 - Anthony Campolo

Yeah, just real quick. If there are any people who are kind of hopping in as newer listeners, a cell is just how Redwood does data fetching in a declarative way. So it's a way to have your different states that your data could be in, either empty, loading, error, or success. So you don't have to write those conditionals to decide how to do error handling or any of that kind of stuff. So you basically saw cells and you're like, this is a really nice convention for something I've been doing myself forever. And these guys look like they pretty much nailed it.

00:11:18 - Danny Choudhury

Yeah, it wasn't that cells do something that I can't do, but it was trying to remove the barriers so what you're building is more fun. You want to focus on building your product rather than focusing on things that are very important, but not necessarily contributing to the development of your product, if that makes sense.

I find examples would be, and Redwood does a lot of this really well, the Babel configurations, the webpack configurations, and all of that. So it felt like a natural fit to just try it out. At this point, I hadn't decided to use it. This was very early on. I think the first time I used Redwood was 0.5, maybe, so just before the auth packages became official. I think what I decided to do, because one of my fears about choosing a new framework is how much lock-in there is. So once you write your application or part of your application in it and you decide you don't want to use the framework, how quickly can you get out of it?

[00:12:23] The plan was, let's spend a few days writing a custom auth for this framework, which doesn't support it yet. The idea was, if I can write the custom auth so quickly in a few days, that probably means the framework is simple enough and extendable enough that we were not going to hit lock-in, because auth is one of the most complicated topics that you can do, and it's also one of the topics that generate the most lock-in into any framework.

Once I managed to do the custom GitHub implementation, that was it. I was sold. I was like, look, there's all of these reasons you want to use it. It feels a little bit like the nice parts of Rails. It takes away the sort of boilerplate code that I don't really want to deal with. I want to build this product quickly and I want to enjoy the process of doing it. I was like, yeah, this is what we're doing. That was my first intro to Redwood.

00:13:18 - Anthony Campolo

Yeah. That's cool. What you said about auth is really interesting. And I like this idea of having some sort of litmus test of how extensible a framework can be or how coupled a framework is. For me, this litmus test was doing the whole Fauna thing. And I've talked about this on the podcast before, figuring out how to take Prisma out and then rewrite your services with Fauna, getting a completely different database, but also ripping out your ORM entirely. To me, that was a really strong litmus test that this is something that can be decomposed in really interesting ways. And auth is something that we've also talked about a lot with Brandon, and we're going to get on and do a real deep dive into auth.

So that's cool. And what auth provider were you using when you did that? Or were you just kind of handling the JWT stuff yourself?

00:14:08 - Danny Choudhury

It was all custom. So it was GitHub, but not GitHub in the way that's officially supported by Redwood. At the time, I thought I had good reasoning behind it, and largely it's because I didn't want to pay for an OTT service.

00:14:22 - Anthony Campolo

And when you say you use GitHub, you mean you use GitHub as a third party login?

00:14:26 - Danny Choudhury

Yes. So it was GitHub to authenticate you as a person. And then once you get the user back, everything else is handled using custom code. The JWT generation and that sort of thing is custom.

And of course there's that old blog post on the Redwood community. If you're curious how it used to work in the 0.6/0.12 days, of course, it's evolved a little bit now. So I think that was the point. I decided, yeah, this is definitely something we're going to use, but there were a few other points where it really confirmed that this is the right way to go.

First of all was the interaction with Peter and David Price, the wonderful people. And at the time, I didn't really know them that well. I'd never met them, but just the way you could interact with them. With David, it was more the higher-level concepts. With Peter, you could just go straight into the depths of some topic, such as auth, and you would get a very reasonable, simple answer back.

[00:15:28] I was like, wow, this is really nice to be able to have that conversation with people there. And then, of course, you start to speak with people like Chris and Toby as well. We debug some stuff together. It kind of draws you in. And then eventually, when you have a chance to speak to Tom.

I remember the first meeting we had. There was a small, I guess, core community meetup, which it wasn't called that at the time. And David put me on the spot to present Tape. No preparation, nothing. And when you first meet Tom, before you get to know him, it feels a little bit daunting, right? Because he's so successful. But also, I feel like he's had a huge influence in the way I think about software with things like Semver, of course, GitHub. But I feel like, how I mentioned KISS and keeping it always simple, make it easy to understand, I feel like Tom always embodies that idea.

Readability and getting your head around the concept seems to be very high on his list, so it was daunting. And that's the demo, and it was wonderful to get that feedback from Tom and from the core community there. And you realize that, hey, maybe this is a decent product, but also that I'd like to be more part of this community because they seem to be receptive to my use of this very early and young framework, and I can see that I can help drive the direction a little bit as a user of Redwood.

00:17:00 - Christopher Burns

I remember the first time I joined one of these meetups, I was like, oh my gosh, this guy has the Christopher Nolan Batmobile in his background. Like, this guy is legit. Of course, he is just a person and he's really great at what he does. But we're all in this world where we put people on pedestals by what they've created previously, and that's very much how it goes in developer world.

It's like, I was lead developer at X company that got sold, great, or founder. A lot of people have major dev careers and you never know because they go into a big company and they just work their way up. I felt with joining Redwood and getting to know everyone that looks are deceiving. Just because it's got a big name behind it doesn't mean that it's going to succeed. It is all about the community and the technology.

00:18:03 - Danny Choudhury

Yeah, I agree. I think the way the community has grown and you see the interaction as well, not just the core community. I mean users who are popping in to try something and you see the messages on Discord. You see someone who's trying something new and they're contributing back. It's really wonderful to be part of building this together with people who you've never met.

I think that's such an amazing thing that we're able to do this because as engineers, we like building things, but the bit that we forget is you get the best out of anything you're building when you work with other people and different perspectives and different backgrounds that kind of help you form your ideas better. The community, I think, is wonderful. It's a big part of Redwood.

00:18:51 - Anthony Campolo

All right, let's get into Tape. We've already said that Tape is something that you can use for screen recording. So when I think of screen recording, I know that Loom is a popular choice. He even mentioned that on his recent episode. I know Adam Wathan, I think, just uses QuickTime to record his screen.

So there are ways you can do it yourself, which is kind of standard programs on a computer. And then there's other kind of more hipper options as well. So how do you see Tape in terms of where it fits into this whole landscape of screen capture tools?

00:19:23 - Danny Choudhury

Let me answer your question in two parts. Let me first talk about the CLI and the mobile side, because that's where Tape got started. And then I'll address the Loom and that part of Tape.

On the CLI, what Tape is doing, by the way, the CLI is completely open source if you wanted to go look at how it works. It's not doing anything that you can't do yourself with other tools because underneath it's using mobile development tools such as ADB and xcrun. These are tools that are on your machine if you do mobile development. It's not that Tape does something that you can't do in any other way, it's just that it does it in a much more simple way.

00:20:06 - Anthony Campolo

And just real quick. When you say for mobile development, are we talking iOS or Android? Both? What does that exactly mean?

00:20:12 - Danny Choudhury

Yeah, both. Whether you're doing Android on macOS, Linux, or Windows, ADB is always there. That's one of the base tools for Android dev. And for iOS, xcrun, which is, I guess, Xcode command line tools. I don't know exactly what it stands for.

00:20:30 - Anthony Campolo

Yeah, Xcode kind of is how everything runs through. If you're doing any sort of mobile iOS, I think you can't really do it without Xcode in some respects.

00:20:37 - Danny Choudhury

Exactly. So the flow normally would be, if you didn't have Tape on the mobile side, it would be, oh, let's record the screen with this very complicated ADB command or xcrun command. Then you get a video file. Then you copy that video file to a folder you're working on. Then you drag and drop into Slack or, I don't know, S3 you want to upload somewhere, and then you can send someone a link.

It's not that you can't do it without Tape. It's the idea that with Tape, all you have to do is say, hey, I want a GIF of this screen, tape gif. That's it. It will pick the first emulator. If you have multiple emulators, it lets you choose. And then it records whatever is happening on your screen. You press spacebar. It will then upload, give you a link, and even copy the link into your clipboard.

So for the CLI, I found it super useful just sharing across Slack with clients to say, hey, I built this. What do you think? Or when I'm doing a PR into the repo to say, this is this new feature, this is what it looks like, or this is what the flow looks like. And you just do tape gif format md, and that gives you a markdown formatted link already in your clipboard. You just go on the pull request and you paste it.

The idea with it is that it makes it much, much easier. The analogy I think of, and this applies to both versions of Tape, when Slack first came in, or that breed of enterprise messaging apps came in, it didn't do anything email couldn't do, or anything Hangouts couldn't do.

00:22:15 - Anthony Campolo

Can I get an emoji reaction to an email, though?

00:22:19 - Danny Choudhury

You can. You can. The point is that it's not doing something that you can't do. It's just reducing the barriers to communication. And I see Tape in both its forms, whether it's the macOS app or the CLI, to do exactly the same thing. When you're building something and you're trying to explain it to someone, you don't want to think about, oh, I'm going to record it with this tool, that tool, whatever. You just want two clicks or, even better, zero clicks. Just a command shortcut. And you get a link back and you just paste it.

So the idea is that you don't need to think about it as much anymore. And that's the core concept behind it.

In the case of the macOS app, you're going to have to remind me of the question.

00:23:09 - Anthony Campolo

Tape and how it relates to other tools as well. So you're explaining kind of like how the CLI works and how that differentiates it.

00:23:16 - Danny Choudhury

Cool. So in the case of the macOS app, the experience is similar, right? You can just use QuickTime to record your screen or use the amazing open source one called Cap to record whichever window you want. And there are various tools like Loom and CleanShot and all of these pretty good products that do what you might want to do.

But I think the case is the same in all of these products: they require a lot more active involvement. You need to click around a little bit more to get what you want. These products, in various degrees, are and can be far more powerful than Tape. But the idea with Tape macOS is I don't want it to be powerful. I want it to be very, very simple. I want it to do one thing and one thing really well.

So the idea is when, I don't know, maybe if you work with spreadsheets and you want to explain how you're doing a certain calculation on one part of the spreadsheet, you just trigger it with two clicks or one shortcut, record what you want to show with your webcam if you want, and you get a link back and you paste it to your colleague.

00:24:29 - Anthony Campolo

People who are into Vim would probably really like it then? People don't want to ever leave their keyboard.

00:24:33 - Danny Choudhury

I used to have this joke. So at my last job, I had a junior dev. She was quite young, but we used to have a joke because she was getting into all of this tooling, and I was showing her all this cool stuff that you could use. And we used to have a joke that, you know, clicking around is for noobs.

So as much as you can, if you use keyboards and you use your shortcuts, I always love the experience better when the shortcuts are done tastefully. So that's the idea, to make the experience smoother and simpler and for it to never get in your way. So clip, send. That's the idea.

00:25:14 - Christopher Burns

Let's talk about some of the technologies Tape is built with, because you've used slightly different projects to what most Redwood apps have used in terms of UI.

00:25:24 - Danny Choudhury

Let's start with Ant Design. When you're choosing a UI library, there's various factors into play. Maybe you want design aesthetics, of course. They are a huge part of it. But for me the biggest thing was, look, I don't have a huge team building this. It's just me, and in the beginning, my partner as well.

We needed something that could get the job done quickly. We needed something with a large amount of functionality baked into the library. Things like copy-to-clipboard text with Ant Design's React library, it's like a prop. That's it. It's decisions like that where you say, if you don't have to build it, don't build it. That is the idea behind it.

So while I stand by that decision, what didn't work out so well with Ant Design was, first of all, the bundle sizes. The bundle sizes are huge with Ant Design. I'm sure there's a way you can do a lot of optimization, but I just couldn't find any sort of good documentation that would point me in the right direction.

[00:26:38] Eventually I started using Tailwind as well. You get there, but you learn from your mistakes along the way.

00:26:45 - Anthony Campolo

So you're using both Ant Design and Tailwind at the same time. Why is that necessary?

00:26:50 - Danny Choudhury

It's literally a case of I don't have enough time to change everything, so I'm doing things incrementally. I realize that the bundle sizes are still quite large, but I don't think the effect is that detrimental. I don't think it's gotten to a point where you have to take it out immediately.

00:27:11 - Anthony Campolo

So can you purge Ant Design, or is that why you're moving to Tailwind? Because you can purge CSS that way.

00:27:16 - Danny Choudhury

There's multiple reasons as well why I started using Tailwind. First of all, I know a lot of my background is in front end, but funnily enough, I'm not very good with UI. I really, really struggle with placing things on the DOM. You know that.

00:27:36 - Anthony Campolo

It's almost like it's not easy to do or something.

00:27:40 - Danny Choudhury

It doesn't come naturally to me. I prefer more the data side of building the front-end applications. But I think Tailwind kind of changed it a lot for me. I'm totally okay with React Native styling. I'm totally okay with how you do flexbox styling. I've even done native development, both on Android and Swift on iOS. I found iOS a little bit more difficult at the time because SwiftUI wasn't there. But I find that some of the newer ways of doing things come more naturally to me. I'm closer to the data side than the design side, if that makes sense.

00:28:22 - Anthony Campolo

I actually describe this as the front of the front end and the back of the front end. So the front of the front end is like the HTML, CSS stuff. And then the back of the front end is things like Redux and state management and how you're actually doing your data fetching and all that kind of stuff. That's all in this larger bundle of what is considered front end now. So yeah, I totally get what you mean there.

00:28:43 - Danny Choudhury

Exactly. And Tailwind kind of changed it all for me. I wouldn't say I'm a whiz, not like Robert from the core team as well. I love his UI library, by the way. If you haven't checked it out, I use that for Tape as well.

The new home page is a wonderful piece of work and sped me up so much, because one of the things you realize as a solo founder... What happened a few months after I first started Tape was my friend and co-founder had to go. He had some other priorities to go look after professionally. So we decided, look, I can keep doing this. It doesn't affect anything; you do what you have to. It became just me building Tape.

At that point, you realize that you have an infinite list of things to always do, because not only am I doing all of the designs, all of the marketing, it's the social media, the code for the front end, the code for the back end, debugging issues that are coming back. It's just a huge, huge list of things that is never-ending. I'm sure you know, Chris.

[00:29:48] So I will take all the help that I can get. That's why it felt like there was a parallel between why I chose Ant in the first place and why I decided to move to Tailwind. For one, the syntax is wonderful and I find it intuitive. But also the prebuilt components that are there don't lock me in because it's just HTML or JSX that I can customize myself. Yeah, it made sense to rebuild the front page in this new UI framework.

00:30:30 - Christopher Burns

My thoughts on these are very similar. As the main founder of the company, as the technical founder, I almost feel like Professor X sometimes. There's a bug and 95% of the time I can go, it's in this file, probably that block. You have to map the whole application in your brain.

We recently took on our first employee, and our first few days were like a scatter map of just trying to explain how everything works in your brain. And something that I saw on Twitter today that resonated with me really well, and this is paraphrasing because obviously sometimes I can't remember these things. The tweet was, it's better to go fast and break than to go slow and right. You become a generalist and you really need to find out very fast what you're really good at and what you're really bad at. And whatever you're really bad at, you just need to hold on so you can hire someone else to do that.

00:31:46 - Danny Choudhury

I agree, because one of the things as a solo founder or as the sole technical person on your project, building a larger product, whatever it may be, is you have to manage your own motivation. If you keep coming across things that you don't enjoy and you find it is a chore to do, eventually it drains away your drive and your motivation.

I learned a lot about my personal motivation through this process to see, look, I know what I enjoy, I know what will give me energy. So even if I'm having an off day today, let's leave that UI thing I'm really struggling with because it doesn't work at the middle screen resolution. Let's leave it for now. Let me do some Redwood. Let me contribute a little fix to Redwood. Get my spirits up again, enjoy the process. And tomorrow I'm going to fix this annoying little UI bug that I just cannot fix today.

00:32:46 - Christopher Burns

One of the things we really want to talk about is pre-rendering. We've both implemented React Snap, an all-in-one library to do it, but you've now gone a step further and are working on the official way for Redwood to do pre-rendering. What's the proper term? Is it SSG, SSR, or is it just pre-rendering? Because I think it's SSG.

00:33:17 - Anthony Campolo

And what do those letters mean when you say SSG?

00:33:21 - Christopher Burns

SSG is server side generation, SSR is server side rendering, and pre-render is a subset of SSG. To me, SSG is done in the past. SSR is done now. I don't know, they're so confusing.

00:33:42 - Anthony Campolo

What I would like to know is when, just within the last week or two, I heard that pre-rendering is just static generation. So kind of what Chris is trying to say over here. So is pre-rendering the same as static generation, or is there a difference there?

00:33:56 - Danny Choudhury

There is a difference, first of all. But I don't want to get into terminology battles, essentially, because you see it one way or the other.

00:34:06 - Anthony Campolo

We need to at least define how we're using it. So when we say these words, people understand what our words mean, because that's what words are for.

00:34:13 - Danny Choudhury

Exactly. I'm going to describe my understanding of it. SSR, before the amazing stuff that Next.js did with SSG and stuff, and all of these terms that Next.js introduced, but originally when there was really one way to do it with React, right? You run it through an Express server and then you get some HTML back. This was my first experience with SSR or server-side rendering with React. And what that refers to doesn't necessarily mean whether it happens at runtime or build time. What that means is you use the Node.js environment to render React code, and that's what SSR originally meant.

So if you look at old documentation and that sort of thing, that's what they'll refer to. And if you look at outdated libraries, you'll see SSR now supported. And what that means is I'm doing an extra check for window before I try to do something with the library. As Next introduced all of these new terms and SSR became an overloaded term, SSR now means I'm going to render it at runtime.

[00:35:27] SSG now means I'm going to run server rendering at build time, but it's actually doing the same thing, just at a different time. And of course, there are some differences. When you say static, I feel like there's more confusion that can get generated here. So when you say static generation, I think of tools like Gatsby or Jekyll or, I don't know, Hugo. These are tools. Whatever you write it in, it's not even important. At the end of it, it generates static HTML files. And once you deploy it, that's it. There's nothing dynamic about it. It's static generation for that reason.

That's how I view static. And the way I view pre-rendering in Redwood, the official term still to be decided, by the way, but the way I view it is much closer to the original SSR, which is to say, we're going to take a component and we are going to render it in a Node.js environment. Currently with Redwood, we're going to try and do this at build time.

[00:36:39] So at build time, it renders your landing page so that you get all the benefits of SEO for whatever reason. Or maybe you want to create the skeleton of your page before your full application loads up. But the difference from static here is that once the JavaScript loads up, it will hydrate your page. So it starts with a static HTML file, and then as soon as your React application or your Redwood application has loaded, it will become dynamic.

00:37:12 - Anthony Campolo

Okay, that makes a ton of sense. So basically the static generation part doesn't involve hydration. How you define these terms, when you're talking about some static generation, once you generate the static, it is static forever. Whereas what we're talking about here is building as much as we can, and then also being able to hydrate it at a certain point.

00:37:30 - Christopher Burns

So to give what it actually does without SSR or pre-rendering, as we will call it, your HTML file is basically one div that literally just says hashtag Redwood or React. Then when SSR runs, it generates the DOM tree and then injects it into that HTML file with the status of hydrated. I think, what's the original status? I think it's hydrated. I can't remember, but it injects HTML into the React tag, then saves the file.

Then when the user loads that page, it instantly shows the HTML structure and the CSS before JavaScript has initialized and the client gets rehydrated. To me, this is going to solve one of the biggest problems with Redwood, the gray screen of death. Redwood is a full application and that requires loading of JavaScript and APIs. And before all of that is done, you want to show something to your user because they will then perceive the website to be faster, even if it takes the same amount of time.

[00:38:56] If it first loads a skeleton and then the client rehydrates, your customers then understand more what it's doing instead of wondering what is going on, if that makes sense.

00:39:09 - Danny Choudhury

That's exactly right. Beyond the SEO benefits, if there are any, I'm not an expert on this topic, but beyond the SEO benefits, you see the experience benefit as well because you can start to do some fun stuff like defer the loading of the JavaScript file altogether, maybe even defer loading of CSS files if you're brave. That's something I'm in the process of looking at the moment.

The idea behind it is you make it feel as fast as possible, while also making sure bots can parse it. And this sort of idea comes from, I think it was Apple's Human Interface Guidelines from many years ago. When they first launched that and developers first started building it, there was a section there that said the original iPhone wasn't very fast, right? So when you load the app, it took a while for it to load up. So what it would do is have a PNG or something.

[00:40:13] I don't know specifically, but have a PNG that is the skeleton of the app so that when you, as the user, touch that icon, it immediately shows you that skeleton and it feels so much faster as soon as you do that.

00:40:28 - Anthony Campolo

I find it so interesting how we're not necessarily managing the performance of our applications here, as we're managing the psychology of our users, because I always hear this term perceived performance in these conversations. We're kind of saying that we're not really making it as fast as it needs to be. We're making it as fast as our users want it to be because they're super impatient.

00:40:50 - Danny Choudhury

I wouldn't say it's about impatience. It's literally how we as users would perceive it. I remember from years ago, I was doing some smart TV development, so a video streaming development for smart TVs similar to Netflix before Netflix was huge. I had a chance to work with the PS4 before it came out. It was all locked down. I had a development unit that I was working on for this product. Absolutely amazing.

But one of the things that was a challenge there was that you say, look, these devices, they vary quite a lot, not the PlayStations, but the smart TVs. They are very limited in their performance. What you need to do is hide away all of the details that people don't see. Leave as much memory as you can in your application. As long as you can do something under 140 milliseconds, any interaction under 140 milliseconds, then the user will never know the difference. And there is this amazing article from Netflix that describes this in detail.

[00:42:00] That was the takeaway for me, that 140 milliseconds. I always use it as a principle. You can optimize all of these things, but is it worth doing the optimization?

00:42:10 - Christopher Burns

One of the things that I think is really interesting when it comes to these optimizations, I can't go into it too in-depth because I only know so much. But when you do server-side generation, also generating the default cache of the store management, and I think you can do this with some Next.js libraries like Pullstate, where you say when you're going to pull the SSG, also set up a default cache. And I think that's how ISR works. I'm pretty sure it is.

00:42:46 - Anthony Campolo

You flip from one SSG to another SSG halfway through that sentence. I hope you just realized that.

00:42:50 - Christopher Burns

Yeah, Next.js is very crazy because they released this step above SSG, where when your user goes to the page, it also refreshes it in the background to have the latest SSG. So it's not only at build time. It's also at user time.

00:43:13 - Danny Choudhury

Let me dig into this a little bit because I've used Next as well. Part of Tape, the share page, is built with Next.js. SSG static stuff actually also hydrates, by the way. So that's something you should let me first explain.

That is, ISR means whenever you go onto a page, in the background it will run that render process again so that when Anthony visits that page, even though I got a stale page and my client refreshed to the latest state, next time when Anthony visits, he's going to see the latest one because it's rendered and cached it. This is also known as, I believe, stale-while-revalidate. Like I said, there's so many terms describing what it is. An easy way to think about it is to always think whether it's happening at build time or is it happening at runtime. And that way it just kind of clarifies it, I think.

00:44:14 - Christopher Burns

What is a framework doing as in the background? Because obviously Next has their own set of black magic. Is that a lambda function that reruns it and then stores locally? Is that something Redwood could achieve in the future?

00:44:35 - Danny Choudhury

That is what Next is doing. But I think Next has this. Remember Next is very mature compared to Redwood. It's had many, many years of improvement. I'm not the sort of person that has to select one framework. I'm a huge fan of Redwood, but when I need something from Next, I will happily use Next because it is a fantastic framework as well.

The advantage Next has here is that they have tightly coupled their infrastructure because it's built by Vercel with the framework. And clearly they're investing a lot into the future of Next as well. Being tied with Vercel, that's where they are able to do the ISR stuff.

00:45:19 - Anthony Campolo

Okay. Because this is something that came up with Brandon. This is exactly what my impression was, is that the integration between Next and Vercel is what allows some of these things. But Brandon said that Next can run with all of its features on any other platform, and I didn't think that was true when he said that.

00:45:36 - Danny Choudhury

I don't think you will get ISR the same way.

00:45:39 - Christopher Burns

On Netlify, for example.

00:45:41 - Danny Choudhury

Yeah, you definitely won't get it on Netlify, that I'm confident you're not going to get on Netlify.

00:45:47 - Christopher Burns

That's what I thought. I was like, are they adding some hidden lambda functions to my Netlify or my custom server?

00:45:55 - Danny Choudhury

I find that part of Next very opaque because I find it very difficult to understand where they're doing this stuff. I guess this is the advantage of combining your infrastructure with a framework because you're able to do these amazing things.

Going back to whether Redwood will be doing this in the future, the answer is a firm maybe because the way I am building pre-render at the moment, the choices I've made, and not just me, because the choices I will discuss with the core team. I will always try and balance out different views to get there, but the general idea is let's focus on what we can do right now with the infrastructure that is there.

00:46:38 - Anthony Campolo

And that infrastructure being which infrastructure? It's like, whose infrastructure are we using here?

00:46:43 - Danny Choudhury

Normal infrastructure that is not specific to any provider.

00:46:47 - Anthony Campolo

To me, that doesn't exist. There's no such thing as normal infrastructure that doesn't exist to one provider.

00:46:51 - Danny Choudhury

I think Netlify's approach is pretty normal. If you run it in a Docker container, that's pretty normal.

00:46:59 - Anthony Campolo

So you're saying Docker?

00:47:00 - Danny Choudhury

No, I'm just saying that you don't want the framework at this point in time to have prior knowledge of what special capabilities there might be at the infrastructure layer. Because sure, Netlify does functions, right? So does Vercel. So there's so many other people, but what they're doing there is they're providing an easy way of using it.

00:47:23 - Anthony Campolo

But those are specific functions. Those functions won't run on Cloudflare.

00:47:26 - Danny Choudhury

They would with Cloudflare Workers, right?

00:47:29 - Anthony Campolo

I don't think so. I think that lambda. So the problem is that when you're writing for functions on Netlify or Vercel, you're writing for lambda functions, but lambda functions and Cloudflare functions, as far as I know, don't necessarily cross over or interop. So this is why I say I don't think there is an agnostic infrastructure that exists.

00:47:46 - Danny Choudhury

Without looking into Cloudflare Workers too much, in my head they're pretty much the same thing. There are different semantics of how it works. Cloudflare Workers are generally also used for more closer to Netlify edge handlers, right? Yeah, but that's probably more because Cloudflare is at the front of your stack. It's not so much. I think they haven't optimized their workflow to say, hey, you know what? You don't need all of this other infrastructure or all of these services you're paying for. Just deploy everything on Cloudflare. I think they're getting there.

00:48:23 - Anthony Campolo

Yeah. This is just something that's on my mind a lot, and I think about it a lot. So that's why I kind of wanted to dig into that.

00:48:27 - Danny Choudhury

You should dig into this because I haven't used Cloudflare Workers. So this is how I see it. I don't know how different in practice they are.

00:48:38 - Anthony Campolo

In general, I think building towards anything that's going to be AWS or layer on AWS is always going to be the right choice. I'm thinking of kind of like farther out into the future. You want to be able to interact with Cloudflare and Fastly's cloud, but this is kind of like more of a bigger term thing. I think today the smart move is always, always, always going to be bet on AWS. I just think that their clouds are moving in interesting directions to keep an eye on.

00:49:00 - Danny Choudhury

Yeah, yeah.

00:49:01 - Christopher Burns

Why shouldn't I just pre-render every page?

00:49:05 - Danny Choudhury

You could.

00:49:06 - Christopher Burns

Exactly.

00:49:07 - Danny Choudhury

If you really want to, you could do it. Why shouldn't you do it? It's not that you shouldn't do it. It's the same idea. Is there any benefit in doing it? I think that's probably the better question to ask.

For example, let me give you an example of a page that may not have a lot of value pre-rendering. Say you have a dashboard page where it loads all of your personal data. This is all of the tasks specific to Chris. It requires login. It requires knowledge of who you are as a user. Maybe your roles, various things that are contextual in your browser. If you pre-rendered this entire page, there's not a lot of benefit because that data will change. You don't know what data is going to be in its place. But instead, if you're smart about it and you say, I'm only going to render the skeleton of this page, as in the frame of this page, and wherever there are cells or dynamic data, I'm going to put in loaders.

[00:50:13] So when you load up the HTML, you see that frame and it feels like, oh, it's already there. It's just loading. That, to me, is the smarter strategy.

00:50:22 - Christopher Burns

The reason why I asked that was because when you would pick something like Gatsby, it's automatic, every page pre-rendered. But with Redwood on your PR, it's opt-in. So why?

00:50:35 - Danny Choudhury

So there is a second reason. So first of all, I think Gatsby and Redwood serve different purposes, in my opinion. I wouldn't choose Gatsby for building something like Tape, and likewise, I wouldn't necessarily choose Redwood to build a news site. That's my personal feeling around this, because I feel like the two different frameworks are optimized for doing that, and they're very, very good at it. So you choose the right tool for the job.

The reason pre-rendering is opt-in with Redwood is, first of all, it's still an alpha feature. It's still in that rough PR. We don't know how it's going to go. It might introduce more complexity, but as a user of Next.js, if you remember, I don't know if you've come across this. One of the annoying things in Next.js is you have to use universal modules. For example, if you have a hook that you're detecting the breakpoint or the intersection observer on your page, and that library hasn't been written to be server-side compatible, it breaks. Next handily provides a way around this, but I feel like that's not an optimal experience, is it?

[00:51:55] It feels like I'm going to have to jump through all of these hoops for maybe something I don't even want. That's the reasoning. I think there may be some good reasons why the Next.js guys have enabled it, probably because they see their target is slightly different to Redwood as well.

At least the way I'm seeing Redwood at the moment is that it's beautifully simple. It does so many things for you that you don't want to deal with, without doing things that you want to handle yourself. So the reason it's opt-in is because, for example, you're most likely going to pre-render your landing page. You're going to pre-render your about page. But let's say I've written a new page where I've added all of these libraries that are browser-only, and as soon as I try to pre-render it, it breaks. Now, as a user, it's just nicer to say, hey, I'm just going to not pre-render this until I find a way around it. So I think that opt-in approach has certain advantages that way.

00:53:00 - Christopher Burns

Will cells be pre-rendered? For example, I have a cell that's just pulling my terms and conditions. Right? Just some standard HTML, doesn't need auth. Would that cell get pre-rendered or does everything that needs to load data have to be hydrated?

00:53:21 - Danny Choudhury

So in the current version it's not going to pre-render anything inside cells. So I can think of a good use case. Maybe pricing is a good use case where you might use a cell to render on your landing page, right, to show you different plans that you have available. For example, this is something that we should probably tackle, but I'm trying to keep this out of the scope for this initial version of pre-render.

There's an interesting, this isn't something officially endorsed or anything. One of the things that's been percolating in my head is that instead of going through the hoops of trying to pre-render the pricing stuff that comes from your database, would we be better off aiming to use React Server Components for this sort of thing? Because it's probably better suited for this. It seems like the right tool for the job. So just an idea. It's something that's been running around in my head, but how we're going to eventually end up doing it, we'll see once we get there.

00:54:27 - Christopher Burns

Wow. Thank you for your time. We really appreciate having you on this podcast. One of the things Danny and I agreed upon is that Danny is looking for more users of Tape, and we've agreed upon a discount code for listeners of the podcast. I can't remember how much we agreed on, 20%, 12%, and the code was FSJam, all lowercase. I believe it was all uppercase. All uppercase.

Danny is looking for more users of Tape because it's built with Redwood, and we all love the community. Danny is giving a discount to the FSJam podcast. That's 20%, and the code is FSJam in all capitals.

00:55:25 - Danny Choudhury

Yep. Yeah, that is cool.

00:55:27 - Anthony Campolo

Thanks a lot, Danny. Thanks for being here. Thanks for all the work you've done on the Redwood team, not only helping out with building the framework, but also always being just a really positive, laid-back presence in the community. I always enjoy how, when you're telling technical topics, it always sounds like you're telling a story about when you're hanging out with your friends. So I really appreciate the presence you bring to the community. Thank you for that.

00:55:52 - Danny Choudhury

Cool. Thank you both for having me and very kind words. Anthony, I appreciate it. Yeah. Keep up the great work on the podcast as well. Look forward to when this comes out and your future episodes.

00:56:34 - Anthony Campolo

Thank you for going super over time also because that was a lot of really good topics we wanted to get to. This is going to be a long episode, but it's really, really valuable stuff, like all the stuff I get asked about constantly and I have no clue what to say because I don't understand any of it.

On this pageJump to section