Phoenix’s live reload functionality instantly refreshes your browser when you update a file in your code editor. The experience is beautiful in its simplicity and the Phoenix code that does it is remarkably lightweight as well. Let’s walk through the elegant magic of LiveReload. How is the required code injected into the HTML? When you run to generate a Phoenix app, you’ll see the following in mix phoenix.new web/endpoint.ex: if code_reloading? dosocket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socketplug Phoenix.LiveReloader...end is responsible for injecting the required HTML bits that trigger live reloading. This is a module plug: it transforms the connection by implementing . Phoenix.LiveReloader call/2 actually declares two functions: Phoenix.LiveReloader call/2 There’s a generic function definition ( source ): def call(conn, _) do This injects an iframe into the HTML that will load “/phoenix/live_reload_iframe”. 2. The other **call/2** function definition loads the iframe content by pattern matching against the request path ( source ): def call(%Plug.Conn{path_info: ["phoenix", "live_reload", "frame"]} = conn , _) do This returns HTML that injects the client-side Javascript to connect to the . Phoenix.LiveReloader.Socket How are changes to files observed? The Erlang package is used to listen to changes to files. When the javascript in the iframe joins the channel, begins subscribing to file system changes ( ). [fs](https://github.com/synrc/fs) LiveReloader source Which files are observed? By default, your static assets (javascript, css, etc) and web views and templates. Have you deployed a Phoenix app? Try Scout, a new Elixir app monitoring solution I helped develop. . Signup is free How does LiveReload listen for changes? After is called, the channel process listens for message events by defining ( ): :fs.subscribe/0 fs handle_info/ source def handle_info({_pid, {:fs, :file_event}, {path, _event}}, socket) do This receives file events on the filesystem. Since we only care about a subset, checks to see if the file is within our Phoenix app. all matches_any_pattern?/2 Then, we send a message via the channel notifying of the change: push socket, "assets_change", %{asset_type: asset_type} How does the Javascript code refresh the page? The JS listens for the event and updates the window in one of two ways: assets_change When a css file is changed, a full reload isn’t required. Instead, a new link element is inserted in the page that loads the updated stylesheet. When a file of any other type is changed, a full window reload is triggered. Summary LiveReload weaves an interesting path through your app: inserting a plug to inject content into the HTML, rendering an iframe, inserting Javascript into the iframe and subscribing to a channel, listening for filesystem events, sending messages via the channel on relevant events, and finally, reloading your browser window. . View the source on GitHub