Code and the Coding Coders who Code it

Episode 50 - Adam Fortuna

Drew Bragg Season 1 Episode 50

Swimming against the current sometimes leads to unexpected treasures. In this fascinating conversation, Adam Fortuna reveals how migrating Hardcover—a social network for readers with 30,000 users—from Next.js back to Ruby on Rails delivered surprising performance improvements and development simplicity.

The journey begins with Adam explaining how Hardcover originated as a response to Goodreads shutting down their API. As a longtime Rails developer who initially chose Next.js for its server-side rendering capabilities, Adam found himself drawn back to Rails once modern tools made it viable to combine Rails' backend strengths with React's frontend interactivity. The migration wasn't a complete rewrite—they preserved their React components while replacing GraphQL with ActiveRecord—and unexpectedly saw significant improvements in page load speeds and SEO rankings.

At the heart of this technical evolution is Inertia.js, which Adam describes as "the missing piece for Rails for a long time." This elegant solution allows direct connections between Rails controllers and React components without duplicating routes, creating a seamless developer experience. We dive into the challenges they faced, particularly with generating Open Graph images and handling API abuse, and how they solved these problems with pragmatic hybrid approaches.

The conversation takes an exciting turn as Adam discusses their work on book recommendation engines, combining collaborative filtering with content analysis to help readers discover their next favorite book. As someone currently enjoying the Dungeon Crawler Carl series (described as "RPG mixed with Hitchhiker's Guide"), Adam's passion for both books and elegant technical solutions shines throughout.

Listen in as we explore how going against conventional wisdom sometimes leads to better outcomes, and discover why Hardcover is now being open-sourced to invite community collaboration. Whether you're interested in Rails, JavaScript frameworks, or book recommendations, this episode offers valuable insights into making technical decisions based on real-world results rather than following trends.


Links

Send us some love.

Honeybadger
Honeybadger is an application health monitoring tool built by developers for developers.

Judoscale
Autoscaling that actually works. Take control of your cloud hosting.

Disclaimer: This post contains affiliate links. If you make a purchase, I may receive a commission at no extra cost to you.

Support the show

Drew Bragg:

Hello everyone and welcome to another episode of Code and the Code Encoders. Who Code it? I'm your host, drew Bragg, and I'm joined today by Adam Fortuna. Adam, for anyone who's not familiar with you, would you please give us a little bit of background on yourself.

Adam Fortuna:

Hey, hey, I'm Adam. I think maybe some Rails and Ruby developers might know me from working at Code School doing interactive courses. Some people might know me from a financial blog I wrote for a couple of years called Minify you, minify JavaScript that's kind of the emphasis of the name. Lately I've been working on Hardcover, which is a social network for readers to find books and get recommendations from friends, all right.

Drew Bragg:

So the way this is going to work for anyone new to the show is I'm going to ask Adam three questions. I'm going to ask him what he's working on, what kind of blockers he has. If he doesn't have a current blocker, he can talk about a recent blocker he had, how he went about solving it. And then we'll wrap up the show by asking Adam what's something cool, new or interesting that he's recently learned or discovered. It doesn't have to be coding related, but of course it always can be so without any further ado, adam, what are you working on?

Adam Fortuna:

I just finished a really big migration for hardcovers codebase where we migrated from Nextjs to Ruby on Rails and that ended up taking quite a bit of time. Some of our back end was already in Rails but our front end was in Next. That migration really took over my life for quite a few months lately.

Drew Bragg:

That's not a quick and easy migration. So, in your mind at least, what would you consider? The difference between a migration and a rewrite Depends on how much you're able to reuse.

Adam Fortuna:

All of our front end was in React within Nextjs, so we were able to keep that piece and move it over to Rails, so that part was able to reuse. All of our front end was in React within Nextjs, so we were able to keep that piece and move it over to Rails, so that part was able to be migrated. And the part that had to be rewritten was all of that data access layer, because previously in Nextjs we were hitting a GraphQL API and getting our data and then sending that to React or sometimes getting it client side and using that in React. This pretty much changed it all to just using it in Rails, getting it from ActiveRecord in the database, serializing it to JSON and sending it to React. So, yeah, it was a bit of a combination of those two.

