I picked Ruby on Rails over React-based SPA to build Reviewbunny and it was wonderful. I didn’t procrastinate determining the perfect setup or choosing dependencies. Instead, I procrastinated after having finished the MVP. I’d rather do the latter!
npm, Yarn 1 or 2 (yes, they’re completely different), pnpm or Snowpack?
Next.js, Remix, Gatsby, Vite, Create React App, Koa or Express?
Set up TypeScript, Prettier, linter and test framework.
There are no conventions on this. Every company or project has their own. Or doesn’t.
Today’s frameworks have rules on how to create pages, which is great. But I’m on my own where to place everything else.
SQL databases, MongoDB, Firebase, Fauna, Cloudflare Durable Objects or Planetscale?
Serverless platforms can spawn many instances of my app, so I need connection pools in front of a SQL database to avoid making thousands of connections. MongoDB and Firebase are too flexible, because there’s no schema. I got bitten by that before. SaaS offerings cost more and there are additional steps to set up a local environment.
Oh, and database migrations? Start looking for another package to do that for you or attempt to do it yourself.
GraphQL or REST? Apollo, SWR, react-query, Relay or fetch?
Remix’s approach is the one I’m looking forward to the most. It tells me exactly how to fetch the data.
Passport, Auth0, Firebase or something custom?
Either way, I’ll also need to design and code “log in”, “sign up”, “forgot password” and “reset password” pages. They’re not fun to work on.
Reviewbunny has background jobs for ingesting data from GitHub. I’d need to pick a queue library, set up Redis and create another entrypoint to process these jobs.
Serverless environments are not designed to have long-running processes. Now I have to deploy my app elsewhere, like Render or Heroku.
After background jobs, I need to find and set up the library for sending emails. Then, pair it with a template library to render the emails themselves.
Reviewbunny has a page where progress of a background job is streamed via Websockets.
As far as I know, serverless platforms don’t support Websockets, so I’d probably lean into using a SaaS like Pusher, which isn’t cheap.
If you got bored reading this, imagine having to do all of this whenever you start a new project.
Compare this to Rails:
- Package manager — Bundler.
- Framework — Ruby on Rails.
- Tooling — Sorbet (type checker, doesn’t even require transpiling), Prettier, Rubocop (linter), Minitest (built-in test framework).
- Project structure — Follow the Rails conventions.
- Data storage — Active Record with support for SQLite, MySQL and PostgreSQL by default. Database migrations are baked in too.
- Data fetching — Happens on the server, talking directly to the database.
- Authentication — Devise + Omniauth for OAuth. Log in, sign up and other pages are provided for you.
- Background jobs — Action Job. Integrates with all popular libraries, like Sidekiq or Resque, in one line of code.
- Email delivery - Action Mailer.
- Real-time updates - Action Cable + Turbo.
See the difference? All the answers to common problems any app might have are there.
As soon as I run
rails new, I’ve got all of that. Things like controllers, models, migrations, views, mailers, background jobs can even be auto-generated via
rails generate. It’s magical to run
rails generate migration AddEmailToUsers email:string and watch it generate a database migration to add an
So where I’m going with this…
- More strong opinions and conventions to relieve us from making unnecessary choices.
- Less configuration and manual labor to start working on anything.
When I think about these principles, XO and Parcel come to mind. They’re configurable and very flexible. However, I don’t have to do anything to start using them, because their authors made sure to pre-configure them with the best choices based on community feedback.