The Phoenix Files

Phoenix and LiveView applications are awesome on Fly.io! This is the home for Phoenix-oriented content ranging from Ecto to LiveView and more.

By Mark Ericksen

Abusing LiveView's new Async Assigns Feature

Previously, in Star-Crossed LiveView Processes, we explored using Elixir’s linked processes to connect a Task and a LiveView together. This required doing some extra work like trapping exits and handling received EXIT messages, but, in the end it wo

Read more
By Jason Stiebs

Elixir and Phoenix can do it all!

As an Elixir/Phoenix developer going on 10 years it is very easy to take for granted everything that Elixir and Phoenix can do for us. So I wanted to take a step back and list all of the stuff that we get for free when we choose Elixir and Phoenix.

Read more
By Mark Ericksen

ChatGPT doesn't know what day it is?

It turns out ChatGPT doesn’t know anything about the date or day of the week! When that’s needed for your application, how can we solve it? Fortunately, Phoenix LiveView and hooks make it easy to get the user’s timezone from the browser for localizin

Read more
By Mark Ericksen

Created my Personal AI Fitness Trainer in 2 Days

This post introduces how I created an AI Personal Fitness Trainer named “Max” that acts in a way that works best for me. In 2 days I had a new workout buddy and it has reignited my fitness excitement! I quickly had a weekly fitness program that works

Read more
By Jason Stiebs

LLaMa on a CPUs

Large Language Model (LLM) based AI models are all the rage and running them typically requires a pretty beefy GPU or paying for Open AI API access. At the moment, Fly.io’s GPUs aren’t publicly available, but I still wanted to join in the fun. So I w

Read more
By Mark Ericksen

Announcing LangChain for Elixir

I created an Elixir LangChain library called “langchain” on Hex.pm. I didn’t invent the idea of LangChain. In fact, it was originally created in Python and JS/TS. I wanted something similar to exist for Elixir and Phoenix applications. What is LangCh

Read more
By Jason Stiebs

DIY Lambda

At Fly.io, we make it super easy to spin up new apps and scale them to Machines distributed around the globe. Also, Elixir is uniquely suited to take advantage of this distributed global network. In this post I am going to show you how to use both to

Read more
By Mark Ericksen

Customizing Phoenix Generators

During my interview with Victor Björklund, I learned how easily the Phoenix generators can be customized for our projects. I was shocked I that I never knew about it and I don’t recall ever seeing it documented. This post is to document this invisibl

Read more
By Jason Stiebs

Streaming Uploads with LiveView

Time to face reality. Sending files over the internet via a web browser is not a solved problem. There has been so many bytes spilled on the varied ways of accepting, uploading, streaming, verifying, storing, backing up, and sharing files from a use

Read more
By Mark Ericksen

Star-Crossed LiveView Processes

Ever wanted to create something like a ChatGPT interface that asynchronously streams in a response? I have! Assuming we’re building it with LiveView, then we want to run that streaming conversation in a separate process because we don’t want to block

Read more
By Jason Stiebs

BEAM Clustering made easy

One of the reasons Fly.io is so great for Elixir and Phoenix is that we have servers in nearly every region on the globe, and they are all connected via built in WireGuard networking. As an Elixir developer, this is an incredible opportunity because

Read more
By Jason Stiebs

Let's search all of Elixir's Packages!

I love ExDocs, I think they are one of the best parts about the Elixir Ecosystem and I frankly cannot shut up about it. My one complaint is that it can sometimes be hard to find exactly what you are looking for using ExDoc’s built in search. My favo

Read more
By Berenice Medel

Sorting and Deleting many-to-many assocs with Ecto and LiveView

Ecto enables us to effortlessly work with different types of associations. In a many-to-many relationship, we can easily insert, modify, or delete elements. However, what if we want to sort the elements in a specific order? How can we remove specific

Read more
By Jason Stiebs

Elixir Docs are Built Different

