Backpex is a highly customizable administration panel for Phoenix LiveView applications. It allows you to quickly create CRUD views of your existing data using configurable LiveResources. Backpex integrates seamlessly with your existing Phoenix LiveView application and provides an easy way to manage your resources. It is highly customizable and can be extended with your own layouts, views, field types, filters and more.
Key Features:
- LiveResources: Quickly create LiveResource modules for your database tables with fully customizable CRUD views. Bring your own layout or use our components.
- Search and Filters: Define searchable fields and add custom filters for instant, LiveView-powered results.
- Resource Actions: Implement global custom actions like user invitations or exports, with support for additional form fields.
- Authorization: Handle CRUD and custom action authorization via simple pattern matching, with optional integration for external authorization libraries.
- Field Types: Out-of-the-box support for Text, Number, Date, Upload, and more. Easily extend with your own custom field type modules.
- Associations: Effortlessly handle HasOne, BelongsTo, and HasMany(Through) associations with minimal configuration. Customize available options and rendered columns.
- Metrics: Add value metrics such as sums or averages for quick data insights, with more metric types on the horizon.
- Elixir: Functional programming language for building scalable and maintainable applications
- Phoenix LiveView: Real-time web framework for Elixir
- Tailwind CSS: utility-first CSS framework
- daisyUI: Tailwind CSS plugin and component library
Backpex follows a modular architecture that separates the library code from the demonstration application. The project is structured as an Elixir library that can be integrated into Phoenix LiveView applications.
The repository contains two main parts:
1. Backpex Library (/)
The root directory contains the Backpex library itself, which is published as a Hex package. Key directories:
lib/backpex/
├── adapters/ # Data layer adapters (Ecto)
├── controllers/ # Phoenix controllers (cookie management)
├── fields/ # Built-in field types (Text, Number, Date, BelongsTo, HasMany, etc.)
├── filters/ # Built-in filter types (Boolean, Select, Range, etc.)
├── html/ # Phoenix Components for UI rendering
│ ├── core_components.ex # Base UI components
│ ├── layout.ex # Layout components
│ ├── form.ex # Form components
│ └── resource.ex # Resource-specific components
├── item_actions/ # Built-in item actions (Edit, Delete, Show)
├── live_components/ # LiveView components
├── live_resource/ # Core LiveResource views (Index, Form, Show)
├── metrics/ # Metric types (Value metrics)
├── plugs/ # Phoenix plugs (ThemeSelector)
├── adapter.ex # Adapter behavior
├── field.ex # Field behavior and config schema
├── live_resource.ex # LiveResource macro and core logic
├── resource.ex # Resource data manipulation
└── router.ex # Routing helpers and macros
priv/
├── gettext/ # Translation files
├── static/ # Static assets (compiled JS, images)
└── templates/ # Default layout templates
assets/js/ # JavaScript for LiveView hooks
The library provides:
- Core abstractions:
LiveResource,Field,Filter,ItemAction,ResourceAction,Metric - Adapter system: Pluggable data layer support (Ecto by default, Ash via community project ash_backpex)
- UI components: Reusable Phoenix Components for rendering admin interfaces
- Routing helpers: Macros for defining RESTful LiveView routes
2. Demo Application (/demo)
The demo directory contains a full Phoenix application that demonstrates Backpex capabilities:
demo/
├── lib/
│ ├── demo/ # Application logic (schemas, contexts)
│ │ └── helpdesk/ # Example domain (Tickets)
│ └── demo_web/ # Web layer
│ ├── components/ # App-specific components
│ ├── live/ # LiveResource implementations
│ │ ├── user_live.ex
│ │ ├── post_live.ex
│ │ ├── product_live.ex
│ │ └── ...
│ ├── filters/ # Custom filter implementations
│ ├── item_actions/ # Custom item actions
│ ├── resource_actions/ # Custom resource actions
│ └── router.ex # Route definitions
├── priv/
│ ├── repo/ # Database migrations and seeds
│ └── static/ # Static assets
├── test/ # Tests (including browser tests with Phoenix.Test.Playwright)
└── assets/ # Frontend assets (JS, CSS)
The demo serves multiple purposes:
- Example implementation: Shows how to use Backpex in a real application
- Development environment: Used for testing new features during development
- Documentation: Live examples for documentation and screenshots
- Testing: Comprehensive test suite including accessibility tests
| Aspect | Backpex (Library) | Demo (Application) |
|---|---|---|
| Purpose | Reusable library package | Example implementation & testing |
| Location | Root /lib/backpex, /priv, /assets |
/demo directory |
| Deployment | Published to Hex.pm | Runs locally (Docker) |
| Dependencies | Minimal (Phoenix, Ecto, Gettext) | Includes Backpex + app-specific deps |
| Code | Generic, configurable abstractions | Specific LiveResource implementations |
| Assets | Compiled JS (hooks) published with package | Full asset pipeline with Tailwind/esbuild |
| Tests | Unit tests for library code | Browser tests, integration tests, a11y tests |
- Custom Fields: Implement
Backpex.Fieldbehavior (seedemo/lib/demo_web/fields/) - Custom Filters: Implement
Backpex.Filterbehavior (seedemo/lib/demo_web/filters/) - Custom Actions: Implement
Backpex.ItemActionorBackpex.ResourceActionbehaviors - Custom Layouts: Provide your own layout components
- LiveView Hooks: Add client-side JavaScript behavior (see
assets/js/) - Adapters: Implement
Backpex.Adapterfor new data layers
A LiveResource in Backpex is a module that contains the configuration for a resource. This module is responsible for defining the resource's schema, the actions that can be performed on it, and the fields that will be rendered. See demo/lib/demo_web/live/post_live.ex for an example LiveResource.
Example structure:
defmodule MyApp.UserLive do
use Backpex.LiveResource,
adapter_config: [...],
layout: {MyAppWeb.Layouts, :admin}
# Callbacks define the resource
def fields, do: [...]
def filters, do: [...]
def can?(assigns, action, item), do: true
endThis generates:
MyApp.UserLive.Index- List view with search, filters, sortingMyApp.UserLive.Form- Create/edit form (handles both :new and :edit actions)MyApp.UserLive.Show- Detail view
Always consult the usage_rules.md file for the usage of packages in this project. It contains guidelines directly from package authors and additional development guidelines (e.g., for Elixir, Phoenix, and Phoenix LiveView). Review these guidelines early and often during development.
- Elixir ecosystem packages: Use Tidewave MCP to find the documentation for Elixir packages (e.g.,
phoenixandphoenix_live_view) - Frontend libraries and other packages: Use Context7 MCP server for daisyUI, Tailwind CSS, and other non-Elixir packages
Before implementing features:
- Search the codebase for similar existing patterns
- Check if there are reusable components or functions
- Understand the architectural patterns used in the project
The demo project runs inside a docker container so you have to run commands inside the container as well:
docker compose exec -T app yarn lintIf the command is related to Backpex it has to be executed on the host system:
mix format- Run linters: Use linters when you are done with all changes and fix any pending issues
- Run
docker compose exec -T app yarn lintto lint the demo application - Run
mix lintto lint Backpex
- Manual testing: Use Chrome DevTools MCP to test your changes at http://localhost:4000
- Test in multiple browser viewports (mobile, tablet, desktop)
- Verify all interactive elements work correctly
- Check for console errors or warnings
CSS Framework Stack:
- Primary: daisyUI components (built on Tailwind CSS)
- Secondary: Tailwind CSS utility classes
- Approach: Mobile-first responsive design
Best Practices:
- Component hierarchy:
- Look for existing Phoenix Components in the codebase (e.g., in
lib/backpex/html/*modules) - Use daisyUI components when available (use Context7 to fetch documentation)
- Build custom components with Tailwind CSS utilities and daisyUI component classes
- Always prefer reusing existing components over creating new ones
- Styling daisyUI components:
- daisyUI components can be styled using Tailwind CSS classes
- Add utility classes directly to daisyUI component markup:
<button class="btn btn-primary mt-4 shadow-lg">Submit</button>
- Responsive design:
- Use mobile-first approach (base styles are for mobile, add
md:,lg:prefixes for larger screens) - Test all breakpoints: mobile (default), tablet (
md:), desktop (lg:,xl:) - Ensure touch targets are at least 44x44px on mobile
- Color and theming:
- Use daisyUI semantic color classes (
primary,secondary, etc.) - Avoid hard-coded color values; use theme variables for consistency
- Ensure color choices meet accessibility contrast requirements
- Component organization:
- Create reusable components in
lib/backpex/html/*modules - Keep components small and focused on a single responsibility
Users are able to translate all strings used by Backpex. If you add any translations to Backpex make sure to use the Backpex.__/2 macro. Pass the text as the first argument. If possible, pass the LiveResource module as the second argument (often available in the socket assigns).
Example in .ex file:
defp apply_action(socket, :form) do
text = Backpex.__("No options found", socket.assigns.live_resource)
endExample in .html.heex file:
<button>
{Backpex.__("Show more", @live_resource)}
</button>Accessibility is mandatory, not optional. All features must be fully accessible.
- Semantic HTML: Use proper HTML5 semantic elements (
<nav>,<main>,<article>,<section>, etc.) - ARIA attributes: Add ARIA labels where text content is not sufficient (
aria-label,aria-labelledby) - Keyboard navigation: All interactive elements must be keyboard accessible (focusable with Tab)
- Visual accessibility: Use appropriate font sizes, ensure color contrast meets accessibility requirements, and add sufficient spacing and touch target sizes
- Screen reader compatibility: Provide alt text for all images, use
sr-onlyTailwind class for screen-reader-only content when needed - Forms accessibility: Always use
<label>elements associated with form inputs
The demo project contains an A11yAssertions module (demo/test/support/a11y_assertions.ex) with an assert_a11y/1 function that can be used to test for a11y. See demo/test/demo_web/browser/address_browser_test.exs for an example of this.
If absolutely necessary, it is possible to create client hooks (LiveView hooks) via the phx-hook attribute to provide client-side JavaScript code. Create the hooks in the assets/js directory. Also export the hook in the assets/js/index.js file. When building hooks, analyse the existing hooks in the assets/js directory first and use existing patterns if possible.
See usage_rules.md for additional guidelines on LiveView Hooks. Fetch phoenix and phoenix_live_view docs via Tidewave MCP if needed.
- Commit messages:
- Write clear, descriptive commit messages
- Use present tense ("Add feature" not "Added feature")
- Reference issue numbers when applicable
- Branch strategy:
- Create feature branches for new work
- Keep commits focused and atomic
- Rebase or merge from main regularly to stay up to date
- Before pushing:
- Run
mix precommitto ensure all checks pass - Review your own changes (diff) before committing
- Ensure tests pass locally