cicadel
Documentation

Style with Tailwind

Tailwind CSS is Cicadel’s default styling workflow. Generated projects include Tailwind v4 input, a styled component page, compiled CSS, and an embedded static route. Use the project CLI to install the compiler, generate CSS and check for stale output. The server has no Tailwind/Node process or CDN dependency. Other CSS systems remain supported: see the opt-out instructions below.

The current toolchain pins Tailwind v4.3.3. Cicadel uses the upstream standalone CLI, not npm, PostCSS, a custom CSS compiler, or a browser-time Tailwind script.

Ask your agent

text
Read https://cicadel.fauzaanu.com/en/dev/howto/tailwind/index.md.
Style [component] using this application's existing Tailwind setup.
Use complete utility classes, keep labels and focus states accessible,
and run the matching Cicadel ui build and ui check commands.

Default authoring loop

From a generated application, after go mod tidy:

sh
# Once per development/CI machine; explicit network download.
go tool cicadel ui css install

# After editing .templ, Go class variants, or CSS input.
go tool cicadel ui build
go tool cicadel ui check --json
go test -race ./...
go build -trimpath -o bin/server .

In the framework checkout substitute go run ./cmd/cicadel for go tool cicadel. The starter includes genuine compiler-generated CSS, so its initial server works without downloading any CSS tool. Tests that compile CSS (including the framework’s scaffold/docs tests) need the explicitly installed compiler. CI installs it first.

CommandResponsibility
ui css installDownload the pinned executable, verify SHA256, install in the OS user cache. An already valid installation does not download again.
ui buildGenerate .templ Go, then build CSS if ui.css.json exists.
ui generateGenerate markup only; use for component-only libraries.
ui css buildBuild/minify CSS only, atomically replacing output after success.
ui check --jsonCheck markup and configured CSS freshness, then compile Go/tests without executing them.
ui css checkRecompile/compare CSS without changing the committed output.

The Go/CSS toolchains still need their normal local caches; install Go dependencies with Go tooling before an offline build. Build/check never download the Tailwind executable or add a Go dependency. Package resolution uses read-only go list. Check uses temporary files/caches but leaves generated source and CSS unchanged. A missing tool fails with UI_CSS_TOOL; stale output fails with UI_CSS_STALE. All failed commands have nonzero exit status. Use top-level ui check --json for machine diagnostics; ui css ... commands print human-readable errors.

Files and configuration

Generated ui.css.json:

json
{
  "version": "v4.3.3",
  "input": "project/styles/input.css",
  "output": "project/static/app.css",
  "packages": []
}

Paths are relative to the project/module directory where you run the command. Input/output must be different local .css paths. Unknown config fields, unsupported versions and invalid paths fail explicitly. Commands do not search parent directories. The pinned framework and config version must agree; upgrading Tailwind is a reviewed framework/toolchain upgrade, not an implicit latest fetch.

project/styles/input.css imports Tailwind with automatic detection disabled and lists the project’s .templ and ordinary Go source patterns explicitly. Generated *_templ.go and tests are excluded, preventing stale generated classes and test payloads from influencing normal CSS. Source paths are relative to the input file, not the caller’s current directory. See upstream source detection.

Customize with CSS-first Tailwind v4, for example:

css
@theme {
  --color-brand-600: #4f46e5;
}

Then write class="bg-brand-600 text-white" in .templ. Keep the existing @import and @source declarations. Local CSS imports resolve relative to the input file. Do not use old v3 @tailwind base directives or assume a tailwind.config.js is auto-loaded. The standalone build is not a promise that arbitrary npm plugins are bundled; those require their own explicitly maintained build integration. CSS remains trusted authored source, not request input.

Classes and variants

Use familiar complete utilities and responsive/state variants:

templ
<button class="rounded-lg bg-indigo-600 px-4 py-2 text-white hover:bg-indigo-700 focus-visible:outline-2 sm:px-6">
    Save
</button>

For dynamic variants, choose between complete literal strings in Go. Do not construct utility names from request values ("bg-" + color + "-600"), because Tailwind scans text rather than evaluating Go. For intentional finite classes that cannot appear literally in scanned source, use an explicit CSS @source inline(...) declaration. Never safelist an unbounded set derived from user input.

ui.Merge combines distinct class tokens. It does not implement tailwind-merge or decide which conflicting utilities win: the generated CSS cascade governs that. Prefer a typed variant that chooses one spacing/color utility per state.

Independently installed component packages

Register an app through Go imports/manifests as usual. Separately add the exact Go import path of a package containing Tailwind classes:

json
{
  "version": "v4.3.3",
  "input": "project/styles/input.css",
  "output": "project/static/app.css",
  "packages": ["example.com/your-library/cards"]
}

That path is illustrative. Cicadel resolves each entry using the host’s selected Go module graph, then adds an explicit Tailwind source directory for the build. It works with installed module-cache sources and local replacements; no paths into a particular user’s module cache are committed. Directory scans include descendants, so point at the narrow component package. The packages setting does not install modules, activate apps, or establish permissions. Missing packages fail with UI_CSS_PACKAGE; install them via normal Go tooling first.

Library releases must include their class-bearing source or literal candidates; Tailwind cannot infer utilities hidden in runtime-only data. Library authors remain responsible for sensible source-directory contents and dependency declarations.

Serving and production

The starter embeds project/static/app.css in Go and serves /static/app.css using static.Handler. layout.Page accepts an optional Props.Stylesheet URL; it emits a contextual-escaped <link rel="stylesheet">. The generated home page supplies the default asset path. The minimal renderer/layout never silently inserts CSS into other applications, so existing pages keep their current stylesheet choice.

Commit CSS input/config and generated CSS together with the generated component Go. Run ui check before the production build. After UI changes, run ui build and restart/rebuild the Go server to refresh embedded assets. There is no HMR/watch server or production runtime CSS compilation. You can serve the output through your existing static host/CDN instead by setting the page’s stylesheet URL explicitly; asset hashing/CDN cache policies are separate from this compiler integration.

Tailwind v4 targets modern browsers; use upstream compatibility guidance when choosing browser support. This integration verifies generated CSS/HTTP delivery, not visual pixel equivalence across browser engines.

Another stylesheet system or an existing project

To opt out, remove ui.css.json, replace project/static/app.css with your own stylesheet/build output, and keep or change the explicit link/static route. ui build/check then handles markup only. Do not leave a Tailwind config pointing at output maintained by a different compiler.

To adopt Tailwind in an existing app, add the config, an input importing Tailwind with explicit source directories, and an output location owned by your static pipeline. Add the stylesheet link, install the tool, build/check, and verify the asset route. Existing apps are not automatically restyled by upgrading Cicadel.

↑

Type to search this version.