Adapting jsreport

Configuration file

The most common way to adapt jsreport settings is using the configuration file. The configuration file is stored at the root directory with name jsreport.config.json. Editing this file, you can change, for example, which port service is running or scale up the number of worker processes jsreport uses. You can find full documentation of various options here.

Configuring using nodejs

In addition to configuration file-based settings, you can also use node.js and dynamically adapt jsreport to your needs. The following chapters applies to those using jsreport on-premise and want to apply some advanced configurations.

Installing and initializing jsreport on-premise will create server.js file containing the following code:


This is the most basic jsreport server startup. It searches for a jsreport.config.json file and initializes a server based on the settings it finds in it or applies defaults. The same code can be also be used when integrating jsreport directly into the existing nodejs application.

In addition to the configuration file, jsreport also parses values from environment variables, command line arguments or you can pass them directly to the jsreport instantiation. Options passed as a parameter take precedence over environment variables which then take precedence over configuration file.

In the following example are the options passed directly to the jsreport instantiation.

require('jsreport')({ httpPort: 3000, httpsPort: 0 }).init();

Additional extensions

jsreport can be easily extended with additional extensions. Extensions usually add a new engine, recipe or even complex studio functionality. There are plenty of them ready to be installed like an extension allowing you to store templates in mongodb or another extension storing reports in Microsoft Azure. You can find the list of extensions in the jsreport official documentation or on the github. If you didn't find what you are looking for, you can even implement your own custom extension. This topic is described separately here.


The goal of jsreport is to render reports. To do it programmatically you use jsreport.render:

jsreport.init().then(() => {
    template: {
      content: '<h1>Hello {{foo}}</h1>',
      engine: 'handlebars',
      recipe: 'chrome-pdf'
    data: {
      foo: "world"
  }).then((resp) => {
    // write report buffer to a file
    fs.writeFileSync('report.pdf', resp.content)    
}).catch((e) => {

See the jsreport-core for complete documentation for rendering.


In order to debug your jsreport app with nodejs debugging tools you will need to change your configuration for templatingEngines.strategy to in-process, this ensures that all operations in the rendering pipeline of jsreport are executed in the same process, which is something handy when debugging because there will be just single process needed to inspect.

Attach to existing express app

jsreport by default starts an express.js-based server running on ports specified in config. This behavior can be overridden by passing an express application instance to the options. In this case, jsreport express extension will just add required routes and middle-wares to the passed instance.

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello from the main application');

const reportingApp = express();
app.use('/reporting', reportingApp);

const server = app.listen(3000);

const jsreport = require('jsreport')({
  extensions: {
      express: { app: reportingApp, server: server },
  appPath: "/reporting"

jsreport.init().then(() => {
  console.log('jsreport server started')
}).catch((e) => {

Using rendering shortcut

It can be convenient sometimes to use jsreport shortcut require("jsreport").render if you want to just render a report. This happens to be usefull when you are not interested in starting jsreport server or storing data in the document store. Shortcut doesn't use configuration files but instead you can add/modify configurations dynamically into require("jsreport").renderDefaults, just make sure to only modify the existing require("jsreport").renderDefaults object, if you assign a new object in renderDefaults, it will not be recognized.

const http = require('http');
const jsreport = require('jsreport');

http.createServer((req, res) => {
    template: {
      content: 'Hello world',
      engine: 'handlebars',
      recipe: 'chrome-pdf'
  }).then((out) => {;
  }).catch((e) => {
}).listen(1337, '');

Dynamic access to jsreport entities

Once you have the jsreport running with some templates or reports created, you can reach them on the server using documentStore property. The API to search and manipulate underlying jsreport data is very similar to the official mongodb driver. It is just using promises.

.find({ name: 'test'})
.then(function(res) {
  // use the entity results for your own purpose

You can read more about documentStore in the article describing how to write custom extension.