# Welcome

LocalLiveView brings local-first interactivity to Phoenix applications by running your Elixir code directly in the browser — using the same [Phoenix LiveView](https://hexdocs.pm/phoenix_live_view/welcome.html) API you already know.

## What is LocalLiveView?

In a standard Phoenix LiveView app, UI state lives on the server. Every interaction travels over the network: user clicks button → server processes event → server sends diff → browser updates DOM. This works great, but it means latency is always in the loop.

LocalLiveView moves that state into the browser itself. Your Elixir modules are compiled to WebAssembly and executed via [Popcorn](https://hexdocs.pm/popcorn/introduction.html), which runs AtomVM — a tiny Erlang virtual machine — directly in the browser. Events are handled locally, renders happen instantly, and the server is only involved when you explicitly want it to be.

The result: **zero-latency UI**, offline capability, and a familiar Elixir/LiveView programming model.

## How it works

```
           Server                                      Browser                 
┌───────────────────────────────┐              ┌──────────────────────────────┐
│ Phoenix LiveView (host)       │              │ Popcorn (AtomVM WASM)        │
│                               │              │                              │
│ render/1                      │              │ MyLocal                      │
│   <.local_live_view           │              │   mount/3                    │
│     view="MyLocal"            │─── assigns ─▶│   render/1                   │
│     items={@items} />         │              │   update/2                   │
│                               │              │                              │
│                               │              │   handle_event/3             │
│ handle_event/3                │◀─── event ───│     push_server_event/3      │
│                               │              │                              │
│ Mirror.MyLocal.handle_sync/3  │◀─── sync ────│   mirror_sync/2              │
│   (optional)                  │              │                              │
└───────────────────────────────┘              └──────────────────────────────┘
```

1. Your `local/` project is compiled to a `.avm` WASM bundle at build time.
2. A server-side LiveView renders the mount point with `<.local_live_view view="MyLocal" />`. Every attribute other than `view` is passed down as assigns and delivered to the local view's `update/2` callback — so the host stays in control of the data, exactly as with `live_component/1`.
3. When the page loads, Popcorn starts the WASM runtime and mounts your LocalLiveViews.
4. User interactions are handled in the browser — no round-trip to the server.
5. A local view can push events back to its host with `push_server_event/3`, which arrives at the host LiveView's `handle_event/3`. Handling the event locally first and pushing afterwards gives you optimistic updates, with the server's authoritative state arriving as the next `update/2`.
6. Optionally, you can sync selected assigns to a server-side mirror module via `mirror_sync/2`, letting other users' LiveViews react to local state changes.

## Key concepts

**LocalLiveView module** — An Elixir module that uses `use LocalLiveView` and implements `mount/3`, `render/1`, and optionally `handle_event/3`. Lives in the `local/` project (compiled to WASM).

**`local/` project** — A separate Mix project inside your Phoenix app, built via `mix llv.build`. The `local/` project depends on `:local_live_view` and contains all your client-side Elixir code.

**`<.local_live_view>`** — A Phoenix component that renders the mount point for a LocalLiveView. Generated by `mix llv.install` and available as `import LocalLiveView.Component` in your web module.

**Mirror** — An optional server-side module (`Mirror.MyLocal`) that receives synced assigns from a LocalLiveView. Useful for broadcasting state changes to other users or persisting data.

## Relationship to Phoenix LiveView

If you know Phoenix LiveView, you already know LocalLiveView. The callbacks (`mount/3`, `render/1` with `~H`, `handle_event/3`), the assign functions (`assign/2`, `update/3`) and the template bindings (`phx-click` and friends) are all the same — LocalLiveView intercepts Phoenix LiveView's standard JavaScript layer, so event attributes work exactly the same way.

The main differences between LLV and standard LiveView are that LLV uses `use LocalLiveView` instead of `use Phoenix.LiveView`, relies on the `update/3` callback to update its assigns, and runs directly in the browser's Popcorn runtime rather than on the server.

LLV can also render LiveComponents and function components natively. These will similarly execute as part of the browser's Popcorn runtime.
