Angular 11 + Tailwindcss 2.0 = Blazing Fast 🔥

How to setup Tailwindcss 2.0 in an Angular 11 project

Christian Ing Sunardi
Feb 18 · 9 min read
Image for post
Image for post
Photo by Melissa Askew on Unsplash

With the recent major release of Tailwindcss v2.0 and Angular v11 back in November 2020, it is really tempting to try it out in a project. However, setting up Tailwindcss to an Angular 11 project may be a bit tricky as it requires some additional webpack configs along with PostCSS plugins. On top of that, the official documentation (as of the time of this article’s writing) does not yet have the installation guide for Angular 11 framework. This article aims to provide a smooth integration of Tailwindcss 2.0 in an Angular 11 project along with other utility libraries that will help us achieve the goal.

Introduction: what is tailwindcss

As the name suggests, tailwind is a CSS framework that provides a different way of composing CSS. Normally, we would write CSS like the following:

Image for post
Image for post
Normal way of writing CSS (taken from the official tailwind docs).

We would create some CSS classes, divide them by their concerns, and write CSS codes specifically for each class. On the other hand, with tailwind, we would write like the following:

Image for post
Image for post
Tailwind way of writing CSS (taken from the official tailwind docs).

Yeah, that’s it. No CSS codes at all. We just need to call the pre-existing utility classes from tailwind and we’re good to go. There is a catch, though. Tailwind does not provide predefined component classes (e.g. .btn, .card, etc.) like Bootstrap or other CSS frameworks do. You may also wonder "what about maintainability and separation of concerns?". Unfortunately, we are not going to discuss that topic in this article, but the author of tailwind, Adam Wathan has a really great blog post that tells his own journey in which he went from writing "Semantic" CSS to Utility-first CSS. Hopefully by now, you have a rough idea about tailwind. Without further ado, let's get on with the guide!

Pre-requisites

Before proceeding to the guide, make sure you have the following installed in your operating system:

  • Node.js v12.13.0 or higher (as part of Tailwindcss v2.0 requirements)
  • Angular CLI v11

Create an Angular 11 project

Using Angular CLI v11, create a new Angular 11 app with SCSS.

ng new angular11-tailwindcss --style=scss
cd angular11-tailwindcss

Install tailwindcss dependencies

First of all, install the latest tailwindcss, postcss, and autoprefixer packages as devDependencies:

npm i -D tailwindcss@latest postcss@latest autoprefixer@latest

Then, install a specific major version of postcss-import, postcss-loader, and postcss-scss:

npm i -D postcss-import@12 postcss-loader@4 postcss-scss@3

Mind that installing the specific major version for postcss-import@12,postcss-loader@4, and postcss-scss@3 is important here as this is the configuration that works from my experience.

Configure an additional webpack config

After that, we’re going to install a 3rd party angular library via Angular Schematics called ngx-build-plus, which is for extending the default webpack configs without the need to eject the angular app:

ng add ngx-build-plus

Make sure the installed ngx-build-plus version matches with the angular version. In our case, the ngx-build-plus version should be 11.x.x as we’re using Angular 11. If for some reasons the installed version does not match, use the specific version install command ng add ngx-build-plus@11.

This command will install the ngx-build-plus as dependencies in package.json and automatically adjust the default angular.json to be like the following:

angular.json changes after `ng add ngx-build-plus`.

Let’s now create a custom webpack config file called webpack.config.js and place it in the root folder with the following configurations:

Additional webpack configs for PostCSS with PostCss Import, Autprofexier, and Tailwindcss plugins.

The above webpack config is mainly for setting up PostCSS. In this case, we’re using postcss-import, tailwindcss, and autoprefixer PostCSS plugins. To customise or learn more about other possible configurations, please visit https://tailwindcss.com/docs/using-with-preprocessors.

Now, we need to add an additional config to enable angular to read our additional webpack.config.js file. Copy the following new line to angular.json under "build", "serve", and "test" options :

angular.json after adding extra webpack config.

Make sure the property name is called "extraWebpackConfig" and the value matches your additional webpack config file name, which in our case should be "webpack.config.js". Additionally, ensure the additional webpack config file is placed in the root folder.

Configure and add tailwindcss

To start using tailwind in the project, let’s first generate a tailwindcss config file in the root folder using the command:

npx tailwindcss init

This will generate a file called tailwind.config.js with the following generated configs:

Initial tailwind configs.

The next step is to include tailwind styles in the global src/app/styles.scss file, like so:

Global style ‘src/app/styles.scss’ after importing tailwind styles.

At this point, tailwind has been configured and it is ready to use!

Test out tailwind utility classes

Now, let’s make a simple page using tailwind utility classes to test whether we can get tailwind styles. Copy the following html codes to the app.component.html file (taken from free samples component of tailwindui):

Login page html using tailwind.

Run your angular app using ng serve command and you should see something like this in the browser:

Image for post
Image for post
Login page created using tailwind sample codes.

Congratulations! You just successfully integrated Tailwindcss v2.0 to an Angular 11 app!

Bundle size concerns