Drew Bragg:

And you recently wrote a fairly detailed blog post or at least a part one blog post on doing this and you go into quite a bit of it and the one part that stuck out to me a bit was the performance improvement that you guys saw and I think that's to a lot of people probably surprising to hear like, hey, we used Ruby on Rails and got better performance. It's not surprising to most Rails devs to hear that, but it could be anyone listening who isn't familiar enough with Rails and may just know the oh, it doesn't scale. It's not performant nonsense that people talk about. Can you talk a little bit about the performance improvements that you're seeing and any say speculations you have onto what is helping the most with that?

Adam Fortuna:

So initially, when the project started back in 2021-ish, I really wanted to do something that was really interactive. So that's kind of why React was chosen as the front end. I'm a Rails developer for quite a long time, but I didn't choose Rails for it initially because the server-side rendering side if you're doing a JavaScript app within Rails five years ago that had a completely different way to do it. So, like with Nextjs, we were able to render the server-side, render all the HTML, so the first load gets all the HTML of the page you need and then it's hydrated with React. But we weren't able to do that with Rails until recently, where now we were able to do that using a combination of Vite and SSR and Inertia to take this big React tree, render it to HTML and send that as the first load, and so that kind of meant there was parity there between what would be loaded initially from Next and Rails.

Adam Fortuna:

I wasn't expecting much improvement beyond that. Next actually handles a lot of cases really well, like fonts it does some really cool things for those where it loads them in really fast ways, and some other just speed improvements for Google PageSpeed but I was kind of surprised at how well Rails was able to do that. But on top of that we were seeing startup times for the initial requests. That took a little bit longer on serverless functions, with Next even on Vercel or Google Cloud Run, and then when we moved to Rails, even just deploying on digital ocean droplets, those time to first byte metrics ended up speeding up significantly and that ended up being the biggest boost to our Google page speed.

Drew Bragg:

Right, and you said that actually helps a lot with how Google ends up ranking you in their search. So it's an SEO kind of thing. I don't know if you would consider it out of the box, but it almost sounds like it was an accident, that those things like that wasn't the target improvement. You were just making the move and then noticed, hey, we're getting these side benefits that we weren't expecting.

Adam Fortuna:

Yeah, the baseline was really not dropping our SEO.

Drew Bragg:

But incidentally, you talk a little bit in the blog about that actually being part of the reason why you chose Next in the beginning because you wanted to React front end for the interactivity. But because React doesn't actually load up a page right off the bat, google was going to kind of not be able to pick up on a lot of your SEO and whatnot and cause a hit to your page speed. So you choose Nextjs for that server rendering component. But then it actually improved even more when you got to Rails.

Adam Fortuna:

Right, exactly.

Drew Bragg:

Yeah, what was it like working with Inertia? Because I've heard lots about it, I know its existence, I've heard good things about it, but I haven't played with it myself. So what do you think about Inertia as part of a Rails project?

Adam Fortuna:

So I feel like Inertia was the missing piece for me for Rails for a long time. The sanctioned Rails path for generating like JavaScript apps has changed quite a bit over the years. We had like RJS for a while and things like that, and then more recently it's been like stimulus, or you just use Turbolinks and just re-render the entire page or something like that.

Drew Bragg:

Yeah, Hotwire is the new Turbolinks at least, and that's a follow-up question I want to talk more about Inertia, but then I want to talk a little bit about Hotwire.

Adam Fortuna:

