JavaScript is hard: here are some of my go-to packages
Tags: javascript, webdev
Published: 2022-06-06 00:37:27

I've been programming for a little while now. I'm not the best, I don't have much formal training, but my code runs and it does the job :)

I started out programming in Java. Then dabbled in python. Then did PHP for a couple of years. And finally committed to the JavaScript game back in 2015.

JavaScript is so versatile and so overloaded that it can be hard to find your way. And once you do get your bearings you can build pretty much anything. We've all read (or at least seen the titles) of articles bashing JavaScript or praising it. This isn't one of those. This is more for documenting which packages I always end up going back to, partly for myself since I forget, and partly for everyone else.

## Table of contents

- **[Isomorphic utilities](#isomorphic-utilities)** – fancy words for "it works everywhere"
- **[Servers](#servers)** – someone else's computer that usually does database work
- **[Databases](#databases)** - the thing that stores your data
- **[Frontend](#frontend)** – your user's computer that displays data and talks to servers
- **[Scraping](#scraping)** – grabbing data from a website when they don't give you an API
- **[Email](#email)** – most people won't care about this but I spent a lot of my time in here

## Isomorphic utilities

| Category         | Name                                                             | Creator                                           | Description                                                                                                                                                                                                                  |
| ---------------- | ---------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Generic utilties | [lodash](https://lodash.com/)                                    | [John-David Dalton](https://twitter.com/jdalton)  | A utility library with a ton of useful functions for manipulating strings, objects, arrays, and basically anything else. I don't think I've ever made a project without it. Oh, and it's the most depended upon NPM package. |
| Debugging        | [debug](https://www.npmjs.com/package/debug)                     | [Debug.js](https://github.com/debug-js)           | A debugging library. Add logs. Filter them out. Colors for easy visual parsing. Another top 10 package.                                                                                                                      |
| Data fetching    | [axios](https://www.npmjs.com/package/axios)                     | [Axios](https://github.com/axios)                 | A super comprehensive library for making HTTP requests. Works in the browser and node.js. Another one that is in almost all of my projects.                                                                                  |
| Data validation  | [yup](https://www.npmjs.com/package/yup)                         | [Jason Quense](https://twitter.com/monasticpanic) | My favorite way to validate an object. It can be as simple or complex as you need. Super portable. Casts values. I use it to validate API requests and form values in formik.                                                |
| ID generation    | [uuid](https://www.npmjs.com/package/uuid)                       | [UUID](https://github.com/uuidjs)                 | Generates universally unique identifiers (UUIDs). I love UUIDs for IDs of things that aren't user facing. Better than sequential IDs.                                                                                        |
| ID generation    | [nanoid](https://www.npmjs.com/package/nanoid)                   | [Andrey Sitnik](https://twitter.com/sitnikcode)   | Generates unique identifiers. I like it for when UUIDs are too long. Think YouTube video IDs.                                                                                                                                |
| ID generation    | [slugify](https://www.npmjs.com/package/slugify)                 | [Simeon Velichkov](https://twitter.com/_simov)    | Takes a string and returns a "slugified" version. i.e. "Hello World" becomes "hello-world". Great for IDs that don't need to be globally unique or need to be memorable to the user.                                         |
| Dates            | [date-fns](https://www.npmjs.com/package/date-fns)               | [date-fns](https://github.com/date-fns)           | You can't go without this one. If you need to deal with dates, this is the tool for you. Formatting, math, comparing, sorting, filtering – it does it all.                                                                   |
| Promises         | [delay](https://www.npmjs.com/package/delay)                     | [Sindre Sorhus](https://twitter.com/sindresorhus) | Sleep for some time. Great for testing delays or for writing flaky code ;)                                                                                                                                                   |
| Promises         | [p-map](https://www.npmjs.com/package/p-map)                     | [Sindre Sorhus](https://twitter.com/sindresorhus) | Maps an array into promises.                                                                                                                                                                                                 |
| Promises         | [p-timeout](https://www.npmjs.com/package/p-timeout)             | [Sindre Sorhus](https://twitter.com/sindresorhus) | Timeout a promise after some time.                                                                                                                                                                                           |
| Promises         | [p-retry](https://www.npmjs.com/package/p-retry)                 | [Sindre Sorhus](https://twitter.com/sindresorhus) | Retries an async function on failure.                                                                                                                                                                                        |
| Promises         | [p-cancelable](https://www.npmjs.com/package/p-cancelable)       | [Sindre Sorhus](https://twitter.com/sindresorhus) | For creating promises you might want to cancel before they complete.                                                                                                                                                         |
| Promises         | [p-progress](https://www.npmjs.com/package/p-progress)           | [Sindre Sorhus](https://twitter.com/sindresorhus) | For creating promises you want to report progress as the work is done.                                                                                                                                                       |
| Promises         | [p-any](https://www.npmjs.com/package/p-any)                     | [Sindre Sorhus](https://twitter.com/sindresorhus) | Resolve after any of the promises finish.                                                                                                                                                                                    |
| Promises         | [p-some](https://www.npmjs.com/package/p-some)                   | [Sindre Sorhus](https://twitter.com/sindresorhus) | Resolve when a specific number of promises finish.                                                                                                                                                                           |
| Promises         | [p-all](https://www.npmjs.com/package/p-all)                     | [Sindre Sorhus](https://twitter.com/sindresorhus) | Resolve when all the promises finish.                                                                                                                                                                                        |
| URLs             | [is-absolute-url](https://www.npmjs.com/package/is-absolute-url) | [Sindre Sorhus](https://twitter.com/sindresorhus) | Checks if a string is an absolute URL.                                                                                                                                                                                       |
| URLs             | [is-relative-url](https://www.npmjs.com/package/is-relative-url) | [Sindre Sorhus](https://twitter.com/sindresorhus) | Checks if a string is a relative URL.                                                                                                                                                                                        |

## Servers

| Category   | Name                                                         | Creator                              | Description                                                                                                 |
| ---------- | ------------------------------------------------------------ | ------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| Server     | [Express](https://expressjs.com/)                            | [Express.js](https://expressjs.com/) | The industry standard for running a node server. If you don't have a strong opinion about a tool, use this. |
| Middleware | [body-parser](https://www.npmjs.com/package/body-parser)     | [Express.js](https://expressjs.com/) | A must have middleware for parsing the body.                                                                |
| Middleware | [cookie-parser](https://www.npmjs.com/package/cookie-parser) | [Express.js](https://expressjs.com/) | A must have middleware for parsing cookies.                                                                 |
| Middleware | [helmet](https://www.npmjs.com/package/helmet)               | [Express.js](https://expressjs.com/) | A must have middleware for securing your server.                                                            |
| Middleware | [cors](https://www.npmjs.com/package/cors)                   | [Express.js](https://expressjs.com/) | A must have middleware for setting good cors headers.                                                       |
| Middleware | [express-ws](https://www.npmjs.com/package/express-ws)       | [Express.js](https://expressjs.com/) | A middleware for setting up web socket things. Not a must have ;)                                           |

## Databases

I almost always reach for PostgreSQL. I've been using it for years, and it's been a great tool. If I need something real-time I use Firebase. If I need something for caching or queuing I use Redis.

| Category           | Name                                                   | Creator                                       | Description                                                            |
| ------------------ | ------------------------------------------------------ | --------------------------------------------- | ---------------------------------------------------------------------- |
| Database connector | [pg-promise](https://www.npmjs.com/package/pg-promise) | [Vitaly Tomilov](https://github.com/vitaly-t) | An promise library for PostgreSQL. Low level and lovely.               |
| Database connector | [ioredis](https://www.npmjs.com/package/ioredis)       | [Zihua Li](https://twitter.com/luinlee)       | A client for Redis. No real opinions. Which is a good sign in-itself.  |
| ORM                | [prisma](https://www.npmjs.com/package/prisma)         | [Prisma](https://www.prisma.io/)              | An ORM with migrations and type-safety. My go-to for any new projects. |
| Queues             | [bullmq](https://www.npmjs.com/package/bullmq)         | [TaskForce](https://taskforce.sh)             | My favorite way to build queues.                                       |

## Frontend

| Category      | Name                                                                                     | Creator                                                            | Description                                                                                                           |
| ------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| Framework     | [React](https://reactjs.org)                                                             | [React](https://reactjs.org/)                                      | A JS library for building user interfaces.                                                                            |
| Metaframework | [Next.js](https://nextjs.org)                                                            | [Vercel](https://vercel.com/)                                      | A React Framework - I wouldn't use React without something like this.                                                 |
| Styling       | [styled-components](https://styled-components.com/)                                      | [styled-components](https://github.com/styled-components)          | A CSS library for React. Only for when I want 100% control.                                                           |
| Styling       | [tailwindcss](https://tailwindcss.com/)                                                  | [Tailwind Labs](https://twitter.com/tailwindcss)                   | The utility-first CSS framework. When I don't care about 100% control, I use Tailwind.                                |
| Data fetching | [SWR](https://swr.vercel.app/)                                                           | [Vercel](https://vercel.com/)                                      | The best way to fetch data in React (that I know of)                                                                  |
| Forms         | [Formik](https://formik.org/)                                                            | [Jared Palmer](https://twitter.com/jaredpalmer)                    | The best way to build forms in React (that I know of)                                                                 |
| Utilities     | [clipboard-copy](https://www.npmjs.com/package/clipboard-copy)                           | [Feross Aboukhadijeh](https://twitter.com/feross)                  | Copies something to the user's clipboard. That's it.                                                                  |
| Utilities     | [file-saver](https://www.npmjs.com/package/file-saver)                                   | [Eli Grey](https://twitter.com/sephr)                              | Makes it super easy to save files to the user's computer.                                                             |
| Utilities     | [react-outside-click-handler](https://www.npmjs.com/package/react-outside-click-handler) | [AirBnb](https://airbnb.io/)                                       | "When the user clicks outside this element, do XYZ"                                                                   |
| Utilities     | [@reach/auto-id](https://reach.tech/auto-id)                                             | [Reach - the accessible foundation for React](https://reach.tech/) | Auto generate IDs. Useful for connecting labels and inputs without needing to manually set the id.                    |
| Utilities     | [@reach/rect](https://reach.tech/rect/)                                                  | [Reach - the accessible foundation for React](https://reach.tech/) | React hook and higher order component to get the exact size of the DOM element.                                       |
| Utilities     | [react-intersection-observer](https://www.npmjs.com/package/react-intersection-observer) | [Daniel Schmidt](https://twitter.com/teh_builder)                  | Track when a DOM element enters the viewport. "When the user scrolls to this element, do XYZ".                        |
| Utilities     | [react-focus-lock](https://www.npmjs.com/package/react-focus-lock)                       | [Anton Korzunov](https://twitter.com/theKashey)                    | "Don't let the user leave this element"                                                                               |
| Utilities     | [react-error-boundary](https://www.npmjs.com/package/react-error-boundary)               | [Brian Vaughn](https://twitter.com/brian_d_vaughn)                 | "When something breaks, display XYZ"                                                                                  |
| Components    | [Reach UI](https://reach.tech/)                                                          | [Reach - the accessible foundation for React](https://reach.tech/) | A ton of accessible React components I turn to all of the team                                                        |
| Components    | [dnd kit](https://dndkit.com/)                                                           | [Claudéric Demers](https://twitter.com/clauderic_d)                | Wanna make sortable lists, drag and drop builders, or anything else that the user can move? This is the tool for you. |
| Components    | [downshift](https://github.com/downshift-js/downshift)                                   | [Kent C. Dodds](https://twitter.com/kentcdodds)                    | Accessible comboboxes.                                                                                                |
| Components    | [react-toastify](https://fkhadra.github.io/react-toastify)                               | [Fadi Khadra](https://twitter.com/fadi_khadra)                     | Easy way to show toast notifications (Those notifications that pop up in the corner.)                                 |
| Components    | [react-contexify](https://fkhadra.github.io/react-contexify/)                            | [Fadi Khadra](https://twitter.com/fadi_khadra)                     | Easy scalable way to add context menus. (What you get when you right click.)                                          |
| Components    | [Split.js](https://split.js.org/)                                                        | [Nathan Cahill](https://twitter.com/nathancahill)                  | Super flexible utilities for resizable panes.                                                                         |
| Components    | [kbar](https://kbar.vercel.app/docs)                                                     | [Tim Chang](https://twitter.com/timcchang)                         | A customizable command palette.                                                                                       |
| Components    | [react-monaco-editor](https://github.com/react-monaco-editor/react-monaco-editor)        | [react-monaco-editor](https://github.com/react-monaco-editor)      | A nice React wrapper around [Monaco Editor](https://microsoft.github.io/monaco-editor/)                               |
| Components    | [react-chartjs-2](https://react-chartjs-2.js.org/)                                       | [reactchartjs](https://github.com/reactchartjs)                    | A nice React wrapper around chart.js                                                                                  |

## Scraping

| Category                      | Name                                                     | Creator                                   | Description                                                                                                                          |
| ----------------------------- | -------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| Headless browser              | [Playwright](https://playwright.dev/)                    | [Microsoft](https://github.com/Microsoft) | A headless browser for testing and prototyping. Supports all major browsers and has great utils for waiting for the DOM to be ready. |
| Extraction                    | [Metascraper](https://www.npmjs.com/package/metascraper) | [microlink.io](https://microlink.io/)     | A library for extracting metadata from web pages.                                                                                    |
| Extraction                    | [html-get](https://www.npmjs.com/package/html-get)       | [microlink.io](https://microlink.io/)     | A library for getting the HTML from any webpage, even if it uses JavaScript for rendering.                                           |
| DOM navigation / manipulation | [cheerio](https://www.npmjs.com/package/cheerio)         | [Cheerio](https://github.com/cheeriojs)   | A jQuery-like library for navigating and manipulating the DOM. Couldn't live without it.                                             |

## Email

Ok so I work in email. I spent a lot of time thinking about email creation, validation, testing, etc. This section probably won't be interesting to most folks but I figured I'd add it anyways.

### Email address validation

| Category      | Name                                                                                   | Creator                                               | Description                                                                                                          |
| ------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Domains       | [disposable-email-domains](https://www.npmjs.com/package/disposable-email-domains)     | [Ilya Volodarsky](https://twitter.com/ivolo)          | A list of domains associated with disposable email services. You'll never catch em all but this is pretty damn good. |
| Domains       | [free-email-domains](https://www.npmjs.com/package/free-email-domains)                 | [Kiko Beats](https://twitter.com/Kikobeats)           | A list of domains associated with free email providers.                                                              |
| Domains       | [email-providers](https://www.npmjs.com/package/email-providers)                       | [Jannis R](https://twitter.com/derhuerst)             | A list of domains associated with email providers.                                                                   |
| Localparts    | [role-based-email-addresses](https://www.npmjs.com/package/role-based-email-addresses) | [Mixmax](https://www.mixmax.com/)                     | A list of localparts (the part before the `@` sign) that refer to a role and not a person (i.e. "sales" or "admin")  |
| Email address | [email-misspelled](https://www.npmjs.com/package/email-misspelled)                     | [Julien Amblard](https://github.com/sl-julienamblard) | A library that will suggest an correction if the given email address probably has a typo.                            |
| Email address | [email-addresses](https://www.npmjs.com/package/email-addresses)                       | [Jack Bearheart](https://github.com/jackbearheart)    | A library for validating email addresses.                                                                            |

### String / HTML / CSS manipulation

I a email creation platform and it requires a fair bit of DOM and string manipulation.

| Category                       | Name                                                                         | Creator                                             | Description                                                                                                                           |
| ------------------------------ | ---------------------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | --- |
| Email parser                   | [mailparser](https://www.npmjs.com/package/mailparser)                       | [Node Mailer](https://nodemailer.com/about/)        | A library for parsing emails. I'm a fan but it's a bit heavy compared with letterparser and is node.js only.                          |
| Email parser                   | [letterparser](https://www.npmjs.com/package/letterparser)                   | [Mat Sz](https://twitter.com/matsz_dev)             | A full isomorphic library for parsing emails. Oh and it has AMP support which is a big plus. My go-to now-a-days.                     |
| CSS inliner                    | [juice](https://www.npmjs.com/package/juice)                                 | [Automattic](https://automattic.com/)               | The industry standard CSS inliner. It's hard to beat.                                                                                 |     |
| CSS navigation / manipulation  | [postcss](https://www.npmjs.com/package/postcss)                             | [PostCSS](https://postcss.org/)                     | A library for transforming CSS. Super powerful but a bit too dependent on perfect code for my liking.                                 |
| HTML navigation / manipulation | [Cheerio](https://www.npmjs.com/package/cheerio)                             | [Cheerio](https://github.com/cheeriojs)             | A jQuery-like library for navigating and manipulating the DOM. Couldn't live without it.                                              |
| HTML navigation                | [simple-html-tokenizer](https://www.npmjs.com/package/simple-html-tokenizer) | [Tilde](https://www.tilde.io/)                      | A library for tokenizing HTML. I use it for finding the source information for HTML attributes.                                       |
| HTML manipulation              | [sanitize-html](https://www.npmjs.com/package/sanitize-html)                 | [Apostrophe CMS](https://apostrophecms.com/)        | A library for sanitizing HTML.                                                                                                        |
| HTML manipulation              | [escape-html](https://www.npmjs.com/package/escape-html)                     | [Component](https://github.com/component)           | A library for escaping HTML.                                                                                                          |
| HTML manipulation              | [html-to-text](https://www.npmjs.com/package/html-to-text)                   | [html-to-text](https://github.com/html-to-text)     | A library for converting HTML to text. Not perfect but a great base to work off of.                                                   |
| HTML information               | [is-self-closing](https://www.npmjs.com/package/is-self-closing)             | [Jon Schlinkert](https://twitter.com/jonschlinkert) | A library for checking if a tag is self-closing.                                                                                      |
| HTML information               | [html-tags](https://www.npmjs.com/package/html-tags)                         | [Sindre Sorhus](https://twitter.com/sindresorhus)   | A list of all HTML tags.                                                                                                              |
| HTML information               | [caniemail](https://www.npmjs.com/package/caniemail)                         | [parcel.io](https://parcel.io)                      | The data powering caniemail.com - the best source of support data for email.                                                          |     |
| String manipulation            | [ranges-apply](https://www.npmjs.com/package/ranges-apply)                   | [Codsen](https://www.codsen.com/)                   | A library for manipulating strings. When you need to do non-parsing HTML/CSS manipulation there is literally no better way than this. |