Hero
Back to all guides

How to add analytics to Express

Add server-side analytics to your Express application with OpenPanel middleware. Track API requests, user actions, and custom events.

OpenPanel Team

12/15/2025

Beginner
8 min

How to add analytics to Express

Server-side analytics gives you reliable event tracking that cannot be blocked by ad blockers or browser extensions. The OpenPanel Express middleware wraps the JavaScript SDK and attaches it to every request, making it simple to track events throughout your application.

OpenPanel is an open-source alternative to Mixpanel and Amplitude. You get powerful analytics with full control over your data, and you can self-host if privacy requirements demand it.

Prerequisites

  • An Express application
  • An OpenPanel account (sign up free)
  • Your Client ID and Client Secret from the OpenPanel dashboard

Server-side tracking requires a clientSecret for authentication since the server cannot rely on browser CORS headers to verify the request origin.

Install the SDK

The Express SDK is a lightweight middleware that creates an OpenPanel instance for each request. Install it with npm (pnpm and yarn work too).

npm install @openpanel/express

Add the middleware

The middleware attaches the OpenPanel SDK to every request as req.op. Add it early in your middleware chain so it is available in all your route handlers.

import express from 'express';
import createOpenpanelMiddleware from '@openpanel/express';

const app = express();

app.use(express.json());

app.use(
  createOpenpanelMiddleware({
    clientId: 'YOUR_CLIENT_ID',
    clientSecret: 'YOUR_CLIENT_SECRET',
  })
);

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

You should store your credentials in environment variables rather than hardcoding them. This keeps secrets out of version control and makes it easy to use different credentials in development and production.

app.use(
  createOpenpanelMiddleware({
    clientId: process.env.OPENPANEL_CLIENT_ID!,
    clientSecret: process.env.OPENPANEL_CLIENT_SECRET!,
  })
);

The middleware also forwards the client IP address and user-agent from incoming requests, so geographic and device data will be accurate even though events originate from your server.

Track events

Once the middleware is in place, you can track events in any route handler by calling req.op.track(). The first argument is the event name and the second is an object of properties you want to attach.

app.post('/signup', async (req, res) => {
  const { email, name } = req.body;

  req.op.track('user_signed_up', {
    email,
    name,
    source: 'website',
  });

  const user = await createUser({ email, name });
  res.json({ success: true, user });
});

You can track any event that matters to your business. Common examples include form submissions, purchases, feature usage, and API errors.

app.post('/contact', async (req, res) => {
  const { email, message } = req.body;

  req.op.track('contact_form_submitted', {
    email,
    message_length: message.length,
  });

  await sendContactEmail(email, message);
  res.json({ success: true });
});

Automatic request tracking

The middleware can automatically track every request if you provide a trackRequest function. This is useful for monitoring API usage without manually adding tracking calls to each route.

app.use(
  createOpenpanelMiddleware({
    clientId: process.env.OPENPANEL_CLIENT_ID!,
    clientSecret: process.env.OPENPANEL_CLIENT_SECRET!,
    trackRequest: (url) => url.startsWith('/api/'),
  })
);

When trackRequest returns true, the middleware sends a request event with the URL, method, and query parameters.

Identify users

To associate events with specific users, use the getProfileId option in the middleware configuration. This function receives the request object and should return the user's ID.

app.use(
  createOpenpanelMiddleware({
    clientId: process.env.OPENPANEL_CLIENT_ID!,
    clientSecret: process.env.OPENPANEL_CLIENT_SECRET!,
    getProfileId: (req) => req.user?.id,
  })
);

You can also send user profile data with req.op.identify(). This updates the user's profile in OpenPanel with properties like name, email, and any custom attributes.

app.post('/login', async (req, res) => {
  const { email, password } = req.body;
  const user = await authenticateUser(email, password);

  req.op.identify({
    profileId: user.id,
    firstName: user.firstName,
    lastName: user.lastName,
    email: user.email,
    properties: {
      plan: user.plan,
      signupDate: user.createdAt,
    },
  });

  req.op.track('user_logged_in', { method: 'email' });
  res.json({ success: true, user });
});

Increment profile properties

If you want to track cumulative values on a user profile, like login count or total purchases, use the increment method.

req.op.increment({
  profileId: user.id,
  property: 'login_count',
  value: 1,
});

Verify your setup

Start your Express server and trigger a few events by making requests to your endpoints. Open the OpenPanel dashboard and navigate to the Real-time view to see events as they arrive.

If events are not appearing, check your server logs for error responses from OpenPanel. Verify that both clientId and clientSecret are correct and that the middleware is added before your routes.

TypeScript support

The Express SDK automatically extends the Request interface to include req.op. If your TypeScript configuration does not pick this up, you can extend the interface manually in a declaration file.

import { OpenPanel } from '@openpanel/express';

declare global {
  namespace Express {
    export interface Request {
      op: OpenPanel;
    }
  }
}

Next steps

The Express SDK reference covers all available options and methods. If you are using a different Node.js framework, the Node.js tracking guide shows how to use the base SDK directly. For comparing OpenPanel to other analytics tools, see the Mixpanel alternative page.

Loved by builders everywhere

From indie hackers to global teams, OpenPanel helps people understand their users effortlessly.

  • Steven Tey
    Steven Tey
    @steventey

    Open-source Mixpanel alternative just dropped → http://git.new/openpanel

    It combines the power of Mixpanel + the ease of use of @PlausibleHQ into a fully open-source product.

    Built by @CarlLindesvard and it’s already tracking 750K+ events 🤩

  • Pontus Abrahamsson - oss/acc
    Pontus Abrahamsson - oss/acc
    @pontusab

    Thanks, OpenPanel is a beast, love it!

  • Piotr Kulpinski
    Piotr Kulpinski
    @piotrkulpinski

    The Overview tab in OpenPanel is great. It has everything I need from my analytics: the stats, the graph, traffic sources, locations, devices, etc.

    The UI is beautiful ✨ Clean, modern look, very pleasing to the eye.

  • greg hodson 🍜
    greg hodson 🍜
    @h0dson

    i second this, openpanel is killing it

  • Jacob 🍀 Build in Public
    Jacob 🍀 Build in Public
    @javayhuwx

    🤯 wow, it's amazing! Just integrate @OpenPanelDev into http://indiehackers.site last night, and now I can see visitors coming from all round the world.

    OpenPanel has a more beautiful UI and much more powerful features when compared to Umami.

    #buildinpublic #indiehackers

  • Lee
    Lee
    @DutchEngIishman

    Day two of marketing.

    I like this upward trend..

    P.S. website went live on Sunday

    P.P.S. Openpanel by @CarlLindesvard is awesome.

Ready to understand your users better?
Start tracking in minutes

Join thousands of companies using OpenPanel. Free 30-day trial, no credit card required. Self-host for free or use our cloud.

Get started now