A few common refrains from developers who are new to Elixir are: “Where are the blog posts?” “Stack Overflow?” “Google was no help…” And I totally get it, if you come from another language ecosystem, you would be right to prioritize tutorials or

Read more
By Jason Stiebs

for Can Do More

Elixir has a for special form called a “list comprehension” and not enough people know what it can do. It can do so much more than a simple for loop, it is kind of like if the Enum and Stream modules got together and had a macro. And I want you to k

Read more
By Berenice Medel

Using Ctrl+Enter to submit a Text Area with LiveView

Problem You have a text area for sending long messages. Users should be able to submit without moving their hands from the keyboard. Pressing Enter only creates a new empty line instead of sending the message: Solution You can define a Hook that lis

Read more
By Jason Stiebs

A LiveView is a Process

LiveView lets users get up to speed quickly by being easy to learn, especially with the familiar mount, render and event handler system that React developers will immediately recognize. But LiveView differs from other front-end frameworks in one very

Read more
By Noah Betzen

Adding Dialyzer without the Pain

This post is about how to start using Dialyzer on an established Elixir project without losing your mind in the process. If you’ve been in the Elixir community for any length of time, you’ve probably heard about Dialyzer. It’s tool that does static c

Read more
By Jason Stiebs

Speed up your boot times with this one Dockerfile trick

Problem You added Whisper text to speech transcription to your voice chat app and while it works great… the boot times on your deployment have slowed to a crawl. Or maybe you really love deploying your apps using single file elixir scripts but are fin

Read more
By Mark Ericksen

Migrating to Verified Routes

Verified Routes were introduced in Phoenix 1.7. The upgrade guide strongly suggests upgrading to Phoenix 1.7 first and keeping your routes the same to begin with. Then later, you can migrate the routes as needed. Well, it’s later. Now let’s figure o

Read more
By Berenice Medel

Dynamic forms with LiveView Streams

You developed a component that lets you add and remove items in a “has_many” relationship. Take, for example, a shopping list where it can have many items. You’ve got a cool form that lets you send data for new items, and it works really well: How

Read more
By Mark Ericksen

Taking Control of Map Sort Order in Elixir

If you’ve recently upgraded to Elixir 1.14.4 and OTP 26, you may have noticed that map keys are no longer showing in a predictable order. Fear not! Understanding why it’s happening and taking the time to sort the keys by default can save you some hea

Read more
By Jason Stiebs

Streaming OpenAI responses

Problem You are building an application that interfaces with OpenAI’s ChatGPT and want to create a real time interactive experience just like the OpenAI Chat UI. To do this we will need to work with the ChatGPT Streaming API, which is built using th

Read more
By Mark Ericksen

Loading a structure.sql file on Prod without mix

Problem At some point, you or your team ran mix ecto.dump and generated a priv/repo/structure.sql file. Then old migrations files were removed. Things were great and you could handle the local dev and test setup using mix ecto.load. If you were migrat

Read more
By Jason Stiebs

Tensors and Nx, are not just for machine learning

The Elixir community has a sleeping giant brewing with Nx, and not just for Machine Learning. Nx allows you to describe nearly any numerical operation, which can then be run in an optimized environment for such operations. If you read the Nx README i

Read more
By Mark Ericksen

Developing after mix ecto.dump

Problem At some point, you or your team decided to cut the dead weight of many old migrations and instead run mix ecto.dump and generate a priv/repo/structure.sql file. Now you want to bootstrap a new staging server, dev environment, or just get setu

Read more
By Berenice Medel

Building a Drag-and-Drop List with LiveView and SortableJS

In this post, we’ll create a List component with draggable and droppable elements functionality. We’ll use some components from core_components.ex to design the List component, and then add the necessary logic to implement its behavior. The end resul

Read more
By Jason Stiebs

Minimum Viable ChatGPT Plugin