So, yeah, carry on with Inertia, I'd kind of spent so much time learning React I hadn't learned the stimulus, that side of Rails. So when I was thinking about how to use this React app on Rails, there were like three major gems that kept coming up. I think there's like a React on Rails and a React Rails one, and those handle things in different ways, but inertia ended up being kind of the most lightweight of them all and it felt the most Rails-y of them all. So I think about it like in a controller of them all. So I think about it like in a controller you set some instance variables and those get passed to a view. Usually With inertia you can do that exact same thing.

Adam Fortuna:

Just set some variables in a controller and you can either call render I think it's render inertia, colon and then a string to a part, to a template, and that template is a React or a Vue component or I think even a Svelte component, and it'll take in those instance variables, or you can pass them in as a separate argument on the render, kind of like render JSON, and then you pass in some JSON. That kind of skips all the rest of it. It goes straight from your controller to a React component. There's no other step there. So your component at that point just takes in whatever was passed in from the controller and then you're just straight in React. There's no other step.

Drew Bragg:

So one of the lovely things I think about working in Rails and I've worked with split code bases before a Rails backend with a it was actually a Vuejs front end, but same basic concept. But the thing that always gave me a little bit of a headache was the routing. I feel like I would define my routes in Rails and then I would sort of redefine them on the front end and from what I know of Inertia, it kind of solves that problem for you.

Adam Fortuna:

Yeah, that was one of the biggest differentiators between Inertia and the other React on Rails libraries that I was looking at.

Adam Fortuna:

Where those ones you would probably need to use React Router or something like that and kind of maybe have like a catch-all route in Rails that rendered something and then there's a lot of different steps.

Adam Fortuna:

With Inertia you can kind of bypass that because the way that it works is like within React or Vue or Svelte you have a custom inertia link component, a JavaScript component, and when you use that component to link from one page to another it doesn't do a full page load, it kind of does something kind of more similar to Turbolinks, where it hits your controller.

Adam Fortuna:

So maybe you're linking from books to show a specific book. When you click on that link to go to that specific book, it hits the Rails route for like books show like it normally would. It renders whatever you would normally render, but depending on if it's a full html request or an inertia request, like when you click on a link, it loads kind of a different version of that page where it's just able to download it and then repopulate the page with it, so it doesn't have to do a full html reload. It just kind of loads the components and data it needs for the new page that you're loading up and replaces your current state on the page with it okay, that sounds familiar to how things kind of work in hotwire, which is kind of the turbo links replacement.

Drew Bragg:

But based on the fact that you keep referring to turbo links, is it safe to assume you're not super familiar with hotwire, as how rails is your? Let's do air quotes here, but preferred way of handling the front end now.

Adam Fortuna:

Yeah, I've only done like the basic turbo links where you don't even have any real JavaScript. You're just re-rendering the page.

Drew Bragg:

Okay, I did want to ask you about why did you choose to stick with React versus Hotwire. If there was a specific reason Like, oh, hotwire doesn't do this well, but React does, so we just stuck with it. Or hey, we had React, our front end was already written. It was easier to port that in than learn Hotwire, so we can skip those questions. That would be a rewrite instead of a migration.

Adam Fortuna:

There you go.

Drew Bragg:

There's the difference between the rewrite and the migration. I hesitate to ask this question because it feels very much like the second question, but I swear it's not. What was the most challenging bit about going from Next over to Rails?

Adam Fortuna:

as active record queries and then serializing them to JSON and then sending them over. I think the most difficult part was probably just getting all of the Vite server and Inertia and Rails and getting all those to work together in harmony. Once they were all working together, it was great. But there were a lot of parts where I'm like I'm not setting a specific Vite variable in my Docker config or in my Docker file. I think those DevOps side parts where it's kind of still a kind of a new combination of these technologies working together and so relying on the documentation helped. But there were a couple of times when I had to join the Inertia, Slack or Discord and they helped me out with some roadblocks.

Drew Bragg:

That's cool. That was a follow-up question right there. How is the community with Inertia? Is it very similar to the Rails community, a little bit different, more React-focused, JavaScript-focused?

Adam Fortuna:

