Skip to content
Adminmate
All posts

How to add an admin panel to your Express app in 10 minutes

Marc Delalonde

Co-founder of Adminmate

Sooner or later, every Express app needs an admin panel. Someone has to find a user, fix an order, refund a payment or answer “can you check why this account is blocked?”. Until then, it’s usually a developer running queries in production.

You can build that admin panel yourself, but it is never just a list and a form: you will need search, filters, pagination, relationships, permissions, an audit trail… and to maintain all of it.

In this tutorial, we add a complete admin panel to an existing Express app in about 10 minutes, using your own Mongoose or Sequelize models. Your data stays on your servers: nothing is copied or synced.

What you need

  • An Express app running on Node.js 16 or later
  • Mongoose models (MongoDB) or Sequelize models (MySQL, PostgreSQL or SQLite)
  • A free Adminmate account

Step 1: Create a project

Log in to Adminmate and create a new project. Give it a name and pick your database type. You get two values: a Project ID and a Secret Key. Add them to the environment variables of your app, with two more values you choose yourself:

Terminal window
AM_PROJECT_ID=your-project-id
AM_SECRET_KEY=your-secret-key
AM_AUTH_KEY=a-long-random-string # openssl rand -hex 32
AM_MASTER_PWD=a-strong-master-password # asked to open the admin panel

The master password is the second lock of your admin panel: it is checked by your own server and never sent to Adminmate.

Step 2: Install the package

Terminal window
# MongoDB with Mongoose
npm install adminmate-express-mongoose
# MySQL, PostgreSQL or SQLite with Sequelize
npm install adminmate-express-sequelize

Step 3: Plug it into your app

Add Adminmate right after the creation of your Express app, before your own authentication middlewares, and list the models you want to manage:

const express = require('express');
const Adminmate = require('adminmate-express-mongoose');
const User = require('./models/user');
const Order = require('./models/order');
const app = express();
app.use(Adminmate.init({
projectId: process.env.AM_PROJECT_ID,
secretKey: process.env.AM_SECRET_KEY,
authKey: process.env.AM_AUTH_KEY,
masterPassword: process.env.AM_MASTER_PWD,
models: [
{ slug: 'users', model: User },
{ slug: 'orders', model: Order }
]
}));
// ...your middlewares and routes

Adminmate only adds routes under /adminmate/api, so it does not interfere with the rest of your app. Restart your server.

Step 4: Open your admin panel

Back in Adminmate, enter the URL of your app (for example http://localhost:3000) and your master password. That’s it: you get a data explorer for your users and orders, with search, filters, sorting, CSV export, create / update / delete, and the related records of each item.

At this point, you already have what most homemade admin panels offer. Let’s go further.

Step 5: Add segments

A segment is a predefined view of your data, available in one click. For example, the orders waiting to be shipped:

{
slug: 'orders',
model: Order,
segments: [
{
label: 'To ship',
code: 'to_ship',
query: { status: 'paid', shipped_at: null }
}
]
}

Step 6: Add a custom action

Actions are where an admin panel really saves time: they run your own business logic from a button. Here is a “Mark as shipped” action, available on one order or on a selection:

{
slug: 'orders',
model: Order,
actions: [
{
label: 'Mark as shipped',
code: 'mark_as_shipped',
target: ['item', 'bulk'],
filter: order => order.status === 'paid',
handler: async ({ ids }, success, error) => {
await Order.updateMany({ _id: { $in: ids } }, { status: 'shipped', shipped_at: new Date() });
success({ message: `${ids.length} order(s) marked as shipped`, reload: true });
}
}
]
}

Because the handler is plain JavaScript running in your app, it can call your existing services: send the shipping email, notify your warehouse, update Stripe… An action can also ask for input with a form before running. See the actions documentation.

Step 7: Invite your team

Invite your teammates and create teams with the right permissions: for example a support team that can only open the production environment, edit the email of a user and use a few actions, but never delete anything. Every change and every action is recorded in the activity log.

Step 8: Deploy

There is nothing specific to deploy: Adminmate ships with your app. Set the four environment variables on your servers, add your production URL as a new environment in Adminmate, and your team can start working.

Use a different master password per environment, and serve your API over HTTPS. The deployment guide has a full production checklist.

Wrapping up

In a few minutes, without writing any UI, you get an admin panel that would take weeks to build and keep maintaining: data explorer, segments, custom actions, dashboards, team permissions and an audit trail. And since the Data API runs inside your app, your data never leaves your servers.

Create your free account and try it on your own app. Everything is free.

Ship your back-office today

Connect your database, invite your team, and get back to building your product.