skip to content
Podcast cover art for UserVitals with Tharshan Muthulingam
Podcast

UserVitals with Tharshan Muthulingam

Tharshan discusses building User Vitals, a feedback collection SaaS tool, with RedwoodJS, covering subdomains, iframes, Prisma, and deployment choices.

Open .md

Episode Description

Tharshan discusses building User Vitals, a feedback collection SaaS tool, with RedwoodJS, covering subdomains, iframes, Prisma, and deployment choices.

Episode Summary

In this episode, Tharshan joins Anthony Campolo and Christopher Burns to discuss his journey building User Vitals, a feedback collection and feature management platform, using RedwoodJS. The conversation begins with Tharshan's background building Scrum Genius with Python and Django, explaining how the disconnect between Django's back end and a React front end motivated his search for a more integrated full-stack solution. He describes what User Vitals does—aggregating customer feedback from tools like Intercom, Slack, and Help Scout into a single platform with branded customer portals, roadmaps, and changelog workflows. The discussion moves into technical territory, covering how Tharshan implemented custom subdomain routing with Render's API, the challenges and necessity of iframes for embeddable widgets, and the trade-offs of using JavaScript over TypeScript. The group exchanges views on Prisma's strengths and limitations compared to Django's ORM, the need for background job processing and CLI script access in Redwood, and the current gaps in server-side rendering and prerendering. Tharshan closes with advice for developers starting serious projects with Redwood: prototype your authentication and deployment setup early, as switching providers later becomes costly.

Chapters

00:00:00 - Introductions and Background

The episode opens with brief banter before Tharshan introduces himself as a SaaS founder currently building User Vitals, his second product alongside Scrum Genius, an asynchronous standup tool integrated with Slack and Microsoft Teams. He explains that Scrum Genius was built with Python, Django, and React, a stack he knows well but one that created friction between the front end and back end.

Christopher asks whether Tharshan would rebuild Scrum Genius in Redwood if given the chance. Tharshan says no due to the heavy server-side logic involved, but explains that the tight integration Redwood offers between front end and back end was exactly what attracted him for his new project. He describes the pain of hydrating React state from Django views, the awkwardness of deciding between API endpoints and request-response cycles for interactions, and the difficulty of onboarding new developers into two entirely separate codebases.

00:04:38 - Discovering Redwood and Subdomain Routing

Tharshan recounts discovering RedwoodJS through Twitter and blog posts over time, eventually choosing it for User Vitals because of its tight Prisma and GraphQL integration and the developer experience features like cells. The conversation shifts to one of Tharshan's notable technical accomplishments: implementing custom subdomain routing in User Vitals, allowing customers to use branded subdomains or their own custom domains.

He explains the high-level architecture, where customers configure a CNAME record and User Vitals handles SSL verification and domain checking through Render's private API. This was a key reason he moved from Vercel to Render, since Render offers unlimited custom domains and an API for managing them without requiring an enterprise plan. Christopher and Tharshan discuss the practical differences between hosting providers when it comes to programmatic domain management at scale.

00:08:52 - What Is User Vitals

Anthony steers the conversation back to the product itself. Tharshan explains that User Vitals is a feedback collection and feature management tool born from his own experience handling lengthy customer suggestions through support tickets. Rather than copying insights into Trello or Notion, User Vitals centralizes them, tracking feedback against the customers who left it and its priority level.

He walks through the product's key features: integrations with Intercom, Slack, Help Scout, and Zapier for inbound feedback; branded customer portals with customizable themes and public roadmaps; and a feedback loop closure workflow that lets teams notify specific customers when features ship, either privately in beta or through a public changelog. The tool serves product managers, founders, customer success teams, and even engineering teams who want to understand the real use cases behind feature requests.

00:12:28 - JavaScript vs TypeScript and Iframe Challenges

Christopher raises the topic of Tharshan's choice to use JavaScript over TypeScript in User Vitals. Tharshan admits it was largely a speed decision, noting that while the Chrome extension uses more TypeScript for reliability, the main Redwood codebase stayed in JavaScript for faster iteration. He acknowledges wanting to add more TypeScript in the future for better type safety and testing confidence.

The discussion then moves to iframes, which both Tharshan and Christopher use for embeddable widgets in their respective products. Tharshan describes iframes as a necessary evil that prevents style and script conflicts when embedding widgets on external sites, but notes the complexity of parent-to-iframe communication via message passing. They discuss W3 portals as a potential future improvement, and Tharshan explains that his widgets use Preact for a lighter footprint while communicating back to the Redwood GraphQL API.

00:22:16 - Framework Choices, Prisma, and GraphQL

Anthony asks about other frameworks Tharshan evaluated. He considered Next.js and sticking with Django, but Redwood's convention-over-configuration philosophy, batteries-included approach, and the seamless GraphQL-to-Prisma pipeline won him over. Christopher adds that Redwood's GraphQL API was his deciding factor over Blitz.js, since it enabled connecting multiple clients through a universal language.

