Developing Kibana Plugins


For quite some time I’ve been meaning to rewrite an old Elasticsearch plugin to a new Kibana plugin. It’s quite different than you were used to. The Kibana plugins are quite new and were released in version 4.2.0. There are quite a few warnings on the Kibana Github issues regarding not having a public API yet or not making plugins at all. Essentially this means you need to keep up with the Kibana releases if you’d like to proceed anyway.


First you would need to set-up a Kibana development environment. In order to do this you can follow these steps: I would recommend not to pick the master branch.

Kibana Plugin Yeoman Generator

Next up is generating the boilerplate for your Kibana plugin using the Kibana Plugin Yeoman Generator. When following the instructions of the readme please notice there is an instruction to put the Kibana development environment at the same folder level as your plugin named kibana.

What did you get?

After we generated the project there is in the root of the project a file called index.js listed below, which ties up the whole project together. In this file we see the configuration of a Kibana plugin. The uiExports object configures your frontend of the plugin. There are more variants other than ‘app’ that can be found here. The properties an app can have are listed in the source code here. The ‘main’ property lists the path to your angular code, which is in fact the public folder of your project.

import exampleRoute from './server/routes/example';
export default function (kibana) {
  return new kibana.Plugin({
    require: ['elasticsearch'],
    // Your frontend app
    uiExports: {
      app: {
        title: 'Example',
        description: 'An awesome Kibana plugin',
        main: 'plugins/example/app'
    config(Joi) {
      return Joi.object({
        enabled: Joi.boolean().default(true),
    init(server, options) {
      // Add server routes and initalize the plugin here

The latter part of the sample above contains configuration for a hapijs server. With this you’re able to write your custom backend API. More of this you can find in the server/routes folder.

The frontend

In the 

    .when('/', {
        resolve: {
            currentTime($http) {
                return $http.get('../api/example/example').then(function (resp) {

The latter part has the uiModules object which is in charge of generating dynamic modules on the fly and coupling them. You can see the uiModules.get() function as replacement for angular.module().

    .get('app/example', [])
    .controller('exampleHelloWorld', function ($scope, $route, $interval) {
        $scope.title = 'Example';
        $scope.description = 'An awesome Kibana plugin';
        var currentTime = moment($route.current.locals.currentTime);
        $scope.currentTime = currentTime.format('HH:mm:ss');
        var unsubscribe = $interval(function () {
            $scope.currentTime = currentTime.add(1, 'second').format('HH:mm:ss');
        }, 1000);
        $scope.$watch('$destroy', unsubscribe);

When writing the templates and styles you should keep in mind that Kibana uses Twitter Bootstrap. Another note is that in the previous file mentioned there is also a chrome object, which you can ignore it will be deprecated in Kibana 5.0.0. It was used to control the navbar.

Useful links

Source Sense
Source Timelion
Kibana styleguide
The plugin I’m converting
More information about plugins