Problem You just got access to the ChatGPT Plugin beta, and you want to hook up your database of knowledge to the AI GPT4, so it can help you and customers navigate your complex world. You’ve never done that, and all of their docs are in Python… Solut

Read more
By Chris McCord

Phoenix LiveView Zipped Uploads

File and image uploads in LiveView are already easy and elegant. But what if the user wants to upload an entire directory with more nested directories and files? How should we handle that? Chris McCord walks us through what it takes to make that a go

Read more
By Jason Stiebs

Elixir and Rust is a good mix

Problem We need to perform a CPU intensive or system level programming task and there are just no good solutions in hex.pm, in this example let’s pretend there are no good ways to do image processing with Elixir. As is often the case, there IS a high

Read more
By Mark Ericksen

Can Phoenix Safely use the Zip Module?

A lot of cool stuff is available in Erlang’s OTP Standard Library. Elixir has the ability to directly use everything in OTP and that means we have a number of built-in features available to us. One of those features is the Erlang :zip module. As the

Read more
By Jason Stiebs

Crafting your own Static Site Generator using Phoenix

The year is 2023, you have many options for building a Static Website. From the OG Jekyll to literally hundreds of JavaScript based options to people suggesting you should just craft HTML by hand. All of these solutions are correct and good, and you

Read more
By Sophie DeBenedetto

Building a Chat App with LiveView Streams

In this post, we’ll build out a LiveView chatroom app with the help of LiveView’s new streams feature. You can follow along in the open source codebase or skip ahead to play around with the finished product. We’ll see how streams seamlessly integrate

Read more
By Berenice Medel

Using LiveView's new primitives for accessibility

In previous posts, Nolan showed us some ways to improve accessibility in existing web applications using the Phoenix real-time social music app LiveBeats as an example. But what if we could integrate accessibility practices into our app developmen

Read more
By Chris McCord

Phoenix Dev Blog - Sounds Like a Bug

I’ve had my fair share of bug reports over the ~10 year life of maintaining Phoenix. Most are mundane Elixir tweaks, or wrangling some JavaScript issues. The core of Phoenix has been baked for years now, so color me surprised when I found myself spel

Read more
By Jason Stiebs

Resizing Images using Elixir

When building web applications we accept user uploaded images and later want to use them as in our applications. This leads to many questions: What format will their device upload? Which format do we accept? Which format do we use? How many bytes i

Read more
By Jason Stiebs

Single File Elixir Scripts

Elixir has powerful built in scripting functionality, allowing us to write Elixir to a file—say my_script.exs— and execute it directly by elixir my_script.exs. The vast majority of production Elixir projects will be directly compiled via mix with al

Read more
By Chris McCord

Phoenix Dev Blog - Streams

This is the first installment of the Phoenix development blog where we’ll talk about in progress features or day-to-day development updates in between major releases and milestones. What’s the Problem? For at least a few years, the Phoenix team has w

Read more
By Jason Stiebs

Phoenix LiveView and SQLite Autocomplete

In our last post we saw an example of how we could use the built-in Full Text Search capability, FTS5, of SQLite3 to create a search index and query it with Ecto. We also know it’s fast to query and especially so since it is in memory. Let’s see how

Read more
By Lubien

Pass User Agent info to your LiveView

Here’s a quick recipe. Say your LiveView needs to show something based on the device your user is on such as Mac or Windows. You can parse that from your User Agent header, in fact LiveView already gives you a simple method for that: get_connect_info

Read more
Tag all the things
Part 2

Making a CheckboxGroup Input

UPDATED: This was updated to support clearing a list of tags. The underlying tag functions were updated and a hidden input ensures a value is passed. See the updated gist as well. Phoenix 1.7.0 brings a lot of new things when we run mix phx.gen my_a

Read more
By Berenice Medel

Custom styling with LiveView function component attributes

Problem You’re writing a new function component that has default styling. You’ve defined default CSS classes in the component’s template, but you want it to have the flexibility to add a few others when calling the function. How can we give a compone

