Using ExAdmin in a Phoenix Application

ActiveAdmin is a very useful tool in the Ruby on Rails world. It is kind of like the Django admin site where you have a CRUD of a model with little code configuration. Thanks to the amazing Steve Pallen now we have the same functionality in the Elixir Phoenix world !

The project is in an early stage and it is not published to hex, yet. But I will guide you into using it in your projects.

Let’s start by creating a new project:

mix blog
cd blog

We need an ecto model so I’ll generate a simple one:

mix phoenix.gen.model Post posts title:string content:text
mix ecto.create
mix ecto.migrate

Now add the ex_admin library as a dependency:

defp deps do
{:ex_admin, github: "smpallen99/ex_admin"},

Fetch ex_admin and compile

mix deps.get
mix deps.compile

Install the admin css, js, configuration and default dashboard in your app

mix admin.install

As per the instruction drop these lines in your router.ex

use ExAdmin.Router
admin_routes :admin

Add the Scrivener pagination to the repo:

defmodule Blog.Repo do
use Ecto.Repo, otp_app: :survey
use Scrivener, page_size: 10

And to the config.exs

config :ex_admin,
repo: Blog.Repo,
module: Blog,
modules: [

Compile and run and go to http://localhost:4000/admin and you should see the admin dashboard.

Add a model to the administration dashboard:

mix admin.gen.resource Post

After the command, modify the configuration to add the module that was generated just now:

config :ex_admin,
repo: Blog.Repo,
module: Blog,
modules: [

Visit the admin again and the post model will be available

Integration with Brunch

Everything is happy and you can checkout examples on changing the index page or the form in the Readme, but there is a small thing we need to do to deploy this application.

The css and images were copied to the priv directory which if you are using brunch is the directory for compiled assets. So lets integrate these files with our brunch pipeline.

First copy the files to the web directory

cp priv/static/css/active_admin.css.css web/static/css/active_admin.css.css
cp priv/static/js/jquery.js web/static/vendor/jquery.js
cp priv/static/js/jquery-ujs.js.js web/static/vendor/jquery-ujs.js.js

And then change the brunch-config.js to compile and create these files:

exports.config = {
// See for docs.
files: {
javascripts: {
// To use a separate vendor.js bundle, specify two files path
joinTo: {
“js/app.js”: [/^(web\/static\/js)/,
“js/jquery.js”: [“web/static/vendor/jquery.js”],
“js/jquery-ujs.js.js”: [“web/static/vendor/jquery-ujs.js”],

// To change the order of concatenation of files, explicitly mention here
// order: {
// before: [
// “web/static/vendor/js/jquery-2.1.1.js”,
// “web/static/vendor/js/bootstrap.min.js”
// ]
// }
stylesheets: {
joinTo: {
“css/app.css”: [/^(web\/static\/css)/],
“css/active_admin.css.css”: [“web/static/css/active_admin.css”],

templates: {
joinTo: “js/app.js”
conventions: {
// This option sets where we should place non-css and non-js assets in.
// By default, we set this to “/web/static/assets”. Files in this directory
// will be copied to `paths.public`, which is “priv/static” by default.
assets: /^(web\/static\/assets)/
// Phoenix paths configuration
paths: {
// Dependencies and current project directories to watch
watched: [
// Where to compile files to
public: “priv/static”
// Configure your plugins
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
ignore: [/web\/static\/vendor/]
modules: {
autoRequire: {
“js/app.js”: [“web/static/js/app”]
npm: {
enabled: true

This will instruct brunch to generate the files in the priv directory and will work in a deployment.

It is very early in the life of ExAdmin but it is already an interesting project to follow an contribute to .

Show your support

Clapping shows how much you appreciated Ricardo Echavarria’s story.