One of the most asked questions from new or junior developers is "what technologies should I learn?"
From the beginning of my career in tech, I haven't really had a huge choice regarding which technologies to learn. In my first professional role as a frontend developer, I used what I knew, namely HTML, SASS and jQuery. There was no scope for using a framework like React (they don't integrate well with the Typo3 CMS), and I wasn't even allowed to use Bootstrap or a CSS framework for the same reason.
Once I moved onto full-stack development, I had no choice but to adopt the tech of the company I was working at. This was React on the frontend and Ruby on Rails for the backend. Given this start, I haven't really deviated much. Some of my roles have focussed more on one than the other, and occasionally I've had the chance to add Node.js on the backend and more niche languages like Elixir to the mix, but sticking with Ruby and React has served me well.
Rails is hands-down the most common Ruby framework, and I've stuck with it for the simple reason that it's easy to use and it's what I'm most comfortable with. Sometimes, I don't use any framework at all, like when I was building AWS Lambda functions for holoride, but typically Rails allows me to start a project at lightning speed, and comes with lots of CLI tools to quickly build out the most standard and boilerplate parts of the codebase. Rails also has a gem that allows for using React components inside a full-stack Rails application, meaning you don't even need a separate frontend and backend if that's what suits the project.
However, most of the time these days, my frontend framework of choice is Next.js. Next takes React to the next level, doubling down on features like static rendering (where the pages are converted to HTML at build time) and server-side rendering (where the pages are converted to HTML at run time when the request is made), which has huge implications in terms of performance and SEO. Discussing this could be its own post, but let's just say that the benefits of Next are abundant and make it a clear favourite for me.
In the past, Heroku was my clear winner when it came to deploying applications quickly and easily. It's a very developer-friendly tool and once you get the hang of it, it's a lovely experience. However, since they axed their free tier in 2022, it has fallen out of favour with many developers, myself included, so now I'm reaching for slightly more obscure options. There are a bunch of options out there, up to and including the free tier that AWS provides, but I don't find this a very practical tool for side projects. For API deployment, my recent go-to has been fly.io, it comes with some fantastic CLI features and boasts a pretty decent free tier. It's a great choice for getting started with a side project.
On the frontend side there is only one option for me. When using Next as the framework, Vercel is by far and a way the obvious choice. With a free tier and very easy-to-use interface, it takes a matter of minutes to deploy a Next application and even provides free preview environments for the new features you're building if you simply open up a GitHub Pull Request.
When it comes to adding styles to a frontend project, there are lots of options available. Tailwind CSS has become a leader in the whole frontend community, with 67k stars on GitHub. However, it never really seemed like a great option for me, and I had a hard time moving away from styled-components. I haven't yet come across a use case that styled-components doesn't handle. You can build simple and complex components in the same way, nesting is easy, and extensibility is a core feature that allows you to build complex components on top of simpler ones. Passing in props to have dynamically styled components gives another layer of functionality that I simply haven't found in other tools, so for me, it's the best option.
Sometimes it can be a bit difficult to arrange the components in a React app, and adding styled-components doesn't help this at times, but overall it's a worthwhile trade-off if you can find a system that works for you.
For making API calls, which most applications do, I like to set up a system using
react-query, which essentially just provides a thin wrapper around
react-query that abstracts away things like the base URL of the request and any authentication that I've set up so that the calling code just needs the path to the resource and a key under which to cache the results, and that's pretty much it. This way makes it quite clean to make queries to the API, although creating/updating/deleting data is still a bit more involved.
Forms are another major component of most applications, and for this I use
react-hook-form. I used to be a great fan of
formik and even though I'd still consider it, I got used to using
react-hook-form while working with some very intelligent colleagues at holoride, so I stuck with it as a way to simplify forms on the frontend.
On the backend, there are many gems that I like in the Ruby ecosystem, such as
active_model_serializers, which gives you the ability to unify the shape of the data that you're returning from your API, modifying and compunding data to suit your use case and removing unnecessary fields like timestamps or metadata that the client doesn't need. This only really makes sense when building an API, since building a full-stack Rails app typically requires no serialisation.
Devise is a common authentication gem and it's now my go-to for all my authentication requirements. However, for token management, I have a difficult time choosing between
devise-jwt is better suited to an omniauth implementation where you want social logins and
devise_token_auth is more for typical username-password authentication. I haven't yet built an API that caters for both, so I'm not sure which I would use for that case.
Active Admin is another standard in the Rails community for easily building out a simple admin interface. The UI/UX requirements for admin interfaces are usually a lot simpler than for the user-facing screens, so the simple but intuitive design fits the bill perfectly in my view.
When it comes to testing Rails apps, RSpec is a great option. Combined with some small gems like
factory_bot, testing becomes simple and easy, which allows for fast development with TDD.
For full-stack Rails app, Capybara is a useful tool for testing user flows and is easier to set up than something like Cypress, which runs your application in a headless browser and interacts with your application and makes assertions on changes or outcomes. Capybara can also be used for TDD, although I find it to be a little more cumbersome.
For testing frontend applications,
testing-library make a great team, allowing you to test user behaviour in React components. These tools are also perfect for TDD, although I'm yet to find a good way to visualky test screens/components that would fail if, for example, simple CSS properties like font colour or background colour were changed. I often think it would be a good open source project to create or discover online and contribute towards. Cypress goes some way to providing this sort of testing, making sure that elements are visible and, for example, clickable, in order to pass the tests. Doing end-to-end testing with Cypress is a great way to add confidence to the development of an application, although it's not very often given the attention it deserves and can become an afterthought for many projects that I've been a part of.