I'd say it's still very small and most people that are using Inertia seem to be using it with Laravel, because Inertia started as a Laravel project and, from what I understand, it was split off into its own standalone project with adapters for additional frameworks like Django and Rails. So Inertia is kind of this high level framework that connects back-end frameworks and front-end frameworks.

Drew Bragg:

Very cool. What has been, for you, your favorite part about being back in Rails, going from Nextjs coming back to Rails? Other than these, oh cool, it turns out our page speed improved and Google's ranking us higher. Those accidental things are great, for sure, but when it comes to actually working with your code base, now, what's been? Yes, I'm so happy to be back on Rails.

Adam Fortuna:

I feel like it's just a combination of active record and being able to just use my models to get the data I need for a page, rather than trying to figure it out with JavaScript libraries and GraphQL, and then kind of on top of that, one of the really cool libraries we're using is OJ Serializers, which is the library we're using to serialize the data that gets passed to React. There's this really neat add-on to that serializer that creates TypeScript objects for those serializers, so we're able to generate TypeScript types for all of our serializers and then use those on the React side. Even though Ruby is obviously not a strictly typed language, we're able to strictly type when you pass things over to the client side.

Drew Bragg:

That sounds very helpful if you're doing TypeScript on the front end and coming from Ruby. Okay, so, as the follow-up to the, what's been your favorite part about coming back to Rails? What's been your least favorite part about coming back to Rails? Listen, we all know that Rails is perfect and no one would change a thing about it. Sarcasm aside, it's got its rough edges. It's not perfect For you. This is a safe space. No one's going to send you hate mail, and if they do, send them to me and I'll set them straight. But, like for you personally or for your team, especially coming from next js, where you might have had these nice helpers or this way of handling things. Then, coming back to rails, maybe you lost it or rails just did it differently For you. What do you think has been a bit of a pain point?

Adam Fortuna:

There was one part that when we moved over, I'm like oh, I don't even know how I'm going to move this part over, because there wasn't a good Rails equivalent which was generating our open graph images. Because we were like a social network, we want people to share everything and we want pretty open graph images for everything that are generated based on the content of that page. So you share a list. We want them to see, like the user that shared it, some of the books on that list. And in Nextjs they have kind of this really nice interface for creating these, where you just kind of write a component, you actually just return HTML and it creates a full image with it. You can pass in fonts. It's kind of like everything's encapsulated in one file.

Adam Fortuna:

It was not the best to test and it had its quirks with Tailwind, but it did work. I tried recreating some of that in Ruby and Rails using Grover, which is this library that I think it uses, like Puppeteer or some kind of headless browser, to like get a page and take a screenshot and use that. But that killed our entire server. The RAM usage of it spiked and I had to like split that out of the main app and into its own JavaScript service. It just takes a URL from the Rails app and then it generates an image for that URL. The creation of the content still happens on Rails, but taking a picture of that content and using it as an Open Graph image happens in JavaScript.

Drew Bragg:

Interesting. Okay. So anyone out there looking for a side project, there you go. Solve that problem in Rails, make it easy for Open Graph images. So we did briefly touch on the migration and what's been a pain point. But what kind of blockers do you have, or did you have that you want to get into? I always find the blockers question a very interesting question because sometimes people will have a current one and it'll be interesting, or someone will say, well, we were really blocked on this for a while and here's the cool way we solved it. And this is such an interesting project because you don't hear about this very often, right, a lot more often you'll hear of someone moving away from Rails into the JavaScript ecosystem because JavaScript's eating the internet. You kind of almost did it in reverse, but you're getting a lot of benefits from it. I'm interested to hear your blockers story or stories from this.

Adam Fortuna:

