Starter Phoenix LiveView Course (Pragmatic Studio) (Free)

Howdy Everyone, :wave:

TLDR: Early access to our Phoenix LiveView course is now open… and it’s free! The first 7 videos (75 minutes) are available, along with exercises and notes. And with that foundation in place, we’ll incrementally release new videos and more advanced LiveView examples as they’re ready in upcoming weeks.


I realize a lot of you on this forum are already deep into LiveView. But you may have friends who are trying to figure out what makes it unique. So the first video answers the question “What Is LiveView?” in just 4 minutes:

Then in the second video we build a basic LiveView step-by-step as an introduction to LiveView’s simple (and fun!) programming model:

But as we all know, even with a simple example there’s a lot going on behind the scenes. And to use LiveView effectively, it’s vital to have a good mental model of the lifecyle and what’s on the wire. Plus, the optimizations are just really clever! So that’s the focus of the third video:

In subsequent videos we build more LiveView examples with increasing complexity. We hope after watching these videos you’ll be inspired to build amazing and useful things with LiveView!

:gift: This course is our way of saying “Thanks!” to the Elixir/Phoenix community. @josevalim, @chrismccord, and contributors to LiveView have done an incredible job creating a library that is both really fun to use and really powerful.

All the course details are at:

I hope you enjoy the course as much as we enjoyed making it! :grinning:



Thank you for this excellent LV course :slight_smile:


Just finished the available modules and came here to talk about that.

Great content and presentation. Videos are very focused and each one of them explains some cool details about what’s being transmitted back and forth on the websocket.

Thanks and congratulations, Mike and Nicole!


You’re very welcome!


Thanks for your encouraging words!


This sounds great, I am definitely trying it out :slight_smile:

One question though: is Pragmatic Studio in any way affiliated to the Pragmatic Bookshelf? Asking because the site having the same logo font and similar name made me think it belongs to the same entity, so I initially tried to login with my PragProg account but it did not work. I changed my PragProg password after that, but felt a bit weird.

EDIT: I see that Pragmatic Studio and Pragmatic Bookshelf are separate entities. Sorry, I was just being a little paranoid as I have quite some value accumulated in my PragProg account…


Yep, we’re affiliated but separate entities. As such, we don’t share any account information back and forth. Sorry that felt a bit weird.

Hope you enjoy the course!


This is a really great set of videos! I haven’t spent any time with LiveView yet, but after watching the videos, I feel pretty confident about getting my hands dirty soon. Thanks!


Thank you so much :heart_eyes:

Finish this course will be my priority in the coming weekends.


great videos!

only feedback would be in Example #4: Live Search at 6:48 - with the immediate loading state change - I was really expecting a component to be introduced and used…

1 Like

This is a great course. Made it to example #3 so far. Really clear with obvious applicability it to real world problems.

Enjoying it. :smiley:


First, thank you to Mike and Nicole for putting this together. Extremely generous of you to spend the time, and very helpful.

In the first example (Porch Light), I noticed that the up/down buttons can exceed the expected range (negative numbers, numbers above 100). I know this isn’t the focus of the course, but what is the most idiomatic way to constrain them? Elixir wouldn’t let me use socket.assigns.brightness inside a guard clause. I eventually came up with this:

  def handle_event("up", _unsigned_params, socket) do
    case socket.assigns.brightness do
      100 -> {:noreply, socket}
      _ -> {:noreply, update(socket, :brightness, &(&1 + 10))}

  def handle_event("down", _unsigned_params, socket) do
    case socket.assigns.brightness do
      0 -> {:noreply, socket}
      _ -> {:noreply, update(socket, :brightness, &(&1 - 10))}

Is there a better way?


Thanks a lot for this great work!


Fantastic content @mikeclark, thanks!

You can pattern match the brightness key inside the assigns map. But it’s just a different style of doing the same thing.

def handle_event("up", _, %{assigns: %{brightness: b}}=socket) 
  when b == 100, do: {:noreply, socket}

def handle_event("up", _, socket)
  do: {:noreply, update(socket, :brightness, &(&1 + 10))}

def handle_event("down", _, %{assigns: %{brightness: b}}=socket) 
  when b == 0, do: {:noreply, socket}

def handle_event("down", _, socket)
  do: {:noreply, update(socket, :brightness, &(&1 - 10))}


Excellent—thanks for this :slight_smile:

1 Like

Hi Dusty,

You’re very welcome! Thanks for your kind words.

In the Notes section after that video, we share the following solution which uses min and mix to constrain the brightness (contributed by a student):

def handle_event("up", _, socket) do
  socket = update(socket, :brightness, &min(&1 + 10, 100))
  {:noreply, socket}

def handle_event("down", _, socket) do
  socket = update(socket, :brightness, &max(&1 - 10, 0))
  {:noreply, socket}

Thanks, @BigTom! Glad to hear you’re enjoying it.

1 Like

Awesome, @jbryant04! Glad to hear they’ve helped you feel confident with LiveView. It’s a lot of fun.

1 Like

this course is excellent! thank you.

any ETA on the remaining videos, please? thank you

“LiveView brings the heat without any of the burn,” is such an excellent quote.