The conversation turns to Prisma, where both developers appreciate its power but acknowledge the importance of understanding underlying database fundamentals like indexing, normalization, and efficient query design. Tharshan shares specific wishes for better JSONB support, aggregations, and clearer many-to-many relationship handling. Christopher jokes about his lengthy migration commands, and both agree that while Prisma does heavy lifting, it hasn't yet matched the maturity of Django's ORM.

00:27:09 - Redwood Wishlist and Background Jobs

Christopher asks what Tharshan would want in Redwood's 1.0 release. Tharshan highlights the need for background job processing and scheduled tasks, explaining that he's been experimenting with Faktory, a language-agnostic job scheduling library from the creator of Sidekiq. His main blocker is the inability to run Node scripts that have access to Redwood's services and database layer outside the normal request cycle.

He also wishes for better CLI script support, similar to Django's management commands, where custom scripts can be dropped into a folder and executed with full framework access. Anthony mentions Rob's Repeater project as a potential native solution. Tharshan clarifies he doesn't expect Redwood to build first-class scheduling support, but wants the framework to be extensible enough to support long-running processes and custom command-line tooling.

00:30:59 - Server-Side Rendering, Prerendering, and Final Advice

Tharshan brings up his wish for server-side rendering support in Redwood, noting that he currently uses Prerender.io with Nginx to handle meta tags and OG images for his single-page application. The current Redwood prerender implementation doesn't support cells or dynamic routes, which limits its usefulness for his case. Christopher shares his workaround using React Snap with Puppeteer, and they discuss the challenges of generating dynamic OG images per customer.

Anthony closes by asking Tharshan what advice he'd give his past self. Tharshan emphasizes prototyping authentication and deployment choices as early as possible, having cycled through Auth0, Supabase, and Firebase, and moved from Vercel to Render. He recommends building a small end-to-end proof of concept before committing, since switching these foundational pieces later is painful. He invites listeners to check out User Vitals and his previous Redwood community talk for more details on his serverless-to-serverful journey.

Transcript

00:00:00 - Anthony Campolo

It should be interesting because it's going to give everyone a run for its money in terms of the biggest, most sophisticated Redwood app ever.

00:00:06 - Christopher Burns

Everfund is getting more complex by the day.

00:00:10 - Anthony Campolo

I can only imagine.

00:00:22 - Tharshan Muthulingam

It's my first podcast, I think.

00:00:24 - Anthony Campolo

Ah, that's super exciting. First off, Tharshan, I want to get your last name pronounced.

00:00:28 - Tharshan Muthulingam

Muthulingam. Muthulingam with an M.

00:00:33 - Anthony Campolo

Muthulingam.

00:00:34 - Tharshan Muthulingam

Yeah, that's right. Tharshan. Please just use my first name whenever something's public. I never say my last name.

00:00:41 - Anthony Campolo

All right, so we'll just say Tharshan. Welcome to the show, Tharshan.

00:00:46 - Tharshan Muthulingam

Hey, everyone. Thanks for having me here.

00:00:48 - Anthony Campolo

Really excited to have you here. We're going to talk about lots of cool stuff with the project you're building and what you're building with Redwood. But before we get into any of that, why don't you first let our listeners know who you are and what you do, so we can get a little bit into your background.

00:01:03 - Tharshan Muthulingam

Hello, everyone. My name is Tharshan, and I'm currently a SaaS founder working on my own product. This is my second product, and that's a bit about me.

00:01:12 - Anthony Campolo

Cool. What was the other product?

00:01:14 - Tharshan Muthulingam

I currently work on Scrum Genius as well, which is an asynchronous standup solution that's integrated with Slack and Microsoft Teams, etc.

00:01:23 - Christopher Burns

Before we can obviously talk about Redwood and how I believe that you are on the same hand as me as a Redwood power user at this point, we're in our own league. We're taking it the crazy route. But first, I've had quite a story on how I moved to Redwood, and Redwood has helped me over at Ever Fund. You've built User Vitals from scratch. You've not really built a second version. So when we talk about Scrum Genius, how has that been built? And if you could rebuild it today, would you rebuild it in Redwood?

00:01:55 - Tharshan Muthulingam

This company is built in a very different architecture and technology stack, so I'm quite familiar with the Python ecosystem. Scrum is built with Python and Django, and I use React on the front end.

I think if I had to, I wouldn't redo it because it would be a lot of code and there's a lot of reliance on the back end, a lot more for Scrum, and there's a lot more need for server-side stuff, if that makes sense. There's a lot of back and forth.

One of the things that drew me to Redwood was the tight integration between the front end and back end, and that's one of the key things that I had trouble with on the Python and Django side. The front end was almost like a separate beast compared to the Python and Django side.

00:02:33 - Anthony Campolo

That's a really common theme that we hear, except instead of Django it may be Rails, or just some sort of very built-out server-side framework which was created to kind of be its own thing a decade before React even existed. Then you take a React front end and you try and stitch them together, and then you find all these weird edge cases. I'd be curious, what were some of the challenges you were running into trying to do that?

00:02:59 - Tharshan Muthulingam

