Get started with a custom Node.js stack

Getting Opbeat set up for your Node.js app is easy, and there are various ways you can tweak it to fit to your needs.

If you are using either Express, Hapi or Koa, we recommend that you read these articles instead:

For a custom Node.js app, follow the guide below and refer to the API documentation for all the advanced stuff.


$ npm install opbeat --save


It’s important that the Opbeat agent is started before you require any other modules in your Node.js application - i.e. before http, before your router, even before Babel if you use that.

// add this to the VERY top of the first file loaded in your app
var opbeat = require('opbeat').start({
  appId: '<app id>',
  organizationId: '<org id>',
  secretToken: '<token>'

In the above example we initialize the agent by calling the start() function. This function takes an optional options object used to configure the agent. Any option not supplied via the options object can instead be configured using environment variables. So if you prefer, you can set the following three environment variables:

OPBEAT_APP_ID=<app id>

And then just start the agent like so:

// Start the Opbeat agent before any thing else in your app
var opbeat = require('opbeat').start()

See all possible configuration options in the API documentation.

The Opbeat agent will now monitor the performance of your application and record any uncaught exceptions.

Route naming

The Opbeat agent tracks incoming HTTP requests to your application in what are called “transactions”. All transactions with the same name are grouped together automatically.

In a normal web application you want to name transactions based on the route that matches the incoming HTTP request. So say you have a route to display posts on a blog identified by GET /posts/{id}. You want requests GET /posts/12, GET /posts/42 etc to be grouped together under a transaction named GET /posts/{id}.

If you are using Express, Hapi or koa-router this naming happens automatically based on the names of your routes. If you use another framework or a custom router you will see that the transactions are simply grouped together in a few big chunks named “unknown route”. In that case, you will need to help us out a little by supplying a name for each transaction. You can do that by calling opbeat.setTransactionName() at any time during the request with the name of the transaction as the first argument.

Example application using the patterns module for route handling:

var opbeat = require('opbeat').start()
var http = require('http')
var patterns = require('patterns')()

// Setup routes and their respective route handlers
patterns.add('GET /', require('./routes/index'))
patterns.add('GET /posts', require('./routes/posts').index)
patterns.add('GET /posts/{id}', require('./routes/posts').show)

http.createServer(function (req, res) {
  // Check if we have a route matching the incoming request
  var match = patterns.match(req.method + ' ' + req.url);

  // If no match is found, respond with a 404. Opbeat will in
  // this case use the default transaction name "unknown route"
  if (!match) {

  // The patterns module exposes the pattern used to match the
  // request on the `pattern` property, e.g. `GET /posts/{id}`

  // Populate the params and call the matching route handler
  var fn = match.value
  req.params = match.params
  fn(req, res)

Manual error logging

By default the Opbeat agent will watch for uncaught exceptions and send them to Opbeat automatically. But in most cases errors are not thrown but returned via a callback, caught by a promise or simply manually created. Those errors will not automatically be sent to Opbeat. To manually send an error to Opbeat, simply call opbeat.captureError():

var err = new Error('Ups, something broke!')


For advanced logging of errors, including adding extra meta-data to the error, see the API documentation.

Connect module support

If you use the connect module and an error is either thrown synchronously inside one of the middleware functions or is passed as the first argument to the middleware next() function, it will be passed to the Connect error handler.

It’s recommended that you register Opbeat as a Connect error handler. In the case where you have multiple Connect error handlers, the Opbeat error handler should be the first in the chain to ensure that it will receive the error correctly.

var opbeat = require('opbeat').start()
var conncet = require('connect')

var app = connect()

// Your regular middleware and router...

// Add the Opbeat middleware after your regular middleware

// ...but before any other error handler
app.use(function (err, req, res, next) {
  // Custom error handling goes here


See the Compatibility article for details.


If you can’t get the Opbeat agent to work as expected, please follow the Troubleshooting Guide.