Use this checklist before shipping a LivePanels application.
A canvas is production-ready when the Elixir package, browser runtime, asset pipeline, canvas declarations, commands, persistence, shared backend, public docs, and verification gates all describe the same system.
Package And Assets
Confirm the application depends on the package version it expects:
{:livepanels, "~> 0.1.0"}Install and build browser assets:
mix livepanels.install
cd assets && npm install
Import hooks:
import { LivePanelsHooks } from "livepanels";
const liveSocket = new LiveSocket("/live", Socket, {
hooks: {
...LivePanelsHooks
}
});Import runtime CSS once:
import "livepanels/runtime.css";or:
@import "livepanels/runtime.css";Canvas Declarations
Run declaration validation:
mix livepanels.check
Check every production canvas:
- composes
use MyAppWeb, :live_viewbeforeuse LivePanels.Canvas; - has the correct
pubsub; - renders every runtime item type the app can restore;
- uses the intended toolkit preset or focused helper imports;
- sets
sessionmode, id, backend, and layout store intentionally; - uses a policy module when product rules should authorize commands;
- configures policy timeout intentionally for bounded command acceptance checks.
Runtime Commands
All canvas mutations should use public command helpers:
- item changes through
LivePanels.Canvas.Item; - item props through
LivePanels.Canvas.Item; - selection through
LivePanels.Canvas.Selection; - layout through
LivePanels.Canvas.Arrange; - history through
LivePanels.Canvas.History; - clipboard through
LivePanels.Canvas.Clipboard; - graph changes through
LivePanels.Graph; - drawing changes through
LivePanels.Drawing; - browser controls through toolkit attrs.
Reject these before release:
- application code replacing private LivePanels assigns;
- DOM-only placement state;
- browser code acting as the accepted graph or drawing store;
- direct calls into private runtime/compositor modules;
- hand-written command payloads where a public attr helper exists.
Persistence
If layouts must survive restart, configure a durable layout store:
defmodule MyApp.CanvasLayouts do
use LivePanels.Canvas.LayoutStore.Ecto,
repo: MyApp.Repo,
schema: MyApp.LivePanelsCanvasLayout
end
use LivePanels.Canvas,
pubsub: MyApp.PubSub,
session: [layout_store: MyApp.CanvasLayouts]Verify:
save/2stores the versioned layout payload unchanged;load/1returns{:ok, layout},:not_found, or{:error, reason};- restored layouts carry the capability snapshots needed for runtime behavior;
- graph connectors and vector state survive restore when expected;
- persistence failure emits telemetry and is visible in logs/monitoring.
Shared Mode
For shared canvases, verify:
- the LivePanels application child is supervised;
- every shared route uses a stable product-owned
canvas_id; - users are authorized before joining a shared canvas;
- the backend is explicit in production;
- clustered deployments use the intended registry and supervisor adapter;
LivePanels.Canvas.Shared.backend_health_check/1orbackend_health_check!/1runs in a release check;- participant metadata is concise and non-secret;
- durable layout storage is configured when recovery matters.
Graph
For graph canvases, verify:
- graph-capable item slots or runtime add payloads declare ports;
- port directions, types, anchors, and connection limits match product rules;
- app-rendered ports use
graph_port_anchor_attrs/2; - browser connection controls use
begin_connector_attrs/3andcomplete_connector_attrs/3; - server changes use
LivePanels.Graph; canvas_runtime/1renders connector items through the world SVG item projection;- connector presentation stores route, label, role, marker, and emphasis fields that need to persist or stream;
- connector CSS targets runtime connector classes and data attrs;
- persistent layouts restore expected connectors.
Drawing
For drawing canvases, verify:
- draw mode is set through
set_cursor_mode_js/3; - draw style maps include all required fields;
- committed vector item edits use drawing attrs or
LivePanels.Drawing; - erase targets use
erase_vector_item_target_attrs/2; - standard
canvas_runtime/1renders committed vector items, or a manual render loop usesLivePanels.Toolkit.Integration.Render; - drawing drafts broadcast only throttled intent before commit and become durable state only after the draw command is accepted;
- vector items persist, undo, redo, copy, paste, and share as expected.
UI And Accessibility
Verify application UI:
- item shells expose visible focus and selection states;
- drag handles are discoverable in your design;
- resize handles are reachable and do not overlap essential controls;
- keyboard scope and focus exemptions are applied intentionally;
- toolbars and inspectors use normal accessible controls;
- graph ports and drawing controls have labels or accessible names;
- runtime CSS is loaded before debugging behavior.
Observability
Attach telemetry for:
- command applied/rejected/profile events;
- shared session start, recovery, participant join/leave;
- broadcast state/delta/profile;
- layout persisted and layout persistence failed.
At minimum, production logs should make rejected commands, persistence failures, and shared recovery failures visible with the canvas id.
Release Checks
Run the checks that match the release:
mix compile
mix test
mix coverage
mix docs --warnings-as-errors
mix livepanels.check
For package or library release work, also run the repository release gates:
mix precommit
mix hex.audit
cd assets && npm test
Use the example application before writing complex custom integration:
cd examples/demo
mix setup
mix phx.server
Confirm these routes still demonstrate the expected behavior:
| Route | Proves |
|---|---|
/workspace | items, selection, history, clipboard, layout controls |
/graph | ports, connectors, routing, graph controls |
/drawing | freehand, shapes, draw tools, vector item editing |
/shared/:room | shared workspace behavior |
Documentation Check
Before release, make sure the docs a user sees match what the package ships:
- README install instructions work from a clean Phoenix app;
- guide filenames and ExDoc navigation are current;
- examples reference current guide names and chapter numbers;
- generated docs include the graph diagram assets;
- public module docs point to public APIs, not private runtime modules.
The release should not require users to learn private internals to build a normal canvas.