One that probably takes a little context to go into. So one of the reasons hardcover was initially started was because Goodreads was getting rid of their API and I used their API to show what books I was reading on my blog and I'm like, oh, I need a new book tracking site that has an API. So I ended up starting one. So we've been very API first since the start, and for our API we used Hasura for it, which generates a GraphQL API from a Postgres database, and you can also have it create GraphQL endpoints that will delegate to API requests to other servers. Create GraphQL endpoints that will delegate to API requests to other servers. So, like our Hasura app would a lot of the time just get stuff from Postgres and return that, but if something is more like a service layer or something that requires a lot of different changes, it'll hit Rails, rails will do some processing, it'll return that result to Hasura and that'll be returned to the user of the GraphQL request. So this big Hasura piece we've been generating API keys for it and we kind of realized that people have started to abuse this API because we didn't really have anything in front of it and we were using the free version, which didn't really allow much in terms of rate limiting or depth limiting, and it also provided with a like query, like a I like, for every single field in the database. I don't think we want people being able to do I like queries on book descriptions when we have 30 million books in our database when we haven't indexed that column. So, okay, we need to do something with this api layer.

Adam Fortuna:

So we ended up creating another rails app and this one is a reverse proxy to hasura. It kind of just sits in front of it and does rate limiting, depth limiting, ip blocking, restricted api keys. If someone like pushes their key up to github, we can like invalidate it. So it's kind of just this layer that sits in front of it and that one was kind of figuring out. That solution was a big problem because it happened because our servers were going down. People were hitting our database so fast and so often that I kept having to increase the size of our database every like month or two. On Heroku, okay, we just have to do something about this, and trying to figure out how to do that when it's coasted software with Asura and put something in front of that ended up being the best solution so far, but we're still kind of figuring it out because it only has like one server. It's kind of just running on one DigitalOcean droplet that forwards to this GraphQL server. But so far it's been a good solution Okay.

Drew Bragg:

You actually just prompted a thought in my head about the kind of infrastructure you have, because you've mentioned we were having to increase our Heroku database, but then you also said it runs on a droplet. What are you using to host and deploy this new Rails app?

Adam Fortuna:

using to host and deploy this new Rails app. Yeah, right now it's pretty much all on DigitalOcean, except the production database, which is still on Heroku, and I think our Hasura API is still on Heroku and Dino's there, but those two are scheduled to be moved over eventually.

Drew Bragg:

Gotcha, and how are you deploying over to DigitalOcean? Moved over eventually, gotcha.

Adam Fortuna:

And how are you deploying over to DigitalOcean For the main app and the API reverse proxy in front of it? Those are just using Kamal, which I have really, really liked. I'm not very good at DevOps, like to be honest. Chatgpt has been answering a lot of my DevOps questions. Sure, yeah, but it's gotten to the point where I can at least deploy something and not feel like it's going to fall down in five minutes.

Drew Bragg:

Right, right, I'm sure it's a little more cost effective than being on Heroku was also Just anyone who's been on Heroku knows the pain of that bill going up very quickly. So is that Kamal 1 or Kamal 2?

Adam Fortuna:

that you're using Kamal 2.

Drew Bragg:

That you're using Small two.

Adam Fortuna:

Okay so, actually, when we moved over and I canceled everything on Heroku, one of the services I was using was Judo Scale, which is, I think, one of your sponsors. Yes, and like Adam emailed me the automatic why did you cancel? And I'm like, oh yeah, we're moving to DigitalOcean, we're canceling. And he responded like oh yeah, you're running hardcover.

Drew Bragg:

I use hardcover too, so it's like a funny moment there. Judo scale is a sponsor. Thank you to them for sponsoring the show and thank you to them for their product, because at my day job podia, we use judo scale, because we're on heroku also, or still, as it were, and every month we get an email from judo Scale like you saved $3,000 plus, this month you saved $4,000. It's just like, holy crap, that's awesome that we don't, a, have to manage that scale ourselves and, b, that we can kind of just set it and save that money between our downtime and uptime, because we have a lot of that depending on what our creators are doing.

Adam Fortuna:

On a similar note, having that on DigitalOcean, with being able to scale out additional droplets for the app, that's something I still an unknown problem for me. I don't know how we're going to do that yet.

