Cannot run Tailwind CSS with Elixir Phoenix 1.8 project

I am trying the Elixir - Phoenix 1.8 Up and Running guide and it does not work:

$ nix# mix phx.server
Could not start dynamically linked executable: /home/me/dev/playground/elixir/phoenix/hello/_build/tailwind-linux-x64
NixOS cannot run dynamically linked executables intended for generic
linux environments out of the box. For more information, see:
https://nix.dev/permalink/stub-ld
[info] Running HelloWeb.Endpoint with Bandit 1.8.0 at 0.0.0.0:4000 (http)
[info] Access HelloWeb.Endpoint at http://localhost:4000
Could not start dynamically linked executable: /home/me/dev/playground/elixir/phoenix/hello/_build/tailwind-linux-x64
NixOS cannot run dynamically linked executables intended for generic
linux environments out of the box. For more information, see:
https://nix.dev/permalink/stub-ld
[watch] build finished, watching for changes...

Tailwind CSS cannot run so no css is available for the Up and Running startup Phoenix app.

After following the help link https://nix.dev/permalink/stub-ld, I added pkgs.tailwindcss_4 to my mkShell:

pkgs.mkShell {
  buildInputs = basePackages ++ [
    pkgs.poedit
    pkgs.tailwindcss_4
    vscodeWithExtension
  ]
  ++ optional pkgs.stdenv.isLinux pkgs.libnotify
  ++ optional pkgs.stdenv.isLinux pkgs.inotify-tools;

  shellHook = ''
    export ROOT_DIR="$PWD"
    export LANG=C.UTF-8
    # Erlang/Elixir environment
    export MIX_HOME="$ROOT_DIR/.mix"
    export HEX_HOME="$ROOT_DIR/.hex"
    # Elixir iex shell history https://hexdocs.pm/iex/IEx.html#module-shell-history
    export ERL_AFLAGS="-kernel shell_history enabled"
  '';
};

But I am still having the same error. I am not sure what to do next, I feel a bit lost with this. Does anyone have any idea how to make that work?

Also, the nixpkgs manual about Phoenix project could benefit from an update.

I’ve the same experience, and while I do not have a correct solution, my workaround has been to manually replace the two binaries tailwind-linux-x64 and esbuild-linux-64 that the mix tool installs under <your-project>/_build with symlinks to the ones installed by nix.

1 Like

Forgot to mention that I added also pkgs.esbuild to the buildInputs, like you did with tailwindcss_4.

Hi, I just ran into this same issue, and found this solution to work for me:

TL;DR: Remove the Tailwind Mix package and configure Phoenix to use nix-installed tailwindcss + watchman for live CSS watching.

Same as you I added tailwindcss_4 to the shell, but I also added the watchman package, since we later have to modify the watch commands for phoenix to be able to use our nix version of tailwindcss.

This is my first post on the nixos discourse, so not completely sure what the normal way to answer is, but i will use some git diffs to show my solution.

You can remove this part:

--- a/config/config.exs
+++ b/config/config.exs
@@ -54,17 +54,6 @@ config :esbuild,
     env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]}
   ]
 
-# Configure tailwind (the version is required)
-config :tailwind,
-  version: "4.1.7",
-  project: [
-    args: ~w(
-      --input=assets/css/app.css
-      --output=priv/static/assets/css/app.css
-    ),
-    cd: Path.expand("..", __DIR__),
-  ]

Use tailwindcss and watchman directly to watch for css changes:

--- a/config/dev.exs
+++ b/config/dev.exs
@@ -26,7 +26,7 @@ config :project, Project.Endpoint,
   secret_key_base: "secret",
   watchers: [
     esbuild: {Esbuild, :install_and_run, [:project, ~w(--sourcemap=inline --watch)]},
-    tailwind: {Tailwind, :install_and_run, [:project, ~w(--watch)]}
+    tailwind: {System, :cmd, ["tailwindcss", ["--input=assets/css/app.css", "--output=priv/static/assets/css/app.css", "--watch"], [cd: File.cwd!()]]}
   ]

And remember to remove the tailwindcss mix package:

--- a/mix.exs
+++ b/mix.exs
@@ -53,7 +53,6 @@ defmodule CrmSirkusagio.MixProject do
       {:lazy_html, ">= 0.1.0", only: :test},
       {:phoenix_live_dashboard, "~> 0.8.3"},
       {:esbuild, "~> 0.10", runtime: Mix.env() == :dev},
-      {:tailwind, "~> 0.3", runtime: Mix.env() == :dev},
       {:heroicons,
        github: "tailwindlabs/heroicons",
        tag: "v2.2.0",
@@ -84,10 +83,10 @@ defmodule project.MixProject do
       "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
       "ecto.reset": ["ecto.drop", "ecto.setup"],
       test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
-      "assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"],
-      "assets.build": ["tailwind project", "esbuild project"],
+      "assets.setup": ["esbuild.install --if-missing"],
+      "assets.build": ["cmd tailwindcss --input=assets/css/app.css --output=priv/static/assets/css/app.css", "esbuild project"],
       "assets.deploy": [
-        "tailwind project --minify",
+        "cmd tailwindcss --input=assets/css/app.css --output=priv/static/assets/css/app.css --minify",
         "esbuild project --minify",
         "phx.digest"
       ],
``
1 Like

@JonasThowsen Great, based on your comment and understanding a bit more about Tailwind, this is what I came to, which seems like an even smaller change:

diff --git flake.nix flake.nix
index 5b43ff8..dac6109 100644
--- flake.nix
+++ flake.nix
@@ -52,29 +52,30 @@
           default = pkgs.mkShell {
             buildInputs = basePackages ++ [
               pkgs.poedit
               pkgs.tailwindcss_4
               vscodeWithExtension
             ]
             ++ optional pkgs.stdenv.isLinux pkgs.libnotify # For ExUnit Notifier on Linux.
             ++ optional pkgs.stdenv.isLinux pkgs.inotify-tools; # For file_system on Linux
 
             shellHook = ''
               export ROOT_DIR="$PWD"
               export LANG=C.UTF-8
               # Erlang/Elixir environment
               export MIX_HOME="$ROOT_DIR/.mix"
               export HEX_HOME="$ROOT_DIR/.hex"
               # Elixir iex shell history https://hexdocs.pm/iex/IEx.html#module-shell-history
               export ERL_AFLAGS="-kernel shell_history enabled"
+              export TAILWINDCSS_PATH="${pkgs.lib.getExe pkgs.tailwindcss_4}"
             '';
           };
 
         };
       }
     );
 
   nixConfig.bash-prompt-suffix = ''\[\e[1;35m\]nix# \[\e[0m\]'';
 }
diff --git config/config.exs config/config.exs
index 54c28b5..77301a3 100644
--- config/config.exs
+++ config/config.exs
@@ -44,21 +44,22 @@ config :esbuild,
 
 # Configure tailwind (the version is required)
 config :tailwind,
   version: "4.1.11",
   hello: [
     args: ~w(
       --input=assets/css/app.css
       --output=priv/static/assets/css/app.css
     ),
     cd: Path.expand("..", __DIR__)
-  ]
+  ],
+  path: System.get_env("TAILWINDCSS_PATH")
3 Likes