| |

Tailwind CSS 79 🎨 Standalone Binary CLI Distribution in Non-Node.js Workflows (Go, Rust, Rails)

⏱️ Estimated read: 14 min | |

A Tailwind project has traditionally required Node.js. The package.json holds the dependency, the node_modules holds the engine, and the build runs through npm scripts or a bundler plugin. For a Go service, a Rust application, or a Rails monolith, that requirement is friction. The project already has a build pipeline, and adding a second runtime for the CSS is the extra dependency the team did not want. The standalone CLI is the answer. It is a single, self-contained executable that bundles the Tailwind engine and runs without Node.js, npm, or the node_modules directory. This chapter covers the binary, the download, the @source directive, and the integration with the three ecosystems.

Key point: The standalone CLI is the same engine as the npm package, compiled to a native binary. It reads the input CSS, scans the source files, and writes the output CSS. The @source directive tells the binary where to look, and the --watch flag rebuilds on the change. The binary is the distribution, and the Node.js is the optional.


Why the standalone CLI exists

The Node.js dependency problem. A Go or a Rust project does not have the Node.js. Adding it for the CSS means installing the runtime, the package manager, and the node_modules tree on every developer machine and every CI runner. The standalone binary is the one file, and the runtime is the none.

The build-pipeline problem. The project already has the Makefile, the Cargo build, or the Rails asset pipeline. Adding the npm script means the second pipeline, the second lockfile, and the second set of the tools to maintain. The standalone binary integrates with the existing pipeline.

The binary-distribution problem. The npm package requires the network access to the registry, the version resolution, and the cache. The standalone binary is the download, the checksum, and the run. The distribution is the simpler.

The version-pinning problem. The package.json pins the version, and the lockfile pins the transitive. The standalone binary is the one version, and the checksum is the integrity.

The performance problem. The binary is the native, and it starts faster than the Node.js process. The Oxide engine is the same, and the startup is the smaller.

The offline problem. The air-gapped environment cannot reach the npm registry. The standalone binary is the download once, and the run offline.

The multi-platform problem. The releases cover the Linux, the macOS, and the Windows, on the x64 and the arm64. The Go, the Rust, and the Rails projects on the any platform use the same command.


a. The download and the setup

The binary is the GitHub release. The download is the platform-specific, and the checksum is the verification.

The download

The releases page lists the assets. The naming is the tailwindcss-<platform>-<arch>.

# The Linux x64
curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64

# The macOS arm64
curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-macos-arm64

# The Windows x64
curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-windows-x64.exe

The latest resolves to the newest release. The pinned version replaces the latest for the reproducibility.

The executable permission

chmod +x tailwindcss-linux-x64
mv tailwindcss-linux-x64 tailwindcss

The chmod adds the execute bit, and the mv renames to the short name.

The verification

# The checksum
sha256sum tailwindcss
# Compare with the release page.

The checksum is the integrity, and the release page publishes it.

The basic command

./tailwindcss -i ./input.css -o ./output.css

The -i is the input, the -o is the output, and the command runs once.

The command flags

The flagThe purpose
-i, --inputThe input CSS
-o, --outputThe output CSS
--watchThe rebuild on the change
--minifyThe minify the output
--cwdThe working directory
--contentThe legacy content (the v3)

The v4 input CSS

@import "tailwindcss";

@source "./**/*.go";
@source "./templates/**/*.html";

The @import loads the framework, and the @source tells the binary where the class names are.

The watch

./tailwindcss -i ./input.css -o ./output.css --watch

The --watch rebuilds on the change. The binary watches the @source paths and the input.

The minify

./tailwindcss -i ./input.css -o ./output.css --minify

The --minify produces the production output.

The setup table

The stepThe command
The downloadcurl -sLO ...
The permissionchmod +x ...
The renamemv ... tailwindcss
The verifysha256sum ...
The run./tailwindcss -i ... -o ...

b. The integration with the Go

The Go project does not have the Node.js. The standalone binary is the downloaded file, and the Makefile is the build.

The project structure