Trying to use Django with React, you mean?

00:03:00 - Anthony Campolo

Yes, exactly.

00:03:02 - Tharshan Muthulingam

I did it in a different, slightly interesting way where I would hydrate the state. So all of the ORM layer, the data, or the business logic would happen in this view. Django works in a very similar MVC-type framework.

Django would have a view where all of the data would be generated, and then what I would do is actually ship that and hydrate that to be loaded on the front end. So React would hydrate the state and then render that stuff.

There was always a little bit of a challenge. If I wanted to add some interactions, should I do an API endpoint for that, or should I just do a request-response type of cycle? There was complexity when more interactions were added and a lot more handling of dynamic data. If you want to do modals and stuff, there's more complexity in that. You ended up spending a lot of time both on the front end and back end. There was not a lot of connection between them.

[00:03:50] They were completely different codebases, almost.

00:03:52 - Christopher Burns

It still confuses me sometimes how you could build your back end in another language and your front end in a different language because I'm a JavaScript purist, and you can type check me on that one.

00:04:05 - Tharshan Muthulingam

It was difficult, and I think when I would bring in people who were external to the codebase, who had just used it for the first time, that was definitely a difficulty. Training them up and upskilling them, like when I've hired interns in the past, that was a key difficulty.

With this technology stack, they had to learn two different things entirely from scratch, both the front end and React and stuff, and then the Python and Django side. I think my familiarity with Python and Django helped a lot. A lot more business logic was there in the application, and then the front end was really just a dummy container that was just rendering the data.

00:04:38 - Anthony Campolo

So how did you originally discover Redwood? How did you first hear about it?

00:04:42 - Tharshan Muthulingam

I think Redwood's been something that I've discovered over time. I've been seeing it in some of the early releases, and I've been reading the blogs and the tutorials on and off. I originally discovered it through Twitter or potentially a [unclear—possibly "Dev.to"] blog post. I've just kept up with it.

When User Vitals came about, when I wanted to work on something new and had that idea, I reached out to Redwood first to see if I could prototype that intersection between tools like Prisma and the React side. Having the front end and back end close together and in the same stack was very appealing to me.

Certain concepts it had, such as cells, were very appealing. It was a clear pattern that made a big difference in how I would go about developing applications.

00:05:32 - Christopher Burns

One of the reasons I would say you would be a power user of Redwood is I know you use your Redwood application on subdomains, and this was a big thing that you've spoken about in the community. You seem to be one of the first ones that have done it.

I sometimes still think, how do you even do things like subdomains? Like, how do I let someone else use my service with a CNAME? Is it as simple as just saying, point to this CNAME? These are questions that sometimes are quite hard to answer, I guess, but sometimes they're probably a really easy solution.

00:06:05 - Tharshan Muthulingam

I hear a lot of developers asking about this in lots of different technology stacks. I think each technology stack solves it differently. I believe that, if I'm correct, Laravel or another framework handles subdomain routing as a key part of the framework. But many of the technology stacks don't have this built in.

Yeah, you are right in terms of the high-level way it works. The customer would add a CNAME record in the example of User Vitals. When you sign up to User Vitals, you can select your subdomain. But if Redwood wanted to go on their own custom domain, they could put it on feedback.redwoodjs.com. They could also put it on roadmap.redwoodjs.com.

We've actually implemented a way for it to be completely self-serve on our site. You can do all the SSL in the background and verify that. What the user needs to do on the other end is connect their CNAME, and we provide that.

[00:07:06] And you add that to your DNS. It could be a provider such as Cloudflare or Namecheap, etc., and you would add your hostname to that.

00:07:15 - Christopher Burns

Do you do any of the complicated logic that some businesses do, such as verifying that you've added the CNAME, or do you just say add the CNAME and then it should just work in 20 minutes?

00:07:28 - Tharshan Muthulingam

This is actually one of the key things I moved to Render from Vercel, because they provide a private API. Right now it's in beta at the moment, but they provide an API where we can use a GraphQL endpoint to essentially add custom domains to our application, and they will take care of SSL verification and actually check if the DNS has been set up correctly.

So on our dashboard we can display those two flags in terms of has SSL been set up, and is the domain check valid and resolved. They handle a lot of that stuff. They offer unlimited custom domains, whereas I think it's a lot more complicated with Vercel or Cloudflare. You generally need to go on the enterprise plans to do that.

00:08:08 - Christopher Burns

Just before we move on, when you mean things like Vercel, Netlify? You mean like you move your name servers to Vercel or Netlify and then obviously start adding your records. But to gain access to that API, you need to necessarily be on Vercel enterprise tier. But with Render, they have it on a lower tier.

00:08:27 - Tharshan Muthulingam

You could realistically support up to a certain amount when you're starting out with a feature like this, to take some requests one by one and handle them manually. So you go into your dashboard, add them to your DNS one by one.

But having this be automatic and completely self-serve in the dashboard, I know with Vercel, I believe there's a limit of 50 domains you'll hit. I don't actually know about the private API, even if they have one. I'm sure they have one for enterprise customers.

