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)

ยท

9 min read

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 ๐Ÿฅ‚