Extending Cube

For some advanced use-cases like instrumentation, or custom authentication, Cube can be extended by installing third-party Node.js packages and using them in the cube.js configuration file.

Sending Express metrics to Prometheus

const prometheusMiddleware = require('express-prometheus-middleware');

module.exports = {
  initApp: (app) => {
        metricsPath: '/metrics',
        collectDefaultMetrics: true,
        requestDurationBuckets: [0.1, 0.5, 1, 1.5],
        requestLengthBuckets: [512, 1024, 5120, 10240, 51200, 102400],
        responseLengthBuckets: [512, 1024, 5120, 10240, 51200, 102400],

Sending Cube logs to Loggly

The example below shows how to use the Node.js Loggly client to collect and send logs from Cube.

First, you'd need to install the third-party library with NPM. In our example, we're going to use winston-loggly-bulk to collect and send logs to Loggly. You can install it with the following command:

$ npm install --save winston-loggly-bulk
Running Cube in Docker

When installing custom Node.js packages for Cube running in Docker container, make sure you mount the project including the node_modules subfolder:

$ docker run -d \
  -v ~/my-cubejs-project:/cube/conf

If you need to use third-party Node.js packages with native extensions, you'll need to build your own Docker image.

Now we can require and use winston-loggly-bulk library inside cube.js:

const winston = require('winston');
const { Loggly } = require('winston-loggly-bulk');

  new Loggly({
    token: 'LOGGLY-TOKEN',
    subdomain: 'your-subdomain',
    tags: ['winston-nodejs'],
    json: true,

module.exports = {
  logger: (msg, params) => {
    console.log(`${msg}: ${JSON.stringify(params)}`);
    winston.log('info', msg, params);

You can directly use @cubejs-backend/server-core or @cubejs-backend/server Node.js packages to run Cube.

We do not recommend embedding Cube into existing Express application to share the runtime. Cube should be scaled very differently vs. other parts of Express, and embedding Cube is not the right approach in the long term, especially for larger deployments.

You can create an index.js file with the following content.

const CubejsServer = require('@cubejs-backend/server');

const server = new CubejsServer();

server.listen().then(({ version, port }) => {
  console.log(`🚀 Cube server (${version}) is listening on ${port}`);

Then start Cube as a regular Node.js application:

node index.js

Did you find this page useful?