00:08:52 - Anthony Campolo

Cool. We went very deep into very technical things. Let's take it back a few steps and set the context for our listeners. What is User Vitals?

00:09:02 - Tharshan Muthulingam

User Vitals is a feedback collection tool. The way that I built it out when I was building my previous product, quite often customers would submit quite lengthy feedback suggestions through a support ticket. In my case, I was using Help Scout. That's the tool of my choice for my ticketing. Many people use Intercom and lots of other tools. Some people even just fall back to email.

Often those suggestions had a really key insight. It might not be the whole thread or the conversation. You sometimes need to go back and forth with them. There's often key insights and quotes that you can take from the customer that you'd probably just want to take and keep around.

So what I would end up doing is moving that and copying and pasting that into Trello, pasting that into Notion and other places to keep track of it. User Vitals is a platform where you can take those key insights and manage them. User Vitals is a feature management and feedback tracking platform.

[00:09:55] So what User Vitals does is it integrates with all these inbound partners. We integrate with Intercom. At the moment we integrate with Slack. We integrate with Help Scout. We were working on a custom API and a Zapier application as well.

So wherever you're getting feedback from, you can add those key insights through any platform you're collecting feedback on to User Vitals and track that against who actually left that feedback and how important it is to them, whether it's a blocker for them, whether it's a critical suggestion, or it's just a nice-to-have for them.

00:10:25 - Anthony Campolo

Who do you think it's aimed at? Do you think it's aimed more at developers or maybe more business-minded people? Who's the target user for User Vitals?

00:10:35 - Tharshan Muthulingam

Let me just go back a little bit in terms of describing the key value proposition. I think when you're starting out, when you're a startup, you're usually concerned about getting more feedback. Part of that is we have tools to enable the collection process of feedback a little bit easier.

So we have built out a customer portal. That's what I talked about earlier, where every customer gets a customer portal that's branded to them, so they can upload their own logo. They can choose the themes and custom colors that suit their brand. Then there is a roadmap solution where customers can submit and see which items are public. The difference is that the admin is able to decide which feedback or roadmap items they want to make public.

The other key value proposition of the tool is actually closing that feedback loop. Often when you finish implementing some sort of feature, you need to go back to the customer. Most companies will do this by implementing a monthly changelog release. But sometimes you need to let select people or groups of people that the feedback came from know about it. Here's what we did. We've actually put it into beta. We're just letting your small group know. Then you might decide that you'd want to release that feature into a public release later on. It allows for those workflows to happen.

User Vitals is made for really anyone in a product role, PMs, founders, and even customer success. Our system has inputs like the Chrome extension, integrations with Help Scout, and more so that other team members can contribute input and view the feedback, including roles like customer support. Even the engineering teams can view that feedback and see what the real use case is behind this engineering request.

It's great when you're scaling up and trying to organize all your feedback in one place, but it's also great when you're just starting out and using the customer portal and the feedback widget to entice more feedback to come through, so you can encourage more feedback and reduce that friction for your customers to give that feedback.

00:12:28 - Christopher Burns

One of the things that I saw with User Vitals is that you use JavaScript over TypeScript. That's an interesting question, and I get why you laugh, because TypeScript is the additional thing. But a lot of people that I've seen, and even I, use TypeScript in a bigger project, and sometimes I think, do I really have benefits over TypeScript in things like my larger project? My question to you really is, have you ever felt so far that you needed TypeScript yet, and has it necessarily hindered your application being just pure JavaScript?

00:13:06 - Tharshan Muthulingam

There are certain parts of the codebase, such as the Chrome extension, that use a lot more TypeScript. Don't ask me why this has gone that way, where we've done a lot more TypeScript and typing on the Chrome extension side, where we needed to make sure that it worked 100% of the time.

But yeah, the Redwood side, I would say I think it's just the speed I've been developing at and the speed that we've been going at that I felt like it was easier just to straight away build with JavaScript and not think too much about TypeScript. It is something I want to get to in the future, to put in more TypeScript and a little bit more typing, so that we have a good confidence that the properties or the specific component is accepting these properties and this is the way it should behave. It probably will make it easier for testing and such a little bit later on.

So I think the answer is probably pure laziness. Yeah.

00:13:52 - Christopher Burns

One of the big things is with Redwood, TypeScript has been a bit rocky at times, and it's got a lot better in the last few months. It's still got a little bit further to go before we're at 1.0.

I don't necessarily think you've done a bad decision by not picking TypeScript right now, because you get tons of errors that are like, this totally works even though it's an error right now, but we'll just ignore that.

One of the things I also know that you've done in User Vitals is iframes. So what's your opinion on iframes?

00:14:24 - Tharshan Muthulingam

They're a necessary evil. I think when you're developing features such as User Vitals has, which is embeddable widgets, and I think, Chris, you have this in your product too for the donation link for Ever Fund, the real crux of it is that when you have external scripts and external styles being loaded in addition to an existing page, and you don't want those styles and scripts to conflict, or that business logic to conflict, or the styles to conflict in any way, having an iframe is actually a really good option.