Drew Bragg:

Okay, yeah, I can definitely see that. If you're used to having Judo scale which just kind of does the magic for you, it's very, in a way, hand wave. You're just like I'm on fly, or I'm on Render, or I'm on Heroku Help me Obi-Wan and it just does it for you. Moving to that, I don't want to say it, but isn't that what Kubernetes is for? Like? Oh no, I think so. Yeah, is that something that you guys are actively working on, or is it more of like a hey, once it becomes a big enough issue or a big enough cost for us, we'll tackle that problem.

Adam Fortuna:

Yeah, I think more the later. For now that performance side hasn't been an issue, so we probably have plenty of room there. Mostly because we're relying very heavily on solid cache for so much, Most requests have very little in terms of functionality. Most of it is able to just be provided from a single solid cache request Nice and is able to just be provided from like a single solid cache request.

Drew Bragg:

Nice, and are you also using the other solids, like SolidQ?

Adam Fortuna:

We're still using Sidekick. I still like Sidekick.

Drew Bragg:

Yeah, we use Sidekick. I'm still a fan. I'm just always curious when someone is using the new stuff to get their takes on it. So we'll at least stick with solid cache. How are you liking that caching strategy?

Adam Fortuna:

It on it. So we'll at least stick with solid cache. How are you liking that caching strategy? It's just kind of worked. I haven't really had to look at it. I actually should probably check if that database is overflowing or something. So far it's been fine.

Drew Bragg:

That's a great sales pitch. Or just hey, it works is a fantastic way of hey, how good is it? Well, it just works. That's really good. I like it when something can just be like oh, out of the box, yeah, it does everything we need, or so much of what we need that we can say it just works, Without naming any of the things we just talked about. Sorry, to make your life more difficult what is something cool, new or interesting that you want to share? It doesn't actually have to be coding related. You can say, hey, I just read this great book, or I just started this hobby. Those are totally answers that people have given and have been awesome answers. So I'm not making jokes. You can pick whatever you want, but what is something cool, new or interesting that you've recently discovered, learned about?

Adam Fortuna:

I'll kind of try to bridge that with a little tech and a little non-tech. So one of the areas I've been trying to explore more is recommendation engines, which are this huge can of worms. Whenever I see a site that does recommendations well, I'm in awe, because a good recommendation engine takes in so many inputs and for us, like a book site, you're taking in data about the book, the, the genres, the description, the lists, it's on the author, what other books that author has written like tons of data and trying to get a recommendation out of it. And initially I was looking into using like tensorflowjs and doing that on the javascript side. Lately I've been kind of trying to look into doing some of that on the python side. One of the reasons for that is, like right now one of the top ways that people find books on hardcover is our trending books list, which is just a popularity list. I kind of think about it like when I was a kid I would always get the Nintendo Power Magazine and I would look at the top 20 games in every month. I'd be like, yes, link to the Past is still number one, and the trending list is kind of like that for books. Are the books that I am really excited about. On it.

Adam Fortuna:

Book I'm really excited about that I'm reading right now is the Dungeon Crawler Carl series, which has been really fun. Definitely recommend it. It's like RPG mixed with Hitchhiker's Guide Just really fun. I want to create a recommendation engine for us that we can use that kind of input. Oh, I liked this book. What are some books like it? Or what are some ones that are inspired by it? And getting an answer to that question has been a lot harder than I thought, but I feel like I'm still in the early days of solving it. So if anyone has any recommendations on things, especially in the Ruby world, because I feel like I'm looking outside the Ruby world for it mostly I've looked at some things in the Ruby world the Disco library, which does collaborative filtering. It's a really neat gem. You can have it create recommendations for things, but it's only using a rating. It doesn't use all the other data about a book. So if anyone has any tips on that, I'd definitely be open to some research.

Drew Bragg:

Yeah, sure, that book name has popped up in my news feeds or whatever. I use Android devices, so they have this discover feed where it'll just randomly show you articles related to stuff you've probably searched about or who knows, it's probably listening to me and I've said something dungeon crawlery, and so it was funny to hear you bring it up. And now I'm even more interested, now that you've kind of floated the idea, an engine like that. Would that be considered machine learning, where you're kind of taking all of this input and building recommendations? Or do I not understand machine learning at all?

Adam Fortuna:

If I understand it, it's a miracle, but I believe so. There's so many terms throwing around in the machine learning world and from supervised learning to unsupervised learning, and how those two structures come together to create a recommendation. And yes, as far as I know, it's still some kind of machine learning problem.

Drew Bragg:

For the longest time, if you wanted to do machine learning, you weren't using Ruby, you were pretty much just using Python. But in recent years there's been a bit of an explosion in gems that help out with machine learning. Andrew Kane has a bunch of stuff, and Landon Gray sorry if I got your last name wrong, Landon, I'm so sorry has been doing a lot of AI and machine learning adjacent stuff in Ruby, and so just when you were like, oh, I thought about TensorFlow and then maybe looking in Python. But if anybody has Ruby, I will have to find the gem names that I've seen pop up recently. I have not personally used them, but pretty much anything Andrew Cain puts out is going to be a solid piece of awesomeness. So if he's got machine learning and Ruby gems, you can pretty well bet that they work awesomely. So I will give you those.

Adam Fortuna:

We're using his Disco library, which creates recommendations, which are the ones that are collaborative filtering, just based on the rating. So, yeah, if he has other ones for content filtering, that'd be amazing.

Drew Bragg:

Something in my head is screaming Andrew Cain, so he has so many libraries for content filtering. That'd be amazing.

Adam Fortuna:

Something in my head is screaming Andrew Cain, so I don't know. He has so many libraries I feel like I haven't even touched on half of them.

Drew Bragg:

I've reached out trying to get him on the show just because I'm not convinced he's a human being Like. I am fairly certain he's a cyborg, that his entire purpose in life is just write ridiculously good gems for the public and then disappear into nothingness, because I've never met the man. But he just puts out such high quality stuff and Saccard's very lucky to have him. Andrew, if you happen to listen to the show, please come on because I want to talk to you. You sound interesting, but, adam, you've also been an interesting guest and the whole project is very interesting, and your blog post, which we'll link in the show notes, very clearly says part one is this like an ongoing thing where you're just gonna like as every step of the way, or is there so much more that you've done already that wasn't covered in part one that you have part two come in, or and how many parts do you expect to put out?

Adam Fortuna:

I end up writing really long blog posts and have to try to split them up.

Drew Bragg:

It was great Like there was a lot of awesome content. I almost felt a little like, man, I shouldn't have read this blog post before having you on the show, just to be like, hey, could you just read me your blog post as a podcast episode.

Adam Fortuna:

But yeah, a lot of good information in it it was shared on one of the newsletters I subscribe to and it always has, like the estimated reading time of all the other ones of like four minutes, five minutes, and it gets to this one. It's like half an hour.

Drew Bragg:

That's a reasonable estimation.

Adam Fortuna:

The other parts of the blog post that I split up. I was going to do one just on moving from cloud to the server, from Google and AWS and Heroku to DigitalOcean and Kamal, one for using Puppeteer to generate those open graph images in JavaScript, one for speeding up Rails with solid cache and Sidekick and Brick, and one for securing and speeding up our API server. So quite a few things we already talked about in this one are going to be elaborated on in that blog post.

Drew Bragg:

Yeah, no, those are all great blog posts. I mean especially some of those are not common, just like you said with the puppeteer one generating that. The fact that there isn't a gem, that kind of does it for you, means the next time someone has to run into it. Having a blog post is a great way of helping the community solve the problem, even if it isn't a gem. I refer to so many different blog posts that I've bookmarked and I don't have to memorize this. I can refer back to this blog post or this book, because there's just so much to learn and to do so, other than your blog series almost a book's worth of blog series. What is next for you and your adventures?

