My Journey Creating My First Solo Project (part 2): Technologies and tools

Introduction

In my previous blog post, I described the motivations behind building DoNotSkip, what problems it would try to solve and the big picture of how I would go about building it.

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.

Main parts

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

Technologies / tools

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).

Common

Most of the technologies and tools are common to the three main parts of the platform, and that's one of the reasons JavaScript is so awesome!

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!

Front-end

  • Typescript as the programming language. I actually got started with JavaScript, but I soon realized it didn't scale well (more on that in another blog post). I do not regret migrating to Typescript whatsoever.
  • 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.
  • Immer makes updating states in Redux reducers way easier than in plain JavaScript. I started out with plain JavaScript and felt the code of my reducers was becoming too difficult to read.

Back-end

  • Typescript as the programming language. Like I said before, I started out with JavaScript but didn't like where my codebase was going.
  • Node.JS as the backend framework. Very popular backend framework in the web development world since the programming language is JavaScript. Deno might be its replacement, but not anytime soon.
  • Firebase for:
    • 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.

Miscellaneous

  • Axios as the HTTP clients for both the frontend and the backend. That way, I can use the same syntax everywhere.
  • Yup to parse and validate JavaScript objects.
  • Jest for unit-testing. I picked up this framework because it was the only one I was familiar with in the JavaScript ecosystem.
  • Github.
  • 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.

Project-specific

I needed to use the right tool for the right job. The 3 projects are each of different nature.

DoNotSkip Coaches

  • 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.

DoNotSkip Programs

  • 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.

DoNotSkip App

  • 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.

DoNotSkip Landing Page

  • Gatsby to create static pages with React.
  • Material-UI for the UI components and design system.

Conclusion

As you can see, I've used a lot of third-party libraries in order to build DoNotSkip (and I didn't mention all of them...). It's pretty common to do that in the JavaScript ecosystem instead of reinventing the wheel. When picking a library, I just made sure it was still maintained.

Now that you know the tech stack I used, I'm going to describe the cloud architecture of DoNotSkip in the next blog post.

Arnaud Cortisse © 2024