Since several people recently asked me to share my ideal React stack, I decided to write it down and share it also with you.
First things first, we developers don't need to be distracted by simple problems and debugging of false positives. That's why I always use Typescript as it is a way to stay sane while writing an app.
Second, we want to have deterministic and easy to use dependency management - this is why I use Yarn. Not only it is super fast, it also has great features like
yarn upgrade-interactive which lets you choose packages you want to upgrade (hint: also use optional flag
Routing: React Router
This is almost a standard for React apps nowadays but I still have to mention it. React Router is great library which provides a simple way to declaratively structure your app and handle static and dynamic routing.
It is also easy to integrate its
Link components with other component libraries like Reactstrap or Material UI.
There are many concepts and libraries to handle styling in a React app: inline styling, linked CSS file, CSS modules, Styled Components, Emotion, etc. I spent almost three days researching which of these libraries would best suit my needs and finally, the answer was: JSS.
What I most love about JSS is its versatility and ease with which I can write and use styles. That's probably why Material UI chose to use it too.
Styles can either be compiled in the browser or in Node.js at build time. These styles are not tied to a particular component, but are just classes which makes them really reusable. JSS also comes with theming support and many plugins to make styling more convenient.
And for those using Typescript: your experience with styling will be a pleasure with JSS.
Honorable mention #1: clsx
To concatenate classNames, use clsx - it is faster and smaller than
When it comes to i18n in React apps, it mainly boils down to two main competitors:
react-i18next. I chose the latter for a variety of reasons.
First of all: react-i18next has great documentation and is very simple to use. It has support for namespacing so your translations can be separated for better maintenance. It has support for lazy-loading which means your app can download only translations it needs right now (and you can deploy translation independently of your app).
And last but not least: the team makes a huge effort to stay up-to-date with latest React features which is why it already has React hooks support.
DateTime manipulation: Luxon
Ah, the accursed DateTime manipulation. I always preferred
date-fns but now I have new favorite which is
luxon, made by one of the people behind
For me, the main benefits of Luxon are:
- immutability and thus predictability
- build-in i18n support
- great documentation => easy to use
It also comes with support for Duration and Intervals.
Honorable mention #2: Lodash
When talking about utility libraries, we can't forget about Lodash. This library makes it very easy to work with data structures, Objects and Arrays in the sane manner.
API communication: Axios, Superagent
The world has been much nicer since the invention of Fetch API. We no longer need to make AJAX calls with jQuery. But still - who wants to remember how to create a JSON POST request with native Fetch? And who wants to write their own API wrapper? That's so 2014...
This is why there are libraries like Axios or Superagent that make API communication easier for us. They're both universal (work in browser and Node.js), they both use Promises because they're based on Fetch API and they're convenient and easy to use even for more robust use-cases.
State management: MobX
Don't get me wrong - Redux is great for storing data in large-scale apps where global state is a must. Its predictability makes it perfect for managing all possible states the app can have and the ability to replay these states is incredible. That said, writing so much of the boilerplate code for state management can be a bit exhausting (and an overkill) for small/medium-sized app.
This is where MobX comes in handy. It is easy to use, scalable state management library that does all the hard work for you. It is based on the Observer pattern which basically means that when you change a state value via MobX action (which is just a decorated function), your connected components automatically update.
That's what I call easy peasy.
Forms and how to handle them properly. What a big topic of React discussions.
For me, Formik found the perfect balance between being "the tool that does everything for you" and "the library that doesn't strap your hands".
It's really versatile - it handles form state, validation, errors, loading and submission and lets you decide if you use its components or write your own.
Thankfully, Formik didn't try to come up with its own validation engine and you can choose whatever you want. On the other hand, it comes with support for Yup validation library which is very convenient.
I also decided to share a couple of online tools I use to search for and work with these libraries:
- npms.io - fast and reliable search engine for node modules which includes great algorithm to score libraries
- DevDocs - imagine all libraries would have documentation in one place, perfectly searchable, available offline. Well that's what DevDocs it trying to achieve and is doing great.
- TypeSearch - for anyone who wants to use Typescript, this is a must. Search for available Typescript definitions for existing libraries.
I hope you enjoyed reading my list of tools. Do you have any favorite library which you can recommend? Leave a comment and let's talk.