You have a couple of hurdles to jump through. There are some things that make it difficult, for example communicating between iframes. You usually have to use some message-passing option to go back and forth between what's happening inside the iframe versus what's actually happening on the parent page, such as if you wanted to do callbacks, or load a particular widget with some configuration on the parent page, and then the iframe component and the widget can load that based on the parent page.

[00:15:23] There is some complexity there, but for better compatibility with any external application, whether it's a single-page application or just an HTML page, there's definitely some benefits there.

00:15:35 - Anthony Campolo

Are you looking forward to portals?

00:15:36 - Tharshan Muthulingam

I think the way I've gone about building the widgets is that I'm using a very light JavaScript footprint. That's how I've gone about doing it. So I'm not even sure that I would add a full React area, if that makes sense.

00:15:49 - Christopher Burns

We're talking about W3 portals, not React.

00:15:52 - Tharshan Muthulingam

Portals are okay.

00:15:55 - Anthony Campolo

And certainly not GraphQL portals, which is another thing as well.

00:15:58 - Christopher Burns

When I say W3, I more mean Google Chrome portals because Google is the one pushing it. It's really worth looking up. It's still in early beta origin trials.

They call it, say you want to share to Facebook. We'll take that as the most typical iframe you can get in the modern world. You want to share to Facebook. What the navigator actually does with portals is it basically says, open Facebook in this kind of UI that's popped over the page, and the navigator now treats it that you've opened Facebook. Then once you've finished doing what you need to do on Facebook, it closes the portal and you go back to the page you're on, kind of like what we expect most pop-up iframe models to do.

I keep looking at it with envy because I have dabbled around with iframes. I've spoken to you about them. It's a project that we really do need at Ever Fund. I keep going back and forth on it. I keep making progress and then putting it to bed for a little while.

[00:17:00] Keep making progress, putting it to bed. But portals seem like the most logical way going forward to do iframes, as in ones that you want to have a little bit of extra connectivity with the outside world and then close. It's not necessarily something that is embedded in the website, more like a pop-up, if that makes sense.

00:17:22 - Tharshan Muthulingam

For pop-ups, that seems like a really great solution. The portal would be something that actually the application itself controls. Yeah, it wouldn't be an external script. Okay.

00:17:30 - Christopher Burns

When Chrome is out with it, you literally just tell it to open a portal to this URL and it will handle everything around it, like blurring the background and the width and the height and the fun stuff that we still have to manage right now.

00:17:46 - Tharshan Muthulingam

Yes, I think a simpler way to do embeddable widgets would be amazing too, because right now the way that most applications do this is that they generally implement a loader script, which potentially would set up some sort of shim and take some config or look for some properties, and then actually load an actual iframe widget and optionally listen for interaction events in the parent page or inside of the iframe.

So there's definitely some complexity there to try to communicate between the parent and the actual iframe stuff.

00:18:18 - Christopher Burns

Exactly. And the biggest thing, as we said, is communication. Say we're going with the most typical one that I said: you click a button, a popup happens. Now inside that popup, you've just had a bit of JavaScript code that made the popup. It loads an iframe. Then once you do whatever you want to do in that iframe, you need to communicate from the iframe back to the website, saying, I've done what I need to do. Now close the popup.

That sounds really easy, but it's not. Sometimes it can be quite complicated to talk between browsers and windows and all that fun stuff.

00:18:56 - Tharshan Muthulingam

100%, yeah. There's definitely some features that we're exploring. I think it would be awesome to embed the portal as an option as an embeddable.

So let's say everyone was using User Vitals. Let's say you had a feedback page or a roadmap page. Instead of it going to our own custom portal, you could take out the header, take out the footer, and just keep a certain part of it. Then you could apply your own base styles, and that way it looks like it's part of Ever Fund. That's something we're looking into. But I think the real solution there is probably iframes.

00:19:26 - Christopher Burns

It's that technology that doesn't disappear and it pops up in tons of different areas. One of my favorite things that I noticed about iframes was an implementation that I've hardly seen before, but it's probably done a thousand times.

Tailwind UI and how they use iframes in their application. Because if you don't know, when you use Tailwind UI, you can view the component and then you can copy the code. But when you're actually viewing the component, what they're doing is injecting a really small HTML file into the iframe inside the web page. Really quite interesting. And it's kind of easy to replicate if you want that same kind of iframe functionality in your own application, but it still involves loading three different libraries to make it quite easy, like iframe resizable, iframe loader, iframe async. They just go on sometimes, iframes.

00:20:19 - Tharshan Muthulingam

The tricky thing is always that parent-to-iframe component communications. For example, we may want to allow for single sign-on. You generate a token on your site for single sign-on for an Ever Fund user, and you just tell it, load me this roadmap, but have them logged in automatically so they don't have to do anything.

That takes quite a bit of communication back and forth to verify that token is valid and loading that, versus what to do, like logging in that Firebase user and doing that stuff.

00:20:45 - Christopher Burns

