Home  /  System  /  Custom Modules

How to make Custom Modules for Shinobi

customAutoLoad modules are as they sound, custom modules. You can change operation of the backend and frontend without modifying the core. Running custom scripts with Shinobi.

Custom Auto Load Modules (customAutoLoad Modules) are a functions sets that don't exist in the official source code but runs as if it does.

You can change or add functions in the backend and frontend.

1. Open your Shinobi folder. By default this is /home/Shinobi .

cd /home/Shinobi

2. Open the libs folder and you'll find customAutoLoad. Open it.

cd libs/customAutoLoad

3. You'll notice this folder is empty. Shinobi does not include any modules but you can try a few from here . Just drop in the module folder (or file) to make it ready to run. Then restart Shinobi to make it load.

pm2 flush && pm2 restart camera && pm2 logs 
index.js This is the initiator for the module. Without it the folder (module folder) will do nothing when Shinobi is restarted.

Here is where you place your code that will alter the operation of the core.
web This folder can have frontend files that will automatically load. See other items on this table.
web/libs/js You can place auto-loading JavaScript files for the frontend here. See "How to Automatically load Libraries in the Frontend" section further down in this article for more details.
web/libs/css You can place auto-loading CSS files for the frontend here. See "How to Automatically load Libraries in the Frontend" section further down in this article for more details.
web/pages/blocks You can place auto-loading EJS files for the frontend here. See "How to Automatically load Libraries in the Frontend" and "Loading CSS and HTML" sections further down in this article for more details.

onMonitorEvents.js is an example of adding events to certain monitor events within the system. Event as-in real-time action, not a Detector Event.

This file would be placed in this file structure.


Sample Module onMonitorEvents.js

module.exports = function(s,config,lang,app,io){
    const memoryCachedMonitorModes = {}
    s.onMonitorInit((initiator) => {
    s.onMonitorStart((monitorConfiguration) => {
    s.onMonitorPingFailed((monitorConfiguration) => {
    s.onMonitorDied((monitorConfiguration) => {
    s.onMonitorSave((newMonitorConfiguration,formPosted,saveRequestResponse) => {
        // Let's make a simple cache to check if the monitor mode has been changed.
        const groupKey =
        const monitorId = newMonitorConfiguration.mid
        const cachedMode = memoryCachedMonitorModes[groupKey + monitorId]
        if(cachedMode !== newMonitorConfiguration.mode){
            console.log(`Monitor Mode has Changed! Was ${cachedMode} and is now ${newMonitorConfiguration.mode}`)
        memoryCachedMonitorModes[groupKey + monitorId] = newMonitorConfiguration.mode

    console.log('Loaded "customAutoLoad" Sample : onMonitorInit, onMonitorStart, onMonitorPingFailed, onMonitorDied, onMonitorSave')

Here we'll focus on showing you JavaScript file loading. Similar practice applies to CSS and HTML. See below for key details about them.

See this example that was made for Dashboard V2. It has a folder structure similar to the root of Shinobi itself.

You can follow the pathing web/libs/js to find a single file : dash.customBlock.js .

The prefix of the filename is important, it designates whether it runs in the Dashboard or the in Superuser panel. Here are the prefixes available and where they will auto load.

  • dash. : Loads in the main dashboard. The panel where you manage cameras.
  • super. : Loads in the Superuser panel. Where you manage the system and create Admin Accounts.

Example Filenames :

  • dash.customBlock.js : Will load in Dashboard.
  • super.customBlock.js : Will load in Superuser panel.

The same methodology applies to CSS files except the path is  web/libs/css instead. Here is an example . This file is empty because the module didn't actually add or change any CSS. The file only exists as demonstration.

Loading HTML is done with EJS and also follows a similar premise. These files are to be placed in  web/pages/blocks . Here is an example.

Sample Page Block from ExtraBlocks Sample Module dash.customBlock.ejs

<!--Some Custom Modal-->
<div class="modal full fade search-parent" id="someModal" role="dialog" aria-labelledby="someModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        <h4 class="modal-title" id="someModalLabel"><i class="fa fa-photo"></i> &nbsp; <%-lang.ModalTitle%></h4>
      <div class="modal-body">

      <div class="modal-footer">
          <button type="button" class="btn btn-default pull-left" data-dismiss="modal"><i class="fa fa-times"></i> <%-lang.Close%></button>
          <button class="btn btn-info"><%-lang['Sample Language Stuff']%></button>


All content is property of their respective owners.