Update FRESH 1.6
Since the latest release of fresh (1.6), you can actually use the official Tailwind CSS package in NPM and so unless you want a solution that does not include node_modules/
folder, you can consider this article obsolete.
Intro
Greetings, fellow human beings 👋
Today, I would like to share my experience with fresh
and why you should replace the styling from twind
-> taiwlind-cli
.
What is fresh?
Fresh is "The next-gen web framework", which could be translated to "Hey! I am cool deno-based SSR framework". Fresh, instead of using react
uses preact
, which is tiny(3kb) alternative to regular-sized react. Preact, just like react, uses .jsx / .tsx
files and syntax and is compatible with react-based libraries.
Cool! But what is twind, and why should we care? Well, twind
is a tiny implementation of tailwind css
in javascript
. Awesome, so what is the problem? Why not stick with it? The answer to this is simple. Currently, they don't have extension for vs-codium and their extension for regular vs-code is not working. There are hacky fixes, but why should I care if I can use regular old tailwind? (I know it's against deno's whole purpose, but I guess one exception is fine?)
Before we continue...
Before we continue any further, it's useful to mention, that I have prepared a template repository for all of you, who are just starting out with fresh and are not looking to replace the twind
, but rather make a brand-new project.
Without any further a do, here is the link.
Replacing twind in existing code-base
So you already have a fresh project and looking for a way to replace the twind
? Well I have a good news, look no further as I will show the way.
Step 1. Removing it
First, we need to remove it from your fresh.json
file as our dependency.
{
"lock": false,
"tasks": {
"check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx",
"start": "deno run -A --watch=static/,routes/ dev.ts",
"build": "deno run -A dev.ts build",
"preview": "deno run -A main.ts",
"update": "deno run -A -r https://fresh.deno.dev/update ."
},
"lint": {
"rules": {
"tags": [
"fresh",
"recommended"
]
},
"exclude": [
"_fresh"
]
},
"fmt": {
"exclude": [
"_fresh"
]
},
"imports": {
"$fresh/": "https://deno.land/x/fresh@1.4.2/",
"preact": "https://esm.sh/preact@10.15.1",
"preact/": "https://esm.sh/preact@10.15.1/",
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@6.2.1",
"@preact/signals": "https://esm.sh/*@preact/signals@1.1.3",
"@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.2.3",
-------- REMOVE THESE LINES ---------------
"twind": "https://esm.sh/twind@0.16.19",
"twind/": "https://esm.sh/twind@0.16.19/",
-------------------------------------------
"$std/": "https://deno.land/std@0.193.0/"
},
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact"
}
}
Great! Now we got rid of it as dependency. As a next step, you should also remove the twind.config.js
file, as we won't be using it anymore.
By removing the config file, we need to update our main.ts
file to following:
/// <reference no-default-lib="true" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/// <reference lib="dom.asynciterable" />
/// <reference lib="deno.ns" />
import "$std/dotenv/load.ts";
import { start } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";
// Remove this import statemet
import config from "./fresh.config.ts";
// Replace following line with just: await start(manifest);
await start(manifest, config);
Awesome! Next, we need to update the fresh config file of the twind removal.
// original
import { defineConfig } from "$fresh/server.ts";
import twindPlugin from "$fresh/plugins/twind.ts"
import twindConfig from "./twind.config.ts";
export default defineConfig({
plugins: [twindPlugin(twindConfig)]
});
// ---------------------------------------
// updated
import { defineConfig } from "$fresh/server.ts";
export default defineConfig({
plugins: [],
});
Voilà! Now are got ourselves fresh project without any styling.
Step 2. Installing tailwind
So now we have a fresh project running, but it looks like garbage, or at least as HTML without any CSS. To fix this, we need to install tailwind CSS.
Fetching the binary file
To continue, we need to fetch ourselves a copy of tailwind binary. Here is a link to the release page. Download the copy for your platform and rename it to just tailwindcss
. We will use this binary to transpile our classes into a regular old CSS file.
Now, we need to update our start
task in deno.json > tasks
.
{
"lock": false,
"tasks": {
"start": "tailwindcss -i ./static/styles/input.css -o ./static/styles/tailwind.css --minify --watch & deno run -A --watch=static/,routes/ dev.ts",
},
...rest of the deno.json code
Alright! We are half way done. Now we have to create tailwind.config.cjs
file with following code:
/** @type {import('https://esm.sh/tailwindcss@3.1.8').Config} */
module.exports = {
content: [
"./routes/**/*.{tsx,ts}",
"./islands/**/*.{tsx,ts}",
"./components/**/*.{tsx,ts}",
],
theme: {
extends: {},
},
plugins: [],
};
Once that is done, we need to create a new file in /static/styles/input.css
and give it the following code:
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
}
Linking the styling
Update the _app.tsx
located at /routes
of the following component:
import { Head } from "$fresh/runtime.ts";
import { AppProps } from "$fresh/src/server/types.ts";
export default function App(props: AppProps) {
const { Component } = props;
return (
<html>
<Head>
<meta charSet="utf-8" />
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<title>Fresh project | starter code</title>
<link rel="icon" type="image/png" href="../favicon.ico"></link>
<link rel="stylesheet" href="../styles/tailwind.css" />
</Head>
<body className="antialiased">
<Component />
</body>
</html>
);
}
Ta Da! Your application should now be styled by the original Tailwind CSS. If you have any questions, don't be afraid to ask. If you want to see a deployment ready app, check out the template repository in the second paragraph.
Top comments (5)
Nice tutorial! Thanks!
I found a way to do it without using the tailwindcss binary:
As you may know, Deno supports npm modules (at least Deno 1.23.1), so it is possible to run tailwindcss directly from command line.
deno run
works likenpx
: Run a module with no need to install it-A
gives it permission to access local files (cache)Thank you for your addition. With the recent release of Fresh, you can actually use NPM's version of tailwind CSS, just like you did with your implementation.
If i want to deploy this production, I assume I would need the tailwind-cli installed somewhere? Have you deployed this to production?
I have deployed my portfolio website with this template. You actually don't need the CLI for production (put it to
.gitignore
for all I care), as what it only does is it compiles your classes to a regular.css
file in/static/styles/tailwind.css
.In the last code example, there is a
_app.tsx
which basically states how our HTML should be rendered. In it, you find a regular HTML link to the compiledtailwind.css
.Makes sense. Thanks!