My last question to do with iframes is what are you loading inside the iframe? What kind of technology does it look like? For me, I picked Next.js. Our whole portal system that we use within iframes would be Next.js. Is yours built in Redwood?

00:21:01 - Tharshan Muthulingam

You know, it's pretty basic. I think we use a light flavor of React. It's called Preact and it's a very light version of React.

00:21:09 - Anthony Campolo

Yeah. It's by Jason Miller on the Chrome team.

00:21:11 - Tharshan Muthulingam

Yeah, definitely. That's quite useful because it gives us a lower footprint, but it allows us to keep the same benefits of the development environment because it's quite close to what we would do with Redwood. There's quite a lot of code shared between them. But no, it's not Redwood. It's really just a simple React app communicating to the Redwood API.

00:21:28 - Christopher Burns

That's awesome. We do a lot of the same kind of things. We use multiple clients communicating through GraphQL. And that was one of the biggest things that actually sold me on Redwood, because I was deciding that when I was moving from Gatsby to something a little bit further forward, like Blitz.js and Redwood, they were both still quite early.

The biggest decision that made me pick Redwood over Blitz was the GraphQL API, because I knew no matter where we would go with the application, it would still be expandable. That's not the case with Blitz. It's a little harder if you want to just add a random client, because it doesn't speak the universal language of GraphQL. And so far, GraphQL has paid dividends in my application with its extensibility using other things like GraphQL Mesh.

00:22:16 - Anthony Campolo

Yeah, that's a good segue. Did you look at other full stack React type frameworks, and did you evaluate them against Redwood?

00:22:23 - Tharshan Muthulingam

My main two choices were Next.js and sticking with Django and Python. I've used Next.js for consulting work before and past projects, but similar to what Chris said, Redwood really attracted me because it felt like a whole package.

I actually didn't explore many other full stacks because I felt like they were all quite new. It felt like everyone was at a similar pace. If that made sense, I felt like I went with something that aligned with my philosophy of the way that I like to develop in terms of having a little bit of convention and best practices in a specific structure to follow.

That's actually one of the things that Django does quite well. There's a specific structure that you follow for doing specific things, and there's quite a bit of batteries included. Redwood felt like that too. There was a good emphasis added towards the developer experience.

00:23:11 - Anthony Campolo

Yeah, it's cool. And it sounds like if you're into full stack, server-rendered frameworks like Django and you're looking for something kind of like Next, Next actually might have been a very good choice for you. But that'll be an alternate universe we'll never be able to explore.

00:23:24 - Tharshan Muthulingam

Yeah, I think for me the primary goal was just getting something that was speaking the same language on the back end and the front end. What really, really, really attracted me to Redwood was having that GraphQL connection in the Prisma ORM and that tight connection between everything.

Having just specced out a service on Redwood, adding the SDL type definition, and then going into your front end and having that autocomplete ready without any further work is awesome. It's a great developer experience.

00:23:54 - Christopher Burns

But it is a bit dangerous because I remember doing a database module in education programs here in the UK twice. Once in college, once in university. That can be quite confusing to someone who's not from the UK because college is university.

The thing is, what I was taught in high school, then college, then university was that you had to get a piece of paper, plan it out, write the relations, and totally understand your database. And then we're in 2021 where you just kind of assume that Prisma will work out for you. You just say what you need and the rest happens in the background. It's yet to bite me that I don't really have a full SDL diagram of my database. Is it something that I should probably have? Maybe.

00:24:47 - Tharshan Muthulingam

Yeah, I think it's helpful. I do have rough SDL diagrams that I've got. But yeah, I think Prisma, you're right. When you have a tool that does a lot of heavy lifting for you and it almost does a lot of magic for you behind the scenes, it's really important to understand the fundamental concepts behind databases and SQL.

You can write very inefficient and slow queries, whether it's on the ORM layer or you design a model that is overly complex without thinking about normalization or normalization in terms of the relationships and the type of queries you're doing. For example, if you're querying a specific field and you haven't indexed that field, then you're losing a lot of performance there that you might be able to gain otherwise by indexing it.

Making sure that you're always referencing and querying by IDs wherever you can, because it's a primary field, it's already indexed by default. I personally also haven't found Prisma to bite me too much. I do wish that Prisma is a little bit more clear on the relationships between two different models, especially when you have many-to-many of the same relationship on the same model, because you often have to have a decorator that says, this is the relationship I need, to decorate them manually.

[00:25:57] It can be confusing. And I also have a really small nitpick where it will auto-create the backwards relationships for you and auto-complete it and put it in, but then it will make them CamelCase. So it would do a capital letter first and then do it. You know, even everything else is like lowercase for me. It does certain things. That is quite magic, I would say, but as long as you have those database fundamentals, I think you're generally good.

00:26:19 - Christopher Burns

When we talk about performance problems, just swapping to Mongo fixes that. That's a joke. I don't know, don't ask me.

00:26:26 - Tharshan Muthulingam

