Setting up Vite with Phoenix

I’d like to use Vite with Phoenix on a new project and have run into questions that I haven’t seen discussed.

  1. When starting up, are ya’ll running npx create-vite . in the ./assets directory? If yes, are you removing everything else in the directory?
  2. Are you running the Vite dev server alongside the Phoenix server?
  3. How are you handling both custom css and tailwindcss?
  4. I’ve noticed the following code example and am wondering why 3000 is specified since that is neither Vite’s or Phoenix’s default port.
<%= if dev?() do %>
  <script type="module" src="http://localhost:3000/@vite/client"></script>
  <script type="module" src="http://localhost:3000/js/app.js"></script>
<% else %>
  <link phx-track-static rel="stylesheet" href={Routes.static_path(@conn, "/assets/app.css")}/>
  <script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/app.js")}></script>
<% end %>

Maybe I should be asking if anyone has the series of steps to setup Vite with Phoenix in 2024? :thinking:

Thanks all :slight_smile:

The default used to be 3000 around V2. But the half-life period in the js ecosystem is so short, that stuff becomes outdated by the hour it seems.


Hey, @woohaaha. I have a repo for this - GitHub - c4710n/phoenix_custom_assets: Provides an alternative assets/ of Phoenix for using LiveView and TailwindCSS..

It’s quite a coincidence; I just marked this repository as archived yesterday because I found a simpler method -

But, you can still follow the repo, it has detailed instructions on how to setup.

Edit: Sorry for replying wrong people.


Is there a particular plugin you need that is not available for esbuild?

A lot can be accomplished with esbuild which vite wraps anyway. Vite whilst faster than most bundlers (due to esbuild) is still slower than just using esbuild.

1 Like

I’ve recently setup a similar stack. I found these guide to be extremely helpful and kind of picked and chose between both similar approaches.

Basically, I set things up in frontend folder, but could also have been in the assets folder too. I run Vite in a separate process (using the mix watchers) on port 3000, with Vite dev server producing requests to port 4000 where phoenix is running. 90% of the time I access the app on port 3000 (Vite) during development.

I also have the Vite production build copy directly to the phoenix assets directory and can easily do a build and access the full app on port 4000 at any time. I have a catch all controller that serves up the dist index.html file.

I’m very comfortable with React and the tool chains and find myself very productive, though phoenix is really just acting as an API server for now.

1 Like

I was under the impression that esbuild does not support HMR ( Hot Module Replacement)

I was sort of hoping to have a phoenix watcher for vite but by doing so there’s no HMR as far as i could tell. It did work in another process but I didn’t want 2 terminal windows in dev. :thinking:

This explains the reload approach in Phoenix with LiveView:

Now the OP didn’t mention liveview, however in Phoenix app the state is managed on the server so it will trigger a reload to get the updated state and render using the new code.

If it’s not Pheonix LiveView then HMR will probably be required to not lose the state held on the client.