Hello, hello!

Right now the most popular way to distribute Blender addons and scripts is to give a download link that the user can use to get a copy of the script.

They can then add it into their user preferences

Blender save addon

or use it from the Blender CLI

blender --python /path/to/my-downloaded-addon.py.

I wanted to share a slightly easier way to distribute your Blender addons and scripts by using npm (or any other package manager).

The idea is to be able to:

npm install -g my-blender-addon
# Run script one off in the Blender CLI
blender -P `my-blender-addon --run`
# or install and save in Blender user preferences
my-blender-addon --install

When you wrap a command in backticks in bash the output of the command gets used as an argument.

So the above my-blender-addon --run command simply prints the absolute file path of the python script that you want to run.

That way, the -P Blender CLI flag ends up getting called with the absolute path to your Blender script.

Let’s say you have a Blender addon package with a tree like so:

tree ./my-addon-package
├── cli.js
├── install-addon.js
├── install-addon.py
├── run-addon.js
├── run-addon.py
├── my-addon-script.py

There are two JavaScript scripts that you’ll expose via your npm module’s CLI. install-addon.js and run-addon.js. You can expose them behind any flag such as --install or --run, for example.

Both scripts simply console.log their corresponding Python script.

// install-addon.js
var path = require('path')
console.log(
  path.resolve(__dirname, './install-addon.py')
)
// run-addon.js
var path = require('path')
console.log(
  path.resolve(__dirname, './run-addon.py')
)

The addon install script takes the absolute path to your Blender addon and passes it into Blender’s addon_install method.

// install-addon.py
dir = os.path.dirname(__file__)
addonFilePath = dir + '/my-addon-script.py'
bpy.ops.wm.addon_install(filepath=addonFilePath)
bpy.ops.wm.addon_enable(module='my-addon-module-name')
bpy.ops.wm.save_userpref()

The run script installs and enables the addon and then executes it.

// run-addon.py
dir = os.path.dirname(__file__)
addonFilePath = dir + '/my-addon-script.py'
bpy.ops.wm.addon_install(filepath=addonFilePath)
bpy.ops.wm.addon_enable(module='my-addon-module-name')
bpy.ops.rigging.myAddonMethodName()

So if a user ran:

npm install g my-blender-addon
blender --python `my-blender-addon --run`

It would really resolve to:

blender --python `/path/to/run-addon.py`

You can check out blender-iks-to-fks and blender-actions-to-json for real examples of npm-installable Blender scripts/addons.

Hope it helps!

- CFN