I'm looking forward to Prisma catching up to the rest of the ORMs out there for me. Like better JSONB support, being able to search inside a JSONB structure and filter inside of a JSONB structure, not just updating or creating and overriding stuff. Better support for aggregations and summarizations of tables and things like that.

They're definitely doing more of that. They're shipping really fast on some of that stuff, and they're catching up quite quickly. Yeah, I think it's not quite on par with the Django ORM yet. That's like the true ORM master for me.

00:26:57 - Christopher Burns

My one nitpick with Prisma is the command that's literally yarn redwood prisma migrate deploy. Please someone shorthand that already.

00:27:08 - Tharshan Muthulingam

Yes.

00:27:09 - Christopher Burns

If we could look at a glass ball and you could decide the 1.0 of Redwood, what does it need in terms for you? I'm sure I have my answer, but what would you say Redwood is critically needing right now for it to just make you so happy?

00:27:27 - Tharshan Muthulingam

There have been some roadblocks I've been hitting recently with certain things I needed to do. So for me, I'm getting to that stage where I need to process applications in the background in terms of functions and background functions and scheduling, being able to run certain tasks on a specific schedule.

I've often had to reach for third-party dependencies, but I prefer to use an open source library that I can self-host rather than rely on an external service for this.

One of the big roadblocks I've run into is being able to access the Redwood files in a Node script. There's various use cases for this, but being able to run quick CLI scripts on the command line that have access to the Redwood services, the database, and other things so that you don't need to recreate them from scratch. I think having that would help.

I was recently experimenting on something called Faktory. There's a pretty well-known background task scheduling library, I believe it's called Sidekiq for Ruby. The author of that made a version that can be used for any programming language, and it's called Faktory.

So the way it works is that you have a client and then you have a worker. The client can send messages. Usually I think Faktory comes with Redis built in, so when you run the Docker image, it will run that and it will run the scheduling. It also comes with an admin interface, which is really nice. So it shows you all the scheduling tasks and the queues and how many tasks are in the queue and things like that.

[00:28:24] So one of the things I had issues with is there's no way right now to run that worker script and have access to the Redwood files at the moment. So if I wanted to execute some sort of service function for a particular callback to a queue or worker script, that's a little bit of a blocker. So I think being able to do that would be awesome.

00:29:12 - Anthony Campolo

You should definitely talk to Rob about that because he has Repeater, which I don't know if you've checked out at all, but that's a whole background job kind of queuing thing, which is using, I think, Sidekiq like you mentioned. So that would be the closest thing to a native Redwood solution for that.

00:29:26 - Tharshan Muthulingam

I definitely don't think Redwood itself needs to handle or have first-class support for scheduling or background queues. It's definitely out of the scope of Redwood itself, but being able to support additions of libraries that are long-running and being able to support use cases for CLI scripts, command-line scripts.

So let's say I wanted to have certain scripts that I'm going to run to populate my database in a specific way. We have the seed database right now, but being able to run it with my own custom command-line scripts would be awesome.

Django has this concept called management scripts, where you can put a particular py file in a folder and it will become a management script that gets exposed through Python manage.py and then just whatever you want, whatever the name is of the file.

00:30:10 - Christopher Burns

Seeding data is really quite a complicated matter. Peter Pistorius is obviously working on a product to help with that. Our solution we made at Fund was the most interesting one: we basically exported all the data from the database, replaced all the user security things that we wanted to get rid of, and then hosted the JSON in the database and just did a seed from it every time to re-populate it in. It kind of works, but it's not the best solution.

I keep meaning to update my snap data to carry on going with that. I really have one final question before we wrap up. If you could take it from the beginning again, building with Redwood and User Vitals, what would be the one thing you would do?

00:30:59 - Tharshan Muthulingam

There's actually one more thing that I was thinking would be awesome to have. Again, it's more of a wish list. I currently use Prerender.io in front of Nginx to do some prerendering and meta tags and OG tags for single-page applications such as Redwood. It would be awesome to have some sort of option where you can server-side render some Redwood pages. I think there's some movement in that, and I know Danny's done a lot of work on that recently with some of the server-side work.

00:31:29 - Anthony Campolo

So what's the issue with the current Prerender implementation? What's the limitation there and what do we need to add to get that?

00:31:34 - Tharshan Muthulingam

I believe the current implementation difference is that it does not support, Chris, correct me if I'm wrong, but I believe currently rendering of cells is not supported and prerendering of routes with dynamic parts is not supported.

00:31:48 - Christopher Burns

Yeah, it's a bit hard to do that. Redwood kind of needs to take steps more to how Next does their pre-rendering with get static props. So when you have the static props then you'll be able to pre-render the cells. But obviously there's a little bit of work to do there to get there.

My hack that I'm still using is React Snap because that does do that because it uses a Chrome Puppeteer in the background to do it.

00:32:15 - Tharshan Muthulingam

Oh, interesting. Okay.

00:32:17 - Christopher Burns

It works, but it's not the best solution. But it's good enough right now.

00:32:21 - Tharshan Muthulingam

Is that similar to Prerender.io, or is that different? How is that different to maybe an external service that would crawl it and then store it in a cache for you?