myapp/
├── cmd/
│   └── server/
│       └── main.go
├── internal/
│   └── handlers/
│       └── home.go
├── web/
│   ├── templates/
│   │   └── home.templ
│   └── static/
│       ├── css/
│       │   ├── input.css
│       │   └── output.css
│       └── tailwindcss
├── Makefile
└── go.mod

The tailwindcss binary is the web/static directory, and the input.css is the web/static/css.

The input CSS

@import "tailwindcss";

@source "../../../internal/**/*.go";
@source "../templates/**/*.templ";

The @source points to the Go files and the templ files. The templ is the templating engine for the Go.

The Makefile

.PHONY: build css css-watch run

build: css
	go build -o bin/server ./cmd/server

css:
	./web/static/tailwindcss \
		-i ./web/static/css/input.css \
		-o ./web/static/css/output.css \
		--minify

css-watch:
	./web/static/tailwindcss \
		-i ./web/static/css/input.css \
		-o ./web/static/css/output.css \
		--watch

run: build
	./bin/server

The make css produces the output, and the make build depends on it. The make css-watch is the development.

The templ class usage

templ Home() {
	<div class="flex items-center gap-4 p-4 bg-blue-600 text-white">
		<h1 class="text-2xl font-bold">Hello</h1>
	</div>
}

The classes are the Tailwind, and the @source scans the .templ file.

The Go table

The aspectThe approach
The binaryThe web/static
The inputThe web/static/css/input.css
The outputThe web/static/css/output.css
The sourceThe internal/**/*.go, the templates/**/*.templ
The buildThe Makefile
The watchThe make css-watch

c. The integration with the Rust

The Rust project has the Cargo build. The standalone binary is the build-dependency or the downloaded tool.

The project structure

myapp/
├── src/
│   └── main.rs
├── style/
│   └── input.css
├── public/
│   └── output.css
├── tailwindcss
└── Cargo.toml

The tailwindcss binary is the project root, and the style/input.css is the input.

The input CSS

@import "tailwindcss";

@source "../src/**/*.rs";

The @source points to the Rust files. The classes are in the view! macro or the equivalent.

The build script

// build.rs
use std::process::Command;

fn main() {
    let status = Command::new("./tailwindcss")
        .args([
            "-i", "style/input.css",
            "-o", "public/output.css",
            "--minify",
        ])
        .status()
        .expect("The tailwindcss failed");

    if !status.success() {
        panic!("The tailwindcss exited with the error");
    }

    println!("cargo:rerun-if-changed=style/input.css");
    println!("cargo:rerun-if-changed=src");
}

The build.rs runs the binary at the Cargo build. The rerun-if-changed tells Cargo to re-run on the input or the source change.

The Leptos class usage

view! {
    <div class="flex items-center gap-4 p-4 bg-blue-600 text-white">
        <h1 class="text-2xl font-bold">"Hello"</h1>
    </div>
}

The classes are the Tailwind, and the @source scans the .rs file.

The Pocopine automation

The Pocopine framework downloads and caches the correct binary on the first run. The manual setup is the alternative.

The Rust table

The aspectThe approach
The binaryThe project root
The inputThe style/input.css
The outputThe public/output.css
The sourceThe src/**/*.rs
The buildThe build.rs
The rerunThe cargo:rerun-if-changed

d. The integration with the Rails

The Rails has the tailwindcss-rails gem, which manages the binary for the developer.

The installation

# The Gemfile
bundle add tailwindcss-rails

# The installer
./bin/rails tailwindcss:install

The bundle add adds the gem, and the installer sets up the files.

The generated files

app/assets/tailwind/application.css

The installer creates the input file. The output goes to the app/assets/builds/tailwind.css.

The input CSS

@import "tailwindcss";

@source "../../../app/views/**/*.erb";
@source "../../../app/helpers/**/*.rb";
@source "../../../app/javascript/**/*.js";

The @source points to the Rails directories.

The Rake tasks

The taskThe purpose
tailwindcss:buildThe one-off build
tailwindcss:watchThe development
tailwindcss:clobberThe clean
tailwindcss:installThe setup

The tailwindcss:build is the production, and the tailwindcss:watch is the development.

