DEV Community

arctic_hen7
arctic_hen7

Posted on

How to set up Tailwind CSS with Yew and Trunk

Yew is a fantastic tool for building web apps with Rust using WASM, though it has very little support for good CSS systems right now. This post will explain how to set up TailwindCSS with Yew and Trunk to create a fully-functional WASM set up with excellent CSS!

Note that this tutorial assumes you have a basic app already set up with Yew and Trunk. If not, check out Yew's official guide to building a starter app here.

Installing Things

We'll use the Tailwind CLI to set things up, which we'll install as a global npm or yarn dependency.

If you are religiously against installing such JavaScript evils on your sacred system, try tailwind-yew-builder, it does very similar things in Docker so you don't have to pollute your computer!

You can install the Tailwind CLI like so:

npm i -g tailwindcss
Enter fullscreen mode Exit fullscreen mode

or

yarn global add tailwindcss
Enter fullscreen mode Exit fullscreen mode

Now run a sanity check:

tailwindcss --help
Enter fullscreen mode Exit fullscreen mode

You should see the help page for the Tailwind CLI! If not, make sure you've set up your PATH properly for global installs by either NPM or Yarn (particularly Yarn...).

Setting up Tailwind

What we're aiming to get is a single CSS file that we can include in our Trunk HTML. We can do this by running this in the same directory as our top-level index.html for Trunk:

tailwindcss -o ./tailwind.css
Enter fullscreen mode Exit fullscreen mode

That will generate a file named tailwind.css that contains around 4MB of pure CSS. We'll come back to cutting that down. For now though, you should make sure that doesn't get added to version control by adding it your .gitignore like so:

tailwind.css
Enter fullscreen mode Exit fullscreen mode

Now it's time to include that file in our index.html, which we can do by adding this to the head:

<link data-trunk href="./tailwind.css" rel="css" />
Enter fullscreen mode Exit fullscreen mode

This directs Trunk to use the Tailwind file as a stylesheet. You can now use styles in your Yew html!, try it out like this:

html! {
    <p class=classes!("bg-red-100")>{"Test!"}</p>
}
Enter fullscreen mode Exit fullscreen mode

Now is you run trunk serve, you should see a paragraph saying Test with a very light red background! Congratulations, you've set up Tailwind with Yew in development!

Going to production

This is all well and good, but we do NOT want to be serving 4MB of assets to our users! Tailwind has an inbuilt feature for purging unused CSS classes, which it does by searching for the classes you've used. It does that using a regular expression, which just analyses the file, meaning Rust is fine!

Create a tailwind.config.js file at the root of your project and add this to it:

module.exports = {
    purge: {
        mode: "all",
        content: [
            "./src/**/*.rs",
            "./index.html",
            "./src/**/*.html",
            "./src/**/*.css",
        ],
    },
    theme: {},
    variants: {},
    plugins: [],
};
Enter fullscreen mode Exit fullscreen mode

You can add any other Tailwind configuration you might have in here as well. All this does though is instruct Tailwind to look at all Rust, HTML, and CSS files in src/ and remove any classes it doesn't find being used there. We also check index.html in case you have anything in there. This check could probably be refined using the extract property so it only checks Rust files in html!, but this is good enough for now.

Now try building Tailwind for production by running this:

NODE_ENV=production tailwindcss -c ./tailwind.config.js -o ./tailwind.css --minify
Enter fullscreen mode Exit fullscreen mode

That will automatically enable purging, and now check the size of the tailwind.css file. It should be something like 3KB! That's a pretty giant improvement!

Bonus: command aliases

These commands are pretty long and tedious to execute regularly, so you might want to use something like Bonnie to alias them to shorter commands like build and run. Check out the Bonnie wiki for an explanation of how this example file works (should be pretty self-explanatory though):

version="0.3.1"

[scripts]
## Builds Tailwind CSS for development (no purging)
build-tailwind-dev = [
    "cd frontend",
    "tailwindcss -c ./tailwind.config.js -o ./tailwind.css"
]
## Builds Tailwind CSS for production (maximum purging and minification)
build-tailwind-prod = [
    "cd frontend",
    "NODE_ENV=production tailwindcss -c ./tailwind.config.js -o ./tailwind.css --minify"
]
## Builds Tailwind CSS for development usage
setup.subcommands.tailwind = "bonnie build-tailwind-dev"
setup.subcommands.prompt-tailwind = "echo \"Have you installed the Tailwind CLI globally with 'npm i -g tailwindcss' or 'yarn global add tailwindcss'?\""
setup.order = """
tailwind {
    Failure => prompt-tailwind
}
"""

## Builds everything
build.cmd = "cargo build"
## Builds the frontend
build.subcommands.frontend = [
    "cd frontend",
    "bonnie build-tailwind-prod",
    "cargo build"
]
## Runs the frontend, watching for changes (uses Trunk)
## Tailwind is assumed to be set up after `setup`
run.subcommands.frontend = [
    "cd frontend",
    "trunk serve"
]
Enter fullscreen mode Exit fullscreen mode

Then anyone starting out with your project can just run bonnie setup to build Tailwind for them! Running bonnie run frontend will spin up a Trunk server for you automatically, and bonnie build frontend will build everything for production (including Tailwind)! Note that this configuration assumes you've got everything in frontend/ in case you've got a backend/ as well (if not you can just remove those bits).

Full disclosure: I am the maintainer of Bonnie.

Closing words

Hopefully, you now have a working setup with TailwindCSS and Yew! As always, any feedback would be greatly appreciated!

Happy coding!

Top comments (8)

Collapse
 
mremanuel profile image
Emanuel Lindström • Edited

Instead of installing tailwind cli globally, you can just run it with npx.

The command is:
npx tailwindcss -o tailwind.css

Using npx, the tailwind command for production is:
NODE_ENV=production npx tailwindcss -c ./tailwind.config.js -o ./tailwind.css --minify

Collapse
 
bocarw121 profile image
bocarw121

Hey everyone,

I created a cli that'll get tailwind setup in your yew application in a matter of seconds.
Check it out here tailwind-yew-cli.

Happy coding!

Collapse
 
itflyingstart profile image
ItFlyingStart • Edited

I have followed your tutorial, but I can't make it work. I have described my test project in details here: stackoverflow.com/questions/713493...

Can you please have a look and spot what I have done wrong? Thanks

Collapse
 
itflyingstart profile image
ItFlyingStart

Never mind. I have made it work after using yew-tailwind-builder. Apparently tailwindcss -o ./tailwind.css doesn't generate the complete css file.

Collapse
 
phughk profile image
Przemyslaw Hugh Kaznowski

Thanks for the hint! Turns out you need the config file for it to generate the tailwind. I then export tailwind without minify - it is 12kb when I only access a single colour bg-red-100 for testing.

Collapse
 
alemartinezz profile image
Alejandro Martínez

How do you handle JS functionality of tailwind components?

Collapse
 
almaju profile image
Almaju

It looks like it is supported out of the box with Trunk.
github.com/trunk-rs/trunk/tree/mai...

Collapse
 
veercodeprog profile image
Veer Pratap • Edited

i had a custom tailwind.config.js, which is not working while the tailwind css is.
any help on how can i make my tailwind.config.js works?