00:32:30 - Christopher Burns

It's a script that basically just runs the website, waits for all the React to build, and then when it detects that there's no more HTML DOM changes, it will copy all the HTML markup into the Redwood tag inside the index.html, and then you basically just host that and tell React to rehydrate from that.

00:32:54 - Tharshan Muthulingam

Would that go through the database and then fetch that data?

00:32:58 - Christopher Burns

No, I don't think you can necessarily do it on logged-in stuff. We use it on CMS kind of stuff. That doesn't matter if you're logged in. But yeah, it's definitely possible if you just need it on more like CMS stuff that you don't necessarily need to be logged in.

00:33:13 - Tharshan Muthulingam

For my use case, it's not for logged-in people. It does need to hit the database. So for example, my use case usually is to just support OG meta tags. I don't know if you've ever run into this where, let's say, someone shares your donation link and you want a nice Ever Fund-type OG image with their custom company name plus Ever Fund and some sort of donate text, and you want to customize that per customer right now. That's not easy to do, and I've resorted to options like Prerender.io to do that.

00:33:46 - Christopher Burns

That was one of the reasons we picked Next.js to host our donation links, was so we could make these interesting OG images, and especially allow the user to edit the OG image using a custom image. It's really good, but the only problem that I've seen with it is that your first user is still going to get the old image, and only when it's reloaded, it reloads in the background to the new one, so then the next person will get the new one, if that makes sense.

00:34:16 - Tharshan Muthulingam

Right. Interesting.

00:34:17 - Anthony Campolo

Okay, so we were curious to get your wisdom that you would give your past self if you could tell yourself, starting this journey, what stuff you would have liked to have known ahead of time or advice for other people who may be starting this journey building some sort of serious product with Redwood.

00:34:32 - Tharshan Muthulingam

Yeah, I think I've gone on an interesting journey related to auth providers and deployment providers. I believe I'm probably one of the people in the community that's tried out the most in each category and quickly iterated and prototyped each solution to find out what worked for me.

I noticed this quite a lot in the Redwood community too. People often get tripped up about OAuth providers or deployment providers in terms of where to host. Redwood right now is touted as a serverless framework, but it can be very well hosted on a serverful solution as well.

So I actually started off hosting on Vercel, and I started off with a different auth provider like Auth0. I tried Supabase and then I ended up coming back to Firebase as my default solution, just because it fit my needs for what I wanted to do for my application.

So I think if I was to go back, I would spend some time to prototype that as early as possible and get to that end flow of what I want my deployment to look like. I'd think about the application and where some of the pitfalls could be, what I want to do with this application, and how I want to deploy it, and really go from start to finish, even with just a very kitchen sink type of application. I'd really think about authentication because it's such a key pillar of the application.

Usually once you get it right, you're not touching it too much. You just got to get the foundation right and then you're good. You generally don't want to be changing it when you have 100 users in your application or whatever it is. Getting that right early on is key. I would say to myself, do that even earlier.

00:36:11 - Anthony Campolo

Yeah, Chris has been banging the serverful drum for quite a while, and I've been getting a lot deeper into it over the last couple months and figuring out how to get a better deploy story for people such as yourself who want to go that serverful route. So happy to hear that that's working out for you 100%.

00:36:27 - Tharshan Muthulingam

Yeah, and I would recommend if anyone wants to learn more about my journey, they can definitely listen to the Redwood talk I did on User Vitals. I talked a lot about my journey on moving from serverless to serverful, and we currently host pretty much all of Redwood's components. So the API, the website, even the embeddable widgets, that's all hosted on Render, even our database and everything. It's a great solution for us.

00:36:50 - Anthony Campolo

Yeah, we'll definitely link to that in the show notes. And why don't you let our listeners know also where they can find you, where they can find User Vitals and all that?

00:36:58 - Tharshan Muthulingam

If you're interested in User Vitals, or a product manager or someone else who owns a product and is a SaaS founder who could use User Vitals, definitely let them know to check it out. It's at [unclear].com, and we have our early access request form there.

Since we're in the early stages, I'm personally onboarding every single person that comes through the door and doing a personalized onboarding to help them fit User Vitals with their workflow of their own tools for customer support and success.

00:37:28 - Anthony Campolo

Awesome. We're really excited to have people building with Redwood. So thank you so much for going on this journey with us, and we're really excited to see these types of products be created. So definitely recommend everyone check out User Vitals.

00:37:42 - Tharshan Muthulingam

Great. Thank you. Yeah, it was great chatting with you guys.

00:37:44 - Anthony Campolo

Have a good day, everyone.

00:37:45 - Tharshan Muthulingam

All right. Bye, guys. Yeah, I think User Vitals is kind of getting complex because of the integrations. The more third-party people you integrate with, the more complexities there are to deal with. Everyone has a different UI and...

00:38:28 - Christopher Burns

API.

00:38:29 - Anthony Campolo

[unclear]

00:38:33 - Tharshan Muthulingam

Yeah, definitely. There's definitely some complexity.

On this pageJump to section