After the Phoenix 1.6 esbuild switch, who should pin Elixir/OTP versions for a team?
0 reputation · 21 Nov 2025, 08:52 UTC
0 reputation · 21 Nov 2025, 08:52 UTC
Since Phoenix 1.6 replaced the webpack/Node.js asset build with esbuild (and 1.7 made Tailwind the default), the asset toolchain is now reproducible through Hex: the esbuild and tailwind packages download pinned binaries based on versions set in config/config.exs, and mix assets.setup / mix assets.deploy replace any npm step. That part of a repeatable dev environment seems settled.
What Phoenix does not manage is the Elixir and Erlang/OTP versions themselves. mix.exs declares only a minimum Elixir requirement, so two developers (or CI) can run different OTP releases against the same codebase. The apparent options are a .tool-versions file with asdf or mise, a Nix flake, or a Docker-based environment — but the Phoenix docs do not endorse one canonical approach.
35775 reputation · 21 Nov 2025, 18:24 UTC
Phoenix does not provide a built-in mechanism to pin Elixir or Erlang/OTP versions. While the 1.6+ asset toolchain (esbuild and Tailwind) is pinned via Hex packages and config/config.exs, the runtime environment remains the responsibility of the development team. To ensure parity across local environments and CI, teams should use an external version manager or containerization strategy.
Since the framework is agnostic to the runtime manager, the community standard is to use one of the following three patterns:
.tool-versions file in the project root. This is the most common approach for Elixir teams, as it allows developers to switch versions automatically upon entering the directory.elixir:1.x-otp-2x-alpine image tag in your Dockerfile. This is the primary method for ensuring CI and production parity.When migrating a pre-1.6 app from Webpack to esbuild, you should decide and implement your version-pinning strategy before the asset migration. Because CI must reproduce the build, having a locked Elixir/OTP version prevents "ghost" failures where asset compilation succeeds on a developer's machine but fails in CI due to a mismatch in the underlying BEAM version or environment variables.
There are no direct compatibility constraints between specific OTP releases and the esbuild or tailwind Hex wrappers. These wrappers download standalone binaries that execute independently of the Erlang VM. However, you must still respect the following dependencies:
mix.exs.To verify your current environment alignment, run the following commands across different team machines:
elixir -v
# Compare the Elixir and OTP versions listed in the output
Check your config/config.exs to ensure asset versions are explicitly set, for example:
config :esbuild, version: "1.28.0"
config :tailwind, version: "3.0.0"
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.