This article was originally published on my personal blog.
In this blog post, I'd like to describe what are the main technologies / tools I used to create it and why I chose them.
As described in my previous blog post, the project consists of 3 main parts:
- A platform for coaches to create and publish workout programs: a single-page application.
- A platform for the workout programs' landing pages: a server-side rendered application.
- A mobile app to use the workout programs
I'm going to list the most important libraries and tools I used in this project. Just so you know, I didn't have to pay anything for the entire development period (and I think that's pretty amazing).
The community is very strong and a lot of empowering tools have been built for you.
Even though I had to build 3 quite different products (a SPA, a SSR app and mobile app), I was able to leverage stuff from each app and apply it to the others. No need to relearn everything from scratch as soon as the requirements change!
- React for the UI. I could have chosen Vue or Angular, but React was the only modern web UI framework I'd used so far.
- Redux for local state management. In my opinion (and I know it's a moot point), Redux is the go-to state management library when developing complex React apps. In retrospect, I shouldn't have used it in DoNotSkip Programs (because the state isn't complex in that app). Otherwise, I think it's an awesome library that scales very well! If I was to start a new React project with Redux, I would definitely have a look at Redux Toolkit, which seems to reduce the amount of boilerplate code to write.
- Reselect to access the Redux state. Not only can you centralize and test the way you access your state, but you can also compute derived state and memoize the result.
- Redux Typed Saga for side-effects. It's just a library providing Typescript over Redux Saga. I basically had to choose between Redux Saga and Redux Thunk. Redux Saga documentation looked very clear and I liked how the code read (I find it way easier to read asynchronous code than nested callbacks).
- react-18next for internationalization. I actually don't remember why I chose it over react-intl but all I can say is it's very easy to use.
- Apollo Client to perform client-side GraphQL requests. There exists plenty of other libraries, but this is one of the most famous. Furthermore, it supports subscriptions which I knew I would need. I just think I haven't really used it properly because I don't leverage its built-in cache system.
- Authentication: you get OAuth authentication for free (with all major sign-in providers).
- Serverless functions: to me, serverless is the future of backend. Why would I even bother managing my own servers when I can have them managed by experts? You only pay when the functions are up (and they go back to sleep after a while) and they scale automatically as demand grows. Of course, they have drawbacks (such as cold-starts), but the advantages far outweighed them in my case.
- Storage: I didn't really compare it with anything else, since I was already all in on Firebase.
- Google Cloud is the cloud provider I chose. First of all, it's what Firebase uses behind the scene. Secondly, they offer a generous 300€ credit (only for the first year). Finally, after having tested Azure and AWS, I found it way easier to use.
- Hasura here is the official description of the product: "Hasura GraphQL Engine is an opensource product that connects to your databases & services and gives you a realtime GraphQL API, instantly." I won't go into the details in this blog post but what I can already tell you is that it's really awesome. You basically have fine-grained access to your database via an automatically generated GraphQL API.
- PostgreSQL for the database. I didn't really choose this one, since this is the only database compatible with Hasura.
- Heroku to host Hasura engines and PostgreSQL databases. Their free tier is also very generous and you can get up and running in a few minutes.
- Axios as the HTTP clients for both the frontend and the backend. That way, I can use the same syntax everywhere.
- Lerna makes dealing with monorepos easier.
- Husky to launch linting + testing automatically whenever I commit changes to Github.
- GraphQL Code Generator to automatically generate Typescript types for my GraphQL requests.
- Google Analytics for analytics. The free version of Google Analytics provides more than enough insight.
- Sentry for application monitoring and error tracking. I had heard it advertised many times in some of the podcasts I listen to and decided to give it a go.
- Github Actions for CI/CD. Pretty easy to use, integrated with Github and generous free tier.
I needed to use the right tool for the right job. The 3 projects are each of different nature.
- Create React App to set up the project. You get everything configured and you are good to go in no time.
- Material-UI for the UI components and design system. I've always loved the simplicity of Google products and since I'm not good at designing, I thought it would be a wise decision to have strict guidelines and predefined components.
- Next.JS to render server-side pages. It's the go-to framework when it comes to building SSR apps with React. It's also the framework I had the most difficulty getting started with because I didn't immediatly understand the core concepts. A few major releases came out since the first time I used it that have made it easier to get started with.
- App Engine to host the Next.JS app.
- Material-UI for the UI components and design system.
- React Native to build hybrid apps. It was a no-brainer since I already had used React so much.
- Expo to have even more tools and services around React Native.
- NativeBase for the UI components and design system.