Autostart JavaScript npm packages on boot with systemd

This tutorial is about the same as my previous one for python written almost exactly one year ago. So without further ado let’s just get into it.

How To

Replace <YOUR-NAME> with a name descriptive of your project. Make it memorable because you have to remember it to stop/restart your project or get the logs.

Replace PATH-TO-PROJECT with the path to your project (something like /home/user/todo-list). Be aware that you still have to use absolute paths to reference your npm executable.

Replace SCRIPT-NAME with the npm script you want to execute. This will probably be something like start or dev. These scripts are listed under the scripts property in your projects package.json.

  1. If you have not yet installed your npm packages then of course do this first. Go into your project folder and execute

    npm i
    
  2. Find out the current path to your npm executable with which. Small recommendation by me for all you macOS and Linux people: Use Node Version Manager (nvm). It works without problems with this, the resulting paths will just look a bit differently.

    which npm
    

    This will return a path in your file system, use this later as <YOUR-NPM-PATH>

  3. Create a service via:

    sudo systemctl --force --full edit <YOUR-NAME>.service
    

    And paste

    [Unit]
    Description=<(Optional) Description of your project>
    After=network.target
    
    [Service]
    WorkingDirectory=/home/user/<PATH-TO-PROJECT>
    ExecStart=<YOUR-NPM-PATH> run <SCRIPT-NAME>
    
    [Install]
    WantedBy=multi-user.target
    
  4. Save it and reload all Systemd services via

    sudo systemctl daemon-reload
    
  5. Enable autostart on boot of your new service:

    sudo systemctl enable <YOUR-NAME>.service
    

Variations

Time of start

The previous example assumes you want your script to start after the network interfaces were initialized and the OS is ready to use. You can change this behaviour by changing the values of the After= and WantedBy= parameters in the service file.

Execute as user or group

Lastly you can run your project as specific Linux user and/or group e.g. as user “pi” if there are some specific permissions requiring this. For this to work you specify a user or group in the service part of the file. This is an example on how to do this for the user pi:

[Unit]
Description=<(Optional) Description of your project>
After=network.target

[Service]
ExecStart=<YOUR-NPM-PATH> <PATH-TO-YOUR-SCRIPT>.py
User=pi
Group=pi

[Install]
WantedBy=multi-user.target

Managing the running script

Stop & Restart

You can stop your service by executing:

sudo systemctl stop <YOUR-NAME>.service

The same goes for restarting it via:

sudo systemctl restart <YOUR-NAME>.service

Status & Basic logs

You can check if your service is running or crashed by typing:

sudo systemctl status <YOUR-NAME>.service

This will also show you the last few lines logged by your script (e.g. print statements).

Disable autostart again

You can disable autostart for your new service at any time by typing:

sudo systemctl disable <YOUR-NAME>.service