Adam Fortuna:

We're working on open sourcing hardcover right now, so we're bringing on some additional members to the team and just cleaning it up so that we can make it public, probably with the same GPL3 license that Mastodon and some other software as a service libraries use. That's going to be the next thing for hardcover. And then, personally, I just started a new job at Librofm, which is also an audiobook company, so I'm able to kind of stay doing fun stuff in the book space, which is fun.

Drew Bragg:

That's awesome. I don't want to take up too much of your time, but if you have the time, what's the motivation on open sourcing hardcover, similarly to the way, like Mastodon's open source? Is it just so that people can have their own instances or do you see people using it in other ways?

Adam Fortuna:

Kind of the main emphasis is that this project's been running for four years. It has 30,000 users, 10,000 active a month. It has a user base, but we're not yet profitable. Costs are basically covering the hosting right now, so it's not like something that can provide like an income for someone working on it. So that means it's a nights and weekends project for the people that are working on it, which means it's going to be very limited just by those few people. My hope is that we've already kind of created this API so we've kind of gotten a bunch of developers that are creating cool stuff with it. Already People are creating plugins so that you can track your reading using like Kobo or like a device and have it automatically update your progress in hardcover. So developers are already kind of working on hardcover. This is kind of giving them a way to contribute even more, especially as I am doing the job thing and won't be able to be spending quite as much time on it.

Drew Bragg:

That makes a lot of sense. That's cool. It's nice when you're able to open source something and get kind of all that extra collaboration from folks. I think that's one of the things that makes Rails so great is you have so many people able to contribute to it. It's not just a small team. Writing everything would slow down progress so much. But because it's open source and people have access to go in and not just report bugs but also fix them and add features and whatnot, I think Rails becomes that much better because of it, and any project that can be open source, I think, benefits greatly from a community. So that's super cool.

Adam Fortuna:

I'm excited about it. I've open sourced libraries, but never like an active website project, so it's going to be a new experience for me too.

Drew Bragg:

Yeah, yeah, is there anything else that you wanted to talk about? Touch on, get out into public. This is a good way of like, hey, if anybody is listening and has solutions to any of the problems that you've already talked about blockers, that you have things that are coming up there's ways of contacting me directly through the show and I can hook you up with Adam, or you'll, at the end, drop, obviously, ways of reaching out and contacting you, but is there anything else that you want to talk about before we get to that?

Adam Fortuna:

I think we've kind of covered a good broad section of stuff.

Drew Bragg:

Yeah, that's been a good episode. So where can people find? You find Hardcover, reach out on the internet.

Adam Fortuna:

You could find Hardcover at hardcoverapp. Find me at adamfortunacom or on bluesky at adamfortunacom. I'm most active on Blue Sky and Hardcover nowadays.

Drew Bragg:

Very cool. I appreciate you spending time to talk about the cool things that you guys are doing. Greatly appreciate the blog post. I'm looking forward to the rest of the series and next time you are working on something cool, feel free to reach out and we'll get you back on the show and we'll talk again about what things you're working on and what cool, new, interesting things you have to share. Sounds good. This has. This has been fun, drew. Yeah, thanks, and audience. I'll talk to you in the next one because I still don't know how to end my own show. Bye, bye.

People on this episode

Podcasts we love

Check out these other fine podcasts recommended by us, not an algorithm.

Remote Ruby Artwork

Remote Ruby

Chris Oliver, Andrew Mason
Ruby for All Artwork

Ruby for All

Andrew Mason & Julie J
IndieRails Artwork

IndieRails

Jess Brown & Jeremy Smith
The Bike Shed Artwork

The Bike Shed

thoughtbot
Code with Jason Artwork

Code with Jason

Jason Swett
The Code Gardener Artwork

The Code Gardener

Alan Ridlehoover & Fito von Zastrow