The asset pipeline

The Rails 7+ uses the Propshaft or the Sprockets. The tailwindcss-rails integrates with the assets:precompile task.

./bin/rails assets:precompile

The task runs the tailwindcss:build before the asset compilation.

The Procfile

web: bin/rails server
css: bin/rails tailwindcss:watch

The bin/dev runs the two processes. The Rails 7 has the bin/dev with the Procfile.dev.

The ERB class usage

<div class="flex items-center gap-4 p-4 bg-blue-600 text-white">
  <h1 class="text-2xl font-bold">Hello</h1>
</div>

The classes are the Tailwind, and the @source scans the .erb file.

The Rails table

The aspectThe approach
The gemThe tailwindcss-rails
The inputThe app/assets/tailwind/application.css
The outputThe app/assets/builds/tailwind.css
The sourceThe app/views, the app/helpers, the app/javascript
The buildThe tailwindcss:build
The watchThe tailwindcss:watch

Complete Example Session

/* ============================================
   PART 1: THE INPUT CSS
   ============================================ */

@import "tailwindcss";

@source "./**/*.go";
@source "./templates/**/*.html";

/* ============================================
   PART 2: THE DOWNLOAD
   ============================================ */

curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64
chmod +x tailwindcss-linux-x64
mv tailwindcss-linux-x64 tailwindcss

/* ============================================
   PART 3: THE BASIC RUN
   ============================================ */

./tailwindcss -i ./input.css -o ./output.css

/* ============================================
   PART 4: THE WATCH
   ============================================ */

./tailwindcss -i ./input.css -o ./output.css --watch

/* ============================================
   PART 5: THE MINIFY
   ============================================ */

./tailwindcss -i ./input.css -o ./output.css --minify

/* ============================================
   PART 6: THE GO MAKEFILE
   ============================================ */

build: css
	go build -o bin/server ./cmd/server

css:
	./web/static/tailwindcss -i ./web/static/css/input.css -o ./web/static/css/output.css --minify

css-watch:
	./web/static/tailwindcss -i ./web/static/css/input.css -o ./web/static/css/output.css --watch

/* ============================================
   PART 7: THE RUST BUILD SCRIPT
   ============================================ */

fn main() {
    let status = Command::new("./tailwindcss")
        .args(["-i", "style/input.css", "-o", "public/output.css", "--minify"])
        .status()
        .expect("The tailwindcss failed");

    if !status.success() {
        panic!("The tailwindcss exited with the error");
    }

    println!("cargo:rerun-if-changed=style/input.css");
    println!("cargo:rerun-if-changed=src");
}

/* ============================================
   PART 8: THE RAILS INSTALL
   ============================================ */

bundle add tailwindcss-rails
./bin/rails tailwindcss:install

/* ============================================
   PART 9: THE RAILS TASKS
   ============================================ */

./bin/rails tailwindcss:build
./bin/rails tailwindcss:watch

/* ============================================
   PART 10: THE COMPLETE PATTERN
   ============================================ */

// 1. Download the binary for the platform.
// 2. chmod +x and rename.
// 3. The @source points to the source files.
// 4. The -i and -o are the input and the output.
// 5. The --watch is the development.
// 6. The --minify is the production.
// 7. The Go uses the Makefile.
// 8. The Rust uses the build.rs.
// 9. The Rails uses the tailwindcss-rails.
// 10. The Node.js is the optional.

The ten parts showed the input CSS, the download, the basic run, the watch, the minify, the Go Makefile, the Rust build script, the Rails install, the Rails tasks, and the complete pattern.


Quick Reference

The CLI Flags

The flagThe purpose
-i, --inputThe input CSS
-o, --outputThe output CSS
--watchThe rebuild
--minifyThe minify
--cwdThe working directory
--contentThe v3 content

The Download

The platformThe file
The Linux x64tailwindcss-linux-x64
The Linux arm64tailwindcss-linux-arm64
The macOS x64tailwindcss-macos-x64
The macOS arm64tailwindcss-macos-arm64
The Windows x64tailwindcss-windows-x64.exe

The Integration

