agentleFS
G1JoshiG1Joshi/Agent-Skills/skills/frameworks/phoenix/SKILL.md

phoenix

Skill15 starsChanged 43 days agoMITView on GitHub

Expert Phoenix assistance covering Elixir web development, LiveView real-time reactive UIs, Ecto queries, and Channels. Use when building high-concurrency real-time web applications with minimal JavaScript.

3 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

3 rules. 0 are common, 1 is distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use Phoenix LiveView with PubSub broadcasting:

    line 115
  2. Very specific:

    Use LiveView streams (stream/3) for large collections to minimize memory usage on both client and server.

    line 144
  3. Very specific:

    Use Ecto Multi (Ecto.Multi) for atomic multi-table transactional workflows.

    line 145

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Phoenix

Phoenix (Elixir) provides real-time scalability (millions of connections). v1.7 + LiveView allows building rich SPAs without writing JavaScript.

When to Use

  • Real-Time Interactive Web Applications: Real-time dashboards, multiplayer games, and collaboration tools with LiveView.
  • High-Concurrency Distributed Backends: Leveraging Erlang/Elixir BEAM VM for fault-tolerant microservices.
  • Scalable WebSocket & Channel Architectures: Millions of persistent connections with minimal memory per process.
  • Maintainable Functional Web Development: Clean separation with Ecto schemas, contexts, and Plugs.

Quick Start

defmodule MyAppWeb.PageController do
  use MyAppWeb, :controller

  def home(conn, _params) do
    render(conn, :home, layout: false)
  end
end

# In router.ex:
# scope "/", MyAppWeb do
#   pipe_through :browser
#   get "/", PageController, :home
# end

Core Concepts

Phoenix LiveView: Server-Driven Interactivity

Real-time UI state management over WebSockets without JavaScript client state:

defmodule MyAppWeb.CounterLive do
  use MyAppWeb, :live_view

  def mount(_params, _session, socket) do
    {:ok, assign(socket, count: 0)}
  end

  def handle_event("increment", _params, socket) do
    {:noreply, update(socket, :count, &(&1 + 1))}
  end

  def render(assigns) do
    ~H[
    <div class="counter-box">
      <h2 class="text-xl">Count: <%= @count %></h2>
      <button phx-click="increment" class="bg-blue-500 text-white px-4 py-2 rounded">
        Increment
      </button>
    </div>
    ]
  end
end

Ecto Contexts & Composability

Decoupled business logic and transactional database access:

defmodule MyApp.Accounts do
  import Ecto.Query, warn: false
  alias MyApp.Repo
  alias MyApp.Accounts.User

  def list_active_users do
    from(u in User, where: u.is_active == true, order_by: [desc: u.inserted_at])
    |> Repo.all()
  end

  def create_user(attrs \\ %{}) do
    %User{}
    |> User.changeset(attrs)
    |> Repo.insert()
  end
end

Phoenix Channels: Low-Latency Pub/Sub

Real-time broadcasting across connected clients:

defmodule MyAppWeb.RoomChannel do
  use MyAppWeb, :channel

  def join("room:lobby", _payload, socket) do
    {:ok, socket}
  end

  def handle_in("new_msg", %{"body" => body}, socket) do
    broadcast!(socket, "new_msg", %{body: body, user: socket.assigns.user_id})
    {:reply, :ok, socket}
  end
end

Common Patterns

Real-Time LiveView Counter with PubSub Broadcasts

Problem: Synchronizing live state changes across multiple concurrent browser tabs.

Solution: Use Phoenix LiveView with PubSub broadcasting:

defmodule MyAppWeb.CounterLive do
  use MyAppWeb, :live_view

  def mount(_params, _session, socket) do
    if connected?(socket), do: Phoenix.PubSub.subscribe(MyApp.PubSub, "counter")
    {:ok, assign(socket, count: 0)}
  end

  def handle_event("inc", _params, socket) do
    new_count = socket.assigns.count + 1
    Phoenix.PubSub.broadcast(MyApp.PubSub, "counter", {:count_updated, new_count})
    {:noreply, assign(socket, count: new_count)}
  end

  def handle_info({:count_updated, count}, socket) do
    {:noreply, assign(socket, count: count)}
  end
end

Best Practices

Do:

  • Target Phoenix 1.7+ with verified routes (~p"/users") and HEEx functional components.
  • Structure domain boundaries using Phoenix Contexts rather than exposing Ecto queries in controllers.
  • Use LiveView streams (stream/3) for large collections to minimize memory usage on both client and server.
  • Use Ecto Multi (Ecto.Multi) for atomic multi-table transactional workflows.

Don't:

  • Store large binary data or huge collections in LiveView socket assigns; use temporary assigns or streams.
  • Make blocking third-party HTTP calls directly in LiveView processes without wrapping in Task.
  • Bypass Ecto changesets for user input validation.

Troubleshooting

ErrorCauseSolution
(Ecto.NoResultsError) expected at least one resultRepo.get! or Repo.one! returned nil for query.Use non-bang variant Repo.get and handle nil safely.
phx-socket closed / reconnecting in LiveViewLiveView process crashed due to unhandled handle_info or handle_event.Inspect Elixir crash stack trace in iex -S mix phx.server.
CompileError: undefined function MyAppWeb...Module name typo or Phoenix view helper not included.Run mix compile and check module namespace in my_app_web.ex.

References

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.