If you'd like to just use a template repository to get started faster, I've prepared one here.
Intro
If you're anything like me, you often find yourself experimenting with the latest web technologies. Unfortunately, a lot of these up-and-coming frameworks aren't compatible with each other. My latest project is a Jupyter Notebook clone, written in Rust, that runs entirely on the browser. Naturally, I looked toward Yew to create the web application.
Even using Rust, though, I didn't want to give up my Atomic CSS classes. I'm accustomed to using Tailwind CSS with frameworks like Next and Astro, but recently I've replaced it with UnoCSS. It has a preset for Tailwind, but it's significantly faster.
This guide aims to provide step-by-step instructions for integrating UnoCSS and Yew.
Setting up a Yew Project
To start off, we can create a new Yew project: 
- I won't go into depth here, but you need to enable the wasm32-unknown-unknown compilation target for WebAssembly to work.
 - Trunk is a bundler for Yew. You can install it using 
cargo, but I opted for a prebuilt binary. I usedbrew, but there are a number of methods available. - Create a new cargo project and add Yew as a dependency. You need to enable the “csr” (short for client-side rendering) feature, because we're building a web application.
 
If you did everything correctly, you should have a Cargo.toml with the following:
[dependencies]
yew = { version = "0.20.0", features = ["csr"] }
Note that your version number may be different.
Now, we just have to add a few things to get a functional Yew app. Start by creating a boilerplate index.html file in the root of your project:
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body></body>
</html>
When we run Yew, it will create static files for us in ./dist. We don't want to keep these under version control, so we can add /dist to our .gitignore.
Editor setup
This next step is optional, but if you're using VSCode, you might find it useful to enable HTML Intellisense for Rust files. Create .vscode/settings.json in the project root with the following content:
{
    "emmet.includeLanguages": {
        "rust": "html"
    }
}
Starting the App
From there, you can populate main.rs with a dummy Yew app:
use yew::prelude::*;
#[function_component]
fn App() -> Html {
    html! {
        <p class="text-5xl">{ "Hello World!" }</p>
    }
}
fn main() {
    yew::Renderer::<App>::new().render();
}
Try running your app now to see if everything's working correctly. You'll need to use trunk serve.
Installing UnoCSS
See that text-5xl class there? That doesn't do anything yet. The next stage is to install UnoCSS: 
- UnoCSS runs on JavaScript, so we'll need to create a Node project. I prefer 
pnpm, but you can also usenpmoryarn. - We're going to add two devDependencies: 
@unocss/cliandconcurrently. 
If you did that correctly, you should now have a package.json with the following:
"devDependencies": {
    "@unocss/cli": "^0.48.4",
    "concurrently": "^7.6.0"
}
Again, your version numbers may vary. Now is a good point to pop node_modules into your .gitignore.
This is also optional, but since I'm using pnpm, I'm going to add a special little script to my package.json:
"scripts": {
    ...
    "preinstall": "npx only-allow pnpm"
},
Tying it Together
Now that the setup is out of the way, we can properly integrate UnoCSS with Yew. The reason we used @unocss/cli was because we're going to use the unocss command to scan our Rust files and generate the necessary classes. Then, all we have to do is link the generated CSS to Yew's index.html.
Create a new script in your package.json:
"uno": "unocss src/**/*.rs index.html --out-file static/uno.css",
- We're telling UnoCSS to search through 
index.htmlas well as every Rust file insrc. - It's going to spit out the generated CSS file (
uno.css) in thestaticdirectory. 
  
  
  Linking uno.css
To link this file in our HTML, we can add the following line to the <head> of the index.html file in our project root:
<link data-trunk rel="css" href="./static/uno.css" />
- This is a special 
<link>.data-trunkis how we tell Trunk to process assets. - Trunk supports a few types of assets. The 
rel="{type}"we're looking for here iscss. - We're setting the 
hrefattribute to theuno.cssfile from earlier. 
Adding a CSS Reset
While we're at it, we should also implement one of the UnoCSS resets. You can pick whichever one you want, but I'm going with antfu.css, which is an extension of Tailwind CSS's Preflight. You have a couple options for linking them:
Here's all we needed to add to index.html:
<link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/@unocss/reset@0.48.4/antfu.css"
/>
<link data-trunk rel="css" href="./static/uno.css" />
Finally, let's add /static/uno.css to our .gitignore. We'll keep a .gitkeep file in there for now, since its only file is being gitignored.
Running UnoCSS with Trunk
Remember when we installed concurrently as a devDependency? That's how we're going to run UnoCSS alongside Yew. Let's first create a “dev” script:
"dev": "concurrently 'trunk serve' 'npm run uno -- --watch'",
Here, we're still using trunk serve to start our Yew app. We're going to run UnoCSS in watch mode so that it automatically updates ./static/uno.css when you update index.html or a Rust file in src. The extra set of dashes is necessary to pass the --watch argument. 
Next, we can create a “build” script for production:
"build": "concurrently 'trunk build --release' 'npm run uno'",
Now, we need neither UnoCSS nor Trunk in watch mode, so we can adjust both commands accordingly.
Testing our App
Now, the command to run our Yew app is pnpm run dev (you can modify this with npm or yarn if you're using those). Let's try it:
- It worked! An 
uno.cssfile was generated in thestaticdirectory. - We can see that trunk successfully processed the asset, too. If you check 
./dist/index.html, you'll notice that it even updated the import to the CSS file. 
Try changing text-5xl to other UnoCSS classes. You'll see the styles get refreshed automatically.
The full source code is available here.
              


    
Top comments (0)