The ecosystemThe mechanism
The GoThe Makefile
The RustThe build.rs
The RailsThe tailwindcss-rails gem

The Rails Tasks

The taskThe purpose
tailwindcss:buildThe one-off
tailwindcss:watchThe development
tailwindcss:clobberThe clean
tailwindcss:installThe setup

The @source Directives

The ecosystemThe source
The GoThe **/*.go, the **/*.templ
The RustThe **/*.rs
The RailsThe app/views/**/*.erb

Best Practices

✅ Do This:

# Download the platform binary.
curl -sLO .../tailwindcss-linux-x64  # ✅

# chmod and rename.
chmod +x tailwindcss-linux-x64 && mv tailwindcss-linux-x64 tailwindcss  # ✅

# Use the @source directive.
@source "./**/*.go";  # ✅

# Use the --watch in the development.
./tailwindcss -i input.css -o output.css --watch  # ✅

# Use the --minify in the production.
./tailwindcss -i input.css -o output.css --minify  # ✅

# Pin the version for the reproducibility.
curl -sLO .../download/v4.0.0/tailwindcss-linux-x64  # ✅

# Verify the checksum.
sha256sum tailwindcss  # ✅

# Integrate with the Makefile or the build.rs.
build: css  # ✅

❌ Don’t Do This:

# Don't use the latest in the production.
curl -sLO .../releases/latest/download/...  # ⚠️ The unpinned

# Don't skip the checksum.
./tailwindcss  # ⚠️ The integrity

# Don't forget the @source.
@import "tailwindcss";  # ❌ The no classes

# Don't use the Node.js-specific content array.
# The v4 uses the @source.  # ❌

# Don't forget the rerun-if-changed in the build.rs.
// The cargo does not rebuild.  # ❌

# Don't commit the output.
git add public/output.css  # ❌ The generated

Common Pitfalls

The pitfallThe reasonThe fix
The classes not generatedNo @sourceAdd the directive
The binary not executableNo chmodAdd the permission
The wrong platformThe wrong downloadUse the platform file
The build slowThe full scanNarrow the @source
The Cargo not rebuildNo rerun-if-changedAdd the directive
The Rails not rebuildNo tailwindcss:buildAdd the task
The output committedThe generatedUse the .gitignore

Real-World Examples

1. The Download

curl -sLO .../tailwindcss-linux-x64

2. The chmod

chmod +x tailwindcss

3. The Input CSS

@import "tailwindcss";
@source "./**/*.go";

4. The Basic Run

./tailwindcss -i input.css -o output.css

5. The Watch

./tailwindcss -i input.css -o output.css --watch

6. The Go Makefile

css:
	./tailwindcss -i input.css -o output.css --minify

7. The Rust build.rs

Command::new("./tailwindcss").args(["-i", "input.css", "-o", "output.css"]).status();

8. The Rails Install

./bin/rails tailwindcss:install

9. The Rails Tasks

./bin/rails tailwindcss:build

10. The Complete Pattern

./tailwindcss -i input.css -o output.css --minify

Visual

The Standalone CLI

┌────────────────────────────────────────────────────────────┐
│  THE STANDALONE CLI                                        │
│                                                            │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The tailwindcss binary                            │     │
│  │    - The Rust engine                               │     │
│  │    - The Oxide, the Lightning CSS                  │     │
│  │    - The no Node.js                                │     │
│  └────────────────────────┬─────────────────────────┘     │
│                           │                                │
│                           v                                │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The input.css                                     │     │
│  │    @import "tailwindcss";                          │     │
│  │    @source "./**/*.go";                            │     │
│  └────────────────────────┬─────────────────────────┘     │
│                           │                                │
│                           v                                │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The output.css                                    │     │
│  │    The generated utilities                         │     │
│  └──────────────────────────────────────────────────┘     │
└────────────────────────────────────────────────────────────┘

The Go Integration