If you notice, when you run the app using ng serve, the terminal shows an output like this:

Image for post
Image for post
Our app bundle size in the terminal from the command ‘ng serve’.

Wait a minute… since we import tailwind in the styles.scss, does it mean that tailwind really took those 11.21 MB?! On a second thought, it’s probably because we have not built the app using the production mode, right? Let’s build the app using the command ng build --prod. You should see the following output:

Image for post
Image for post
Our app bundle size after ‘ng build --prod’.

Much better, but isn’t 3.53 MB still quite big though? Well, tailwind is actually a pretty big library to begin with. The following is the development build size from the official documentation of tailwind:

Image for post
Image for post
Tailwind development build size (taken from the official tailwind docs).

Even after being compressed with Gzip, its bundle size is considerably big; around 294.0kB. You see, the development build is large by design. Tailwind provides thousands of utility classes for us, which we probably only use some of them. Therefore, does it not make sense that it has a big build size? However, don't fret! The author of tailwind notices this and provides a solution that can make our production build to be much much smaller than that!

Optimising tailwind for production

Now, the trick to optimise the tailwind build size is to use a 3rd party library called PurgeCSS, which is already included and used in tailwind under the hood. As the name says, it will purge all of the unused CSS when we build our app for the production. Because PurgeCSS has already been included in tailwind, we don’t need to install an additional library. Instead, we just need to add the following additional configuration in tailwind.config.js:

Tailwind config with Purge mode.

The configuration presented above purges unused CSS classes in all HTML and TS files. If you’d like to know more about optimisation best practices specifically for tailwind, it is recommended to read this article from the official tailwind documentation.

There is another step though. Since tailwind purges the unused CSS by checking if NODE_ENV is set to production, we need to include an additional script command to our package.json, like so:

package.json file with a new production build script.

With this, we are now ready to build our app! Let’s run npm run build:prod command and you should see the following output:

Image for post
Image for post
Our app bundle size after a configuration with PurgeCSS.

Would you look at that! We went from a chunky 3.53 MB to as small as 6.86 kB with only 2 new lines added! If you are still not convinced, we can check the built files from /dist/angular11-tailwindcss/styles.{{hash}}.css file:

Built CSS files with purge mode in tailwind.

As can be seen, you may not be able to find any unused tailwind utility classes as the one are being included there are only the used tailwind classes, which in our case are the CSS classes used in app.component.html file. As a result, you should now have a production-ready application with a really small bundle size!

**Bonus: vscode css linting**

Tailwind provides several custom functions and directives that can help us produce compact yet optimised CSS codes. One that I personally used is the @apply directive that let us instead of using tailwind utility classes directly in the template like this:

Without tailwind `@apply` directive.

We can extract and embed tailwind utility classes to custom CSS classes like so:

With tailwind `@apply` directive.

This can be very handy if we still prefer the “conventional” way of writing CSS. However, if we try to use these directives specifically in VSCode, we will get something like the following:

Image for post
Image for post
VSCode CSS linting errors.

We may get some error messages like semi-colon expected scss(css-semicolonexpected) or Unknown at rule @responsive scss(unknownAtRules) when trying to use a directive as the wrapper. This does not result in a compilation or build error though as this is only a linting error. As such, the above CSS codes would still work just fine. However, wouldn't it be better if we can get rid of this annoying false positive error message? Rest assured, after scrolling through the Internet, there is a possible solution.

Disable vscode css validations and extend stylelint rules

To remove the vscode css linting errors, we first need to create a user-level VSCode setting file called .vscode/settings.json in the root folder and paste the following configs:

VSCode user setting for disabling css validations.

Then, install stylelint vscode extension:

Image for post
Image for post
Stylelint extension on VSCode Marketplace.

After that, we need to install stylelint-config-standard package as devDependencies:

npm i -D stylelint-config-standard

Next, create a new config file called stylelint.config.js in the root folder, with the following configurations:

Stylelint config for handling tailwind directives.

Notice that we’re extending stylelint-config-recommended instead of stylelint-config-standard. The package stylelint-config-recommended gets automatically installed when we install stylelint-config-standard package (check thepackage-lock.json file).

The above configuration extends the stylelint-config-recommended linting rules and ignores some rules that might cause unintended error messages while using tailwind’s custom functions and directives. Finally, restart your VSCode and voila, we should no longer see the linting errors:

Image for post
Image for post
VSCode no longer shows CSS linting errors.

Conclusions

To summarise, integrating Tailwindcss 2.0 with Angular 11 may look a bit daunting at first. However, with the help of some 3rd party libraries like ngx-build-plus and figuring it out which versions of libraries we need to install, it makes the process much smoother. In addition, the built-in purge feature from Tailwind (with the help of PurgeCSS library) provides an easy way to remove unused CSS classes in the project, in which when we combine with Angular 11 production build can result in a considerably small app size!

GitHub repository

If you’d like to see the full implementation of this article, feel free to clone or view the GitHub repository here:

References

Tunaiku Tech

Stories behind Tunaiku Products, Engineering and Data Team

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store