How to love modern web development

Modern web development seems complicated, but it doesn't have to be

Modern web development in the last few years has garnered serious notoriety for being difficult, confusing and complicated, so much so that that we have even coined terms like Javascript Fatigue to describe it. But is the situation as dire as some would make out?

To be fair it's easy to see why that would appear to be the case, if you look at most job descriptions for Front End development it almost reads as another language, littered with the names of various technologies: "webpack, redux, react, postcss, scss, styled components, emotion, vuejs, css3, gulp, html5, mobx, grunt, mobx-state-tree, less, bootstrap, angular" I could go on, but you get the point.

The web is unique in that we started with a platform built for rendering simple, text based documents on desktop computers and had to go from that to a platform capable of supporting highly sophisticated and interactive applications across an enormous number of different devices and multiple browser targets in a relatively short period of time.

To accomplish this, browsers innovated, web developers innovated and JS, CSS & HTML evolved, but to go from a relatively simple document based platform to full blown application platform there undoubtedly had to be a transition period.

What's come out of this transition period is a vast number of bundlers, frameworks, libraries - abstractions we desperately cobbled together to try and deal with the delta between the capabilities of the platform and the expectations from users and businesses. Inevitably, a lot of these imperfect abstractions still exist and are still used because our software and developers are still playing catch up and have been for years.

I do however think that things are beginning to slow down, it feels -at least to me- as though web development is beginning to converge and mature to a point where there are some technologies you can use today that can actually make modern web development reasonably straight forward and maybe (just maybe!) even an enjoyable experience.

How to approach modern web development in 2019

1. Don't use Webpack, don't use Babel*

Firstly, what is webpack? Webpack is a bundler, you give it your source code and it spits out something that can be run in a browser. The problem with Webpack is for it do anything useful you need to configure it, which isn't rocket science but isn't exactly a walk in the park either - Webpack is powerful and flexible, but for those reasons configuring it can be complicated. If you want to use modern versions of Javascript with features that may not be supported in browsers yet, you need to pair webpack with something like Babel. Already at this point, things are getting needlessly difficult - you now have to learn what Webpack is, what loaders are, and now you have to learn about Babel as well.

The good news is, today, you can avoid this completely and just use Parcel instead.

Parcel touts itself as a "Blazing fast, zero configuration web application bundler", but for all intents and purposes you can think of Parcel as a compiler for the modern web, and one that is really easy to use. You install it via NPM or Yarn npm install -g parcel, create an index.html file and run parcel build index.html to build the project and parcel index.html to serve the project for development purposes.

Out of the box, parcel supports well over a dozen asset types modern Javascript (ES20XX), CSS, SCSS, LESS, TypeScript, HTML, TOML and YAML just to name a few. And the magic of it is, it just works - seriously! You import any of these asset types and it pretty much just works as you would expect.

It really feels like back in the day when web development was a html file with a couple of tags to pull in your JS and CSS - except that now you can leverage as little or as much of the modern web as you like. If you want to just use plain CSS fine, go ahead, if you want to use SCSS instead just import your SCSS file and Parcel will handle it. If you want to use typescript, just import a *.ts file, parcel will read the extension and apply the appropriate transformations automatically with no configuration required.

Is Parcel a Webpack killer?

Yes, and no. I think for 95% of use cases Parcel is more than sufficient, but what you don't have is the ridiculous power and flexibility (the same two things that make it painful to work with) that come with webpack. Webpack has a huge ecosytem built around it with loaders for almost anything you could think of, so there will be some projects where Webpack could be more appropriate though I would argue they would be in the minority.

2. Use React and ditch Redux and Mobx

Let's face it, love it or hate it - React is here to stay. Sure there are some alternatives, Vue, Angular, Ember, but React is king, and it's likely to be around for years to come.

If you are going to learn just one web development technology (other than basic html, css and js) I would recommend React over virtually any thing else. Unless you are just going to be developing very basic websites as opposed to web apps, I would even start with React before learning the native DOM API. Why? working with the DOM directly beyond anything trivial gets messy fast, you're either going end up pulling in some library to make it tolerable or roll out your own adhoc solution - at which point you would have been better off pulling in React anyway.

So erm... why don't I need Redux/Mobx?

Modern React now has hooks, and although they don't make Redux completely obsolete, they do make it less compelling. React comes built in with a useReducer hook and paired with React's context API covers a lot of ground that Redux used to. If you are building a very large / complex app you may want to think about pulling in Redux/Mobx/CerebralJS or some other state management library but vanilla React will probably get you 90% of the way there.

Not required but I like pairing useReducer with Immer

3. Don't use Styled-components, Emotion, SASS, LESS

In terms of styling I've used virtually everything, I've gone from vanilla CSS, to SASS, to CSS modules, to CSS modules with SASS, to Glamorous, to Styled Components to Emotion.

And I ended up going full circle, back to vanilla CSS! And it's awesome! Why? Because thanks to TailwindCSS, I'm not actually writing much CSS (just composing existing classes instead):

Tailwind CSS is a highly customizable, low-level CSS framework that gives you all of the building blocks you need to build bespoke designs without any annoying opinionated styles you have to fight to override.

Now this library is a little controversial because at first glance, it reminds people a lot of inline styles, which have long been considered to be bad practice. The reactions of some commenters on Hacker News, illustrates this.

I think a lot of the criticism ultimately stems from misunderstandings of what Tailwind is doing that is different from something like inline styles and how it works when paired with something like React. Adam Wathan, the creator, addresses some of these concerns in his blog post and does a really good job of explaining the ideas behind the framework.

Anecdotally I feel significantly more productive using TailwindCSS than probably any CSS framework or technology I've used in the past. I quickly throw together the classes I need to make the component that I am visualizing and if I do find myself repeatedly using the same styles I create a new React component to encapsulate it, there's no switching between files, and I don't find myself creating single-use abstractions or investing time trying to come up with an appropriate class name.

Wrapping up

So there we have it, Parcel + React + Tailwind = 💗. I did just want to mention Gatsby as another alternative to Webpack and Parcel. Gatsby is known for being a static-site generator, but it really is a lot more than that and could be viewed more as an abstraction on top of webpack with all performance optimizations built in. If you are building a site/app with a mix of static and non-static content Gatsby may be worth considering, like parcel, it also alleviates the need to configure bundlers directly.

*Parcel uses babel under the hood, so when I say don't use babel I mean don't use it directly. If you're using Parcel, Babel remains invisible unless you need some specific configuration.