┌────────────────────────────────────────────────────────────┐
│  THE GO INTEGRATION                                        │
│                                                            │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The Makefile                                      │     │
│  │    build: css                                      │     │
│  │      go build -o bin/server ./cmd/server           │     │
│  │                                                   │     │
│  │    css:                                            │     │
│  │      ./tailwindcss -i input.css -o output.css      │     │
│  └────────────────────────┬─────────────────────────┘     │
│                           │                                │
│                           v                                │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The @source                                       │     │
│  │    "./internal/**/*.go"                            │     │
│  │    "./templates/**/*.templ"                        │     │
│  └────────────────────────┬─────────────────────────┘     │
│                           │                                │
│                           v                                │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The templ classes                                 │     │
│  │    <div class="flex items-center gap-4">            │     │
│  └──────────────────────────────────────────────────┘     │
└────────────────────────────────────────────────────────────┘

The Rust Integration

┌────────────────────────────────────────────────────────────┐
│  THE RUST INTEGRATION                                      │
│                                                            │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The build.rs                                      │     │
│  │    fn main() {                                     │     │
│  │      Command::new("./tailwindcss")                 │     │
│  │        .args(["-i", "input.css",                   │     │
│  │               "-o", "output.css",                  │     │
│  │               "--minify"]).status();               │     │
│  │                                                   │     │
│  │      println!("cargo:rerun-if-changed=src");       │     │
│  │    }                                               │     │
│  └────────────────────────┬─────────────────────────┘     │
│                           │                                │
│                           v                                │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The view! macro                                   │     │
│  │    <div class="flex items-center gap-4">            │     │
│  └──────────────────────────────────────────────────┘     │
└────────────────────────────────────────────────────────────┘

The Rails Integration

┌────────────────────────────────────────────────────────────┐
│  THE RAILS INTEGRATION                                     │
│                                                            │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The Gemfile                                       │     │
│  │    gem "tailwindcss-rails"                         │     │
│  └────────────────────────┬─────────────────────────┘     │
│                           │                                │
│                           v                                │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The application.css                               │     │
│  │    @import "tailwindcss";                          │     │
│  │    @source "../../../app/views/**/*.erb";          │     │
│  └────────────────────────┬─────────────────────────┘     │
│                           │                                │
│                           v                                │
│  ┌──────────────────────────────────────────────────┐     │
│  │  The bin/dev                                       │     │
│  │    web: bin/rails server                           │     │
│  │    css: bin/rails tailwindcss:watch                │     │
│  └──────────────────────────────────────────────────┘     │
└────────────────────────────────────────────────────────────┘

Summary

The itemThe value
The standalone CLIThe single binary
The engineThe Rust, the Oxide
The -iThe input CSS
The -oThe output CSS
The --watchThe rebuild
The --minifyThe production
The @sourceThe class scan
The GoThe Makefile
The RustThe build.rs
The RailsThe tailwindcss-rails

Key takeaways:

  • The standalone CLI is the single binary. It bundles the Tailwind engine and runs without the Node.js, the npm, or the node_modules. The distribution is the download, and the runtime is the none.
  • The download is the platform-specific. The releases cover the Linux, the macOS, and the Windows, on the x64 and the arm64. The checksum is the verification.
  • The @source directive tells the binary where the class names are. The @source "./**/*.go" scans the Go files, and the @source "./templates/**/*.templ" scans the templ. The directive is the v4 replacement for the content array.
  • The -i and the -o are the input and the output. The -i reads the CSS with the @import and the @source, and the -o writes the generated. The --watch rebuilds on the change.
  • The --minify produces the production output. The minified CSS is the smaller, and the CI should run the command.
  • The Go integration is the Makefile. The make css runs the binary, and the make build depends on it. The make css-watch is the development.
  • The Rust integration is the build.rs. The script runs the binary at the Cargo build, and the rerun-if-changed tells the Cargo to re-run on the change.
  • The Rails integration is the tailwindcss-rails gem. The gem manages the binary, and the Rake tasks run the build. The assets:precompile includes the tailwindcss:build.

Remember: The standalone CLI is the Tailwind engine in the single binary. It runs without the Node.js, integrates with the Go, the Rust, and the Rails, and produces the same CSS as the npm package. The result is the CSS in the build pipeline the project already has, and the Node.js is the optional.


Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!