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
16 min Read
Using AI to Boost Accessibility and SEO
In the fast-paced world of digital content, the adage “a picture is worth a thousand words” remains as true as ever. This is the case for Sarah, a content manager at a popular online magazine. She is racing to finalize a feature article called “The H
Phoenix LiveView v0.20.4 was released in February 2024. It included a new feature that hasn’t gotten enough recognition. This simple little feature is a nice improvement for developer experience. Where previously I used Alpine.js or needed to craft a
World Page Speed Test – planet-wide elastic scale with FLAME
I closed out the year the publishing a new library and programming model, called FLAME. If you missed it, FLAME replaces the need for AWS Lambda or Cloudflare Workers and the proprietary services that call proprietary services fractal of architecture
Phoenix LiveView is a server-side frontend framework and with this great power comes great responsibility on the developer. A very common source of frustration is around Forms, their assigns values and connection resets or deploys. In this post we’ll
A big barrier to getting started with local AI development is access to hardware. And by “local”, we mean having direct access to a GPU and not going through AI-as-a-Service. Some of us are lucky enough to have a beefy Nvidia GPU, if so, good for you
Phoenix Dev Blog – Server logs in the browser console
There are some features that are such quality of life improvements I’m shocked we didn’t ship them sooner. The latest phoenix_live_reload which streams servers logs down to the client is one such example.
The phoenix_live_reload project is about as
TL;DR: Check out the Elixir Fly.io guide Easy Clustering from Home to Fly.io for the steps on exactly how to cluster the Elixir application running on your laptop with one running at Fly.io. Grab the bash script that automates a chunk of it too. Here
What if S3 could be a fast, globally synced, Key Value Database? That's Tigris
That said… building applications that span the globe is a hard problem. Heck, syncing data between two machines is not trivial. It might require writing to a “primary” and reading from a “secondary”. Or using a CRDT to “sync” state, combined with pub
Elixir has been quietly building out a truly impressive list of packages, and while a deep resource of packages that solve common or complex problems is good, for some people it’s not enough and want more. Which is to be expected, the Elixir communit
Let’s be real. You’re probably never going to create a 3D game in Phoenix LiveView. It’s not the best tool for that job, at least yet. However, we can still create interesting, compelling, and responsive games in LiveView!
What’s a fundamental piece
Recently I started playing with the idea of using LLama.CPP with Elixir as a NIF. Creating C/C++ Nif’s in Erlang is kind of a project and you need to be especially careful to not cause memory errors bugs. So I found a Rust Wrapper around LLama.cpp an
We live in truly a time of wonders; every single week, a new demo drops with a mind glimpse of what our incredible AI future might be. From generating illustrations, front-end apps, or very convincing text, however…
If we’re being honest, those demo
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
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.
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
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
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. So I wondered: Can I run a LLM Model on a normal Fly Machine?
Locally on my M2 Mac, I’ve been able t
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Read more
By Berenice Medel & Mark Ericksen
8 min Read
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
Read more
By Berenice Medel & Chris Nicoll
8 min Read
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
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
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
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
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
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
(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
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
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
Read more
By Berenice Medel & Chris Nicoll
6 min Read
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
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
Read more
By Berenice Medel & Chris Nicoll
5 min Read
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
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
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
Read more
By Berenice Medel & Chris Nicoll
8 min Read
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.
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
Read more
By Berenice Medel & Chris Nicoll
9 min Read
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
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
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
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
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
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
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
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
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
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.
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
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.