Read more
SQLite3 Full Text Search
Part 1

SQLite3 Full Text Search with Phoenix

One of the benefits of SQLite is that you can query lightning quick because your database is colocated next to your server. And a bonus it also comes with built-in Full Text search capabilities! But how does this work with Ecto? In this Series we wi

Read more
Tag all the things
Part 1

Tag All the Things!

UPDATED: This was updated to support clearing a list of tags from a UI input component. Whether you link labels to a Github issue, track the different muscle groups strengthened by an exercise, or describe a book by the set of genres that apply to i

Read more
By Jason Stiebs

Copy to Clipboard with Phoenix LiveView

Problem When you need to make sure a user copies an important string of text, don’t let their mouse and keyboard stand in the way. Give them a button to press so they don’t need to manually move a cursor around. But how might you do this with LiveVie

Read more
By Berenice Medel

Async processing in LiveView

Last month Chris McCord developed an amazing single-file example for doing image classification using Bumblebee, Nx and LiveView. We can see all the parts together in one place, and run the example just with a single command… it must be said, it’s im

Read more
By Mark Ericksen

Flying with a Fledgling Phoenix

Phoenix is a living, breathing and active project. Prior to the release of a new major version, there is often a “release candidate” for people to test out and report issues. Getting and trying those pre-release versions isn’t straight forward. We’ll

Read more
By Berenice Medel

Bringing Phoenix Authentication to Life

Many of us used the phx.gen.auth generator to quickly build out authentication systems in our Phoenix apps. It spits out well-designed auth logic so we can get on quickly to the more interesting parts of our app. But LiveView has increased in popula

Read more
By Lubien

Persistent forms with your URL on LiveView

Problem Say you have a simple posts search form LiveView like this one: Whenever users change the title or author on the search form you perform the search just fine but whenever you hit the refresh button your filters are emptied, poof. We did not

Read more
By Alexander Koutmos

Elixir, OpenTelemetry, and the Infamous N+1

In this article, we’ll dive into the topic of observability and specifically the OpenTelemetry project. We’ll see how to set up the Elixir and Erlang OpenTelemetry libraries in a Phoenix LiveView application so you can debug troublesome database quer

Read more
By Mark Ericksen

Github Actions for Elixir CI

A critical ingredient for modern development teams is a regularly run set of code checks. If it’s up to every developer to run code tests and checks locally before pushing code, you know it will be forgotten at some point. This leaves it as a problem

Read more
By Chris McCord

Shutting down a Phoenix app when idle

Edit - Apr 14th 2023 Since the writing of this post, we’ve rolled out V2/machines apps on Fly.io. V2/machine apps are now the default for new organizations. And we encourage existing ones to create new V2/machine apps. Which mean you can use this

Read more
By Berenice Medel

Migrating to LiveView v0.18

LiveView 0.18 is here, bringing new and exciting features to try! In this post we’ll talk about errors that may appear when migrating your project from LiveView v0.17 to v0.18, and how to deal with them. Migrated Functions Some of the errors that yo

Read more
By Mark Ericksen

Plucking the 'A' from PETAL

Recently, LiveView has matured greatly. A recent feature in v0.18, covered by Chris McCord in his ElixirConf 2022 keynote, is the addition to declarative assigns (think the old React/Vue props). This feature improves the developer experience when cr

Read more
By Jaeyson Anthony Y.

Infinitely Scroll Images in LiveView

We see plenty of examples around the web of infinite scrolling content. Phoenix LiveView gives us some nifty abilities to do this elegantly and smoothly without needing any frontend frameworks. In this post we’re going to build a very simple infinit

Read more
By Berenice Medel

Testing LiveView forms

In previous posts we’ve used forms for different purposes, but we’ve never talked about how to test that our app does the right thing when a form is submitted. In this post we’ll take a walk around some functions of the LiveViewTest module that com

Read more
By Berenice Medel & Mark Ericksen

Live sessions in action

Phoenix LiveView often makes us feel like “wow, that was really fast!” and that is not a coincidence. Behind LiveView’s magic, there are a bunch of design decisions, but also interesting features we can use. Under the umbrella of LiveView navigatio

Read more
By Berenice Medel & Chris Nicoll

Triggering a Phoenix controller action from a form in a LiveView

Have you ever wanted to use LiveViews for a site’s authentication? Among many other implementation details, you need to save some data to identify the logged-in user. This can be a token or some unique identifier, and it needs to persist even as the

Read more
By Mark Ericksen

Making Tabs Mobile Friendly

This recipe creates a Tailwind UI styled tab component that gracefully switches to an HTML select input when viewed on smaller screens. It doesn’t use Alpine.js or other client-side javascript frameworks for managing the UI. It is built as a client-s

Read more
By Chris McCord

Phoenix LiveView Tailwind Variants

Problem Users of Tailwind CSS know the productivity gains the utility-first CSS framework provides. One of Tailwind’s biggest advantages is that you can rapidly build applications without ever leaving your HTML. There’s no context-switching between ma

Read more
By Mark Ericksen

Set Up VSCode for Elixir Dev

Since Elixir and Phoenix appeared prominently in the Stack Overflow Survey Results for 2022, more people have been discovering the joy of Elixir and the power of LiveView. This article introduces developers to getting the popular VS Code editor up and

Read more
By Berenice Medel

Triggering JS from the server in LiveView: showing a spinner

It’s always frustrating when we click something—and it looks like nothing’s happening. The default solution to this is to throw up a spinner while the server is chewing on a request, to help users resist the temptation to keep clicking. UX win! We ca

Read more
By Berenice Medel

A reusable Multi-Select component for Phoenix LiveView

Have you ever wanted a feature that lets your users select multiple items from a list, and performs some action on their selection? This is a really common thing to do, and it can be pretty involved to build. What do we do when we don’t want to write

Read more
By Philip Brown

Recognize digits using ML in Elixir

(Updated March 2023 by Tom Berman for the official Axon releases.) Machine learning allows you to solve problems that were once totally unimaginable. The ability for a computer to take an image and tell you what it sees was once only possible in sci

Read more
By Berenice Medel

Formatting the user's local date-times using Hooks

Problem When we’re developing an application for users around the world, we are bound to hit problems with timezones. Often we decide to store the dates in UTC format to avoid storing the timezone of each user. This brings us to the real problem, “Ho

Read more
By Sophie DeBenedetto

Easy UI Toggling with LiveView JS Commands

LiveView empowers developers to be more productive than ever before by keeping your mind firmly focused on the server, even while you build out rich interactive UIs. But until recently, we were somewhat limited by LiveView’s reliance on server-side s

Read more
By Berenice Medel & Chris Nicoll

Loading indicators for events with JS.push

Problem Phoenix/LiveView apps involve a lot of interaction between the client and the server. We want to customize how we indicate to users that our UI is waiting for a server response to some event. Specifically, we’d like to see a general-purpose lo

Read more
By Mark Ericksen

Exploring Options for Storing Custom Data in Ecto

Ever wanted to store a blob of custom data on a database record? The data we want to store might be complex too, made up of multiple fields and even lists. When the data is stored using Ecto there are several ways we can do it. This article explores

Read more
By Berenice Medel & Chris Nicoll

Pushing Events: with and without JS.push

LiveView DOM element bindings can be used to send events to the server, as well as issue LiveView JS commands on the client. In another post, we used client-side JS commands to show and hide content in a set of tabs, just by manipulating DOM element

Read more
By Sophie DeBenedetto

LiveView card components with Bootstrap

You may already be reaching for LiveView components to wrap up the behavior and markup of distinct portions of your LiveView UI. In this post, we’re going to take a single-purpose component that displays book review data in Bootstrap-style card form

Read more
By Mark Ericksen

Build Simple Reusable Widgets Using Slots

A new feature in LiveView called “slots” can help make your components more composable and reusable. This post is about getting started with slots to build a simple component. Problem You have a design element that is used repeatedly in your site. Rat

Read more
By Berenice Medel & Chris Nicoll

Client-Side Tabs in LiveView with JS Commands

There are some things it really does make sense for our LiveView to do without calling home. Simple things that the browser doesn’t need help with. Things we’d like to see happen instantly, like hiding a modal—maybe even with a transition animation.

Read more
By Mark Ericksen

LiveView feels faster with a delayed loading indicator

LiveView is already fast. Couple that with hosting it on Fly.io where the server can be physically closer to your users and you’ve already got a great experience. However, the default setup for a new LiveView application displays the topbar progress

Read more
By Berenice Medel & Chris Nicoll

Reuse markup with function components and slots

The problem We’d like a way to reuse code for UI components that are very similar in structure, but carry different content. Imagine we’re writing a Phoenix LiveView app that frequently uses modals to display or save information. For a consistent exp

Read more
By Berenice Medel

Keep LiveViews alive across live redirects

Problem You are building a website for listening to your favorite songs. You want to play or pause the current song while you are adding songs to your playlist or even editing your profile. You create a LiveView to handle the player controls and show

Read more
By Mark Ericksen

Passing Unknown Attributes into Your Component

On your LiveView page, you are using a custom component. You want to be able to pass HTML attributes into the component, but the component doesn’t know anything about the attributes being passed! You need a way to pass arbitrary attributes through an

Read more
By Mark Ericksen

Restore LiveView State on Startup

You are storing some LiveView state in the browser. You want to retrieve that saved state as early as possible to improve the user experience. How can you do that? Problem The approach in Saving and Restoring LiveView State waits for the LiveView to

Read more
By Chris McCord

Tailwind Standalone for Phoenix

Tailwind v3 was just released with some great new additions. One such feature is a new “standalone” tailwindcss CLI that includes pre-built binaries for all major platforms. This enables all of Tailwind’s great features without the dependency on node

Read more
By Berenice Medel

Active nav with LiveView

One of the most important challenges when we are developing a new website is to give the user a great navigation experience, the user must know where they are and what navigation options they have at their disposal within the website. For this we use

Read more
By Mark Ericksen

Saving and Restoring LiveView State

There are multiple ways to save and restore state for your LiveView processes. You can use an external cache like Redis, your database, or even the browser itself. Sometimes there are situations, like I described previously, where you either can’t or

Read more
By David Bernheisel
Intro

Safe Ecto Migrations

As an Elixir developer who cares about system up-time and avoiding “scheduled maintenance” windows, and more importantly avoiding “unscheduled maintenance” windows 😉, this guide dives deep into Ecto database migrations and how they can be used safely

Read more
Safe Ecto Migrations
Part 1

Anatomy of an Ecto migration

In order for us to create and run safe Ecto migrations on our database, it is helpful to understand what is _actually_ happening with the database. To do that, we'll dig deeper into how Ecto migrations work by looking both at the code being executed

Read more
Safe Ecto Migrations
Part 2

How to migrate Mix Release projects

Not long ago, deploying and managing Elixir projects was not as straight-forward as today; some might say it was downright painful. Thankfully, since Elixir 1.9, Mix ships with tools to help developers assemble applications for deployment.

Read more
Safe Ecto Migrations
Part 3

Migration Recipes

This is a non-exhaustive guide on common migration scenarios and how to avoid trouble. These migration recipes may evolve over time, so be sure to check the git edition of these recipes at https://github.com/fly-apps/safe-ecto-migrations with up-to-d

Read more
Safe Ecto Migrations
Part 4

Backfilling Data

When I say "backfilling data", I mean that as any attempt to change data in bulk. This can happen in code through migrations, application code, UIs that allow multiple selections and updates, or in a console connected to a running application.

Read more