Building my first PWA with Next.js, ChakraUI, Typescript, Firebase, and Web Workers (Intro: The good, the bad, and the ugly)

Building my first PWA with Next.js, ChakraUI, Typescript, Firebase, and Web Workers (Intro: The good, the bad, and the ugly)

It was January 15, 2021.

I was scrolling on Hashnode when I stumbled upon this article: Announcing Hashnode Hackathon Powered by Vercel.

I never participated in a hackathon before, but I thought to myself: "How hard could it be?". I used NextJs + Vercel for this blog, and it could be a fun learning experience. Plus, I long wanted an app to track my higher-level goals and the actions I take towards them. So here we go πŸ’ͺ🏾.

Three weeks later..., the hackathon closed, and I wasn't even close to done πŸ˜….

I don't know if it is because of my inexperience or my propensity to complicate things, but I made many mistakes in the process. At the same time, I learned a ton about NextJS, Firebase, server-side-rendering, etc. That is why I decided to start this series to share my learnings with you.

PS: I am still building the app, and you can track my progress on Github.

Part I: Designing the app

This part was straightforward: I use AdobeXD (which is free), and I collected ideas from Dribbble. You can see the mocks further.

The good βœ…

I shared the mocks on Twitter, and so far, this is my most successful tweet with > 250 reactions. Plus, I could gauge people's interest.

The bad 🀯

I am not a designer, so I had to spend some time picking up colors, fonts, designing mocks, etc.

The ugly ❌

I spent 20h doing the mocks => I could have spent this time building the app πŸ˜….

original mocks light original mocks dark

Part II: Choosing a tech stack

This part wasn't the easiest, and I made some (costly) mistakes with my early decisions (looking at you AWS 🀏🏾). These are the libraries that I finally choose:

TypeScript

typescript.png

The good βœ…

Adding Typescript to your JS project is like adding your dating type in your dating profile πŸ˜‰. Other people know what you expect, and you will get suggestions for the types you mentioned. Similarly, when you use Typescript, the other developers know what parameters a function expects, the type of a variable, etc. IDEs (like VSCode) can flag you when you're using the wrong type, give you suggestions, etc.

PS: If you want to get started with Typescript, check this guide.

The bad 🀯

Similar to how setting up expectations in a dating app is great, it also limits the pool of people you can date. Plus, you have to stay consistent. Typescript is the same; once you start using it, you have to respect the types and specify a type for everything: which can get laborious.

The ugly ❌

  • I realized that my project is slower to build/rebuild when using Typescript vs. pure JS.
  • I ended up using the any type in a couple of cases; this defeats the purpose of using Typescript (read more here)

NextJS

nextjs.png

The good βœ…

I discovered NextJS last year: I used it to create this blog, and it was a great experience πŸ™‚. It helps you set up an optimized React project with server-side rendering and no initial setup. Plus, the community is excellent, and the company keeps improving the product.

The bad 🀯

I didn't know NextJS well enough πŸ˜…. True, I could build a blog, but I wasn't solid on the fundamentals: I didn't even know what server-side rendering implied. Nor did I know :

  • The difference between getStaticProps, getServerSideProps,...
  • How the pages API worked
  • Etc.

The ugly ❌

Nothing to report πŸ˜€

ChakraUI

chakra.png

The good βœ…

I discovered Chakra through leerob's blog, and I am in love ❀️ with it since then. As a React developer, it is the quickest way to build beautiful (but accessible) UIs.

The bad 🀯

My app would work in dev mode but not in prod. After hours of debugging, I discovered that some Chakra components don't work with Preact + NextJS (issue). In fact, for performance reasons, I use Preact instead of React in production mode. I had to decide between redesigning the components or dropping Preact: I choose to redesign, which takes time.

The ugly ❌

  • Chakra is a JS library, and unfortunately, JS is more expansive than CSS. If I were using CSS only or TailwindCSS, my app would be more performant, but it would take me more time.
  • It loads some unnecessary JS like some framer-motion JS; this affects the Lighthouse score πŸ˜₯.

Firebase

firebase.png

I didn't start with Firebase (alternatives here) because I didn't find it very novel => I should have πŸ€¦πŸΎβ€β™€οΈ.

The good βœ…

  • There is a ton of documentation around Firebase.
  • You don't have any config or decision to make (i.e., which machine to use, how many cores, etc.).
  • You can start for free.
  • It is "easy" to set up authentication/authorization.

The bad 🀯

Like for NextJS, I have basic knowledge of Firebase, so I have to learn along the way => which takes time.

The ugly ❌

Firebase increases your JS bundles (i.e., the user has to download more JS to use your app) => this is why I use web workers.

Web Workers

The good βœ…

  • I always wanted to learn about web workers. This is the first time I use them: exciting πŸ₯³.
  • The web workers' script loads lazily, which is excellent for perf.
  • I can use my main thread only for UI (i.e., Chakra, charts, etc.)

The bad 🀯

  • If you've read through this, you likely noticed that I picked technologies I am not familiar with πŸ˜…. I am also not familiar with Web workers: so I can't count the time I spent debugging issues.
  • Using Web workers adds complexity to the code.

The ugly ❌

  • Web workers can't access the DOM and have limited access to the window object's methods. Thus I had to find a workaround for Google, Twitter, or Github Firebase authentication. Methods like signInWithPopup, signInWithRedirect don't work with web workers.
  • Any object shared between a web worker, and the main thread must work with the structured clone algorithm.

Where I am at right now

I finally made the authentication work with Firebase + web workers πŸŽ‰. As a next step, I will let the user choose a username + create categories/goals. In parallel, I bought a fireship.io subscription to learn the best way to model data on Firebase πŸ™‚.

Conclusion

If you liked this article and want to see the code, find it here => https://github.com/Joyancefa/goalswin.
You can also access the (work in progress) app here => http://goalswin.app/ .
Don't hesitate to reach out on Hashnode or Twitter if you have any questions.
Cheers πŸ₯‚