arcanemachine

arcanemachine

Tailwind CSS RISC-V Node Wrapper - a Linux RISC-V compatible Tailwind CSS v4 CLI distribution

I (with the help of an LLM-based agent) put together a Node-backed Tailwind CSS v4.3.1 wrapper for Linux RISC-V GNU systems:

This repo offers a prebuilt binary and a simple tailwindcss CLI wrapper. The binary is reproducible using a simple Docker-based workflow.

This came out of trying to run a Phoenix app on a Scaleway RISC-V server running Ubuntu 24.04. Phoenix’s tailwind package could not download an official Tailwind binary for riscv64-unknown-linux-gnu, and Tailwind’s official standalone binary path depends on Bun. Bun does not currently provide a Linux RISC-V target, so the official single-file Tailwind standalone binary is not available there.

DISCLAIMER: I built this to scratch an itch for a weekend project, and have only run this in a :dev config environment. Everything appears to work, but this is presented as an experimental proof-of-concept, and nothing more. I just thought it was cool and wanted to share it.


This package is not Tailwind’s official standalone binary. It is a self-contained tarball distribution with:

  • A wrapper (bin/tailwindcss) that provides a compatible interface for the :tailwind Mix package.
  • bundled Node
  • pinned @tailwindcss/cli / tailwindcss
  • the Linux RISC-V native addons needed by the Node CLI

It does not need npm at runtime, and it does not require app-local Tailwind node_modules. It does need the extracted package directory to remain intact, because bin/tailwindcss is a wrapper around the bundled runtime.

For Phoenix, the important part is to point the Elixir Tailwind config at the wrapper and disable the version check.

config/config.exs

  config :tailwind,
    version: "4.3.1",
+   path: "/path/to/tailwindcss-riscv64-linux-gnu-v4.3.1/bin/tailwindcss",
+   version_check: false,
    hello_phoenix: [
      args: ~w(
        --input=assets/css/app.css
        --output=priv/static/assets/css/app.css
      ),
      cd: Path.expand("..", __DIR__),
      env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]}
   ]

Also remove tailwind.install --if-missing, because the Elixir Tailwind downloader does not provide a Linux RISC-V binary.

mix.exs

defp aliases do
  [
-   "assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"],
+   "assets.setup": ["esbuild.install --if-missing"],
    "assets.build": ["compile", "tailwind hello_phoenix", "esbuild hello_phoenix"],
    "assets.deploy": [
      "tailwind hello_phoenix --minify",
      "esbuild hello_phoenix --minify",
      "phx.digest"
    ]
  ]
end

I built and verified this on Ubuntu 24.04 LTS on a Scaleway RISC-V server. Phoenix asset build/deploy worked, and the rendered page was styled correctly in the browser, and works correctly with Phoenix’s built-in hot reload feature.

The long-term upstream fix is still Bun support for Linux RISC-V, or a different official Tailwind standalone build path that does not depend on Bun. Until then, this gives Phoenix apps a technically-usable Tailwind v4 path on Linux RISC-V.

Most Liked

olivermt

olivermt

Hi,

You could also pr risc support (if zig needs it?) into BeaconCMS’s compiler.

Once Brian merges my pr ( Add streaming candidate extraction by olivermt · Pull Request #2 · BeaconCMS/tailwind_compiler · GitHub ) then you should have all of tailwind in a box without needing node.

Where Next?

Popular in Announcing Top

danschultzer
In short Plug n’ play OAuth 2.0 provider library. Just set up a resource owner schema with Ecto (your user schema), install the dependen...
New
ityonemo
Currently just starting out on a new mini-project - getting zig NIFs to run in elixir. https://github.com/ityonemo/zigler The idea here...
New
mtrudel
Bandit is an HTTP server for Plug and WebSock apps. Bandit is written entirely in Elixir and is built atop Thousand Island. It can serve...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
oltarasenko
Dear Elixir community, After a year of development, bug fixes, and improvements, we are proudly ready to share the release of Crawly 0.1...
New
type1fool
WebAuthnLiveComponent WebAuthnComponents See this post about renaming the package. Passwordless authentication for Phoenix LiveView app...
New
sbs
Only 650 LOC, wrote for fun :slight_smile: https://github.com/sunboshan/qrcode
New
mindok
What is ContEx? A pure Elixir server-side data plotting/charting library outputting SVG. It has nice barcharts in particular and works g...
New
Jskalc
Hi! Today, after a couple weeks of development I’ve released v0.1 of LiveVue. It’s a seamless integration of Vue and Phoenix LiveView, i...
New
tfwright
After working on it for a couple of months and using it in production for most of that time, today I’ve released LiveAdmin, a LiveView ba...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29603 241
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43487 311
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54120 245
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement