Plugin Marketplace
Sign in

Documentation

All articles

Building a plugin

Write your first plugin

Create a plugin with the PrusaSlicer CLI, see what its Lua file holds and run it in PrusaSlicer.

A plugin is one Lua file. It describes itself in an info table and does its work in an execute function. Plugins travel in a bundle: a folder with manifest.json and one or more plugin files. Everything the Lua code can call is in the Lua API reference.

Some of the following commands assume the PrusaSlicer 3 executable is on your PATH as PrusaSlicer. On macOS it is /Applications/PrusaSlicer.app/Contents/MacOS/PrusaSlicer.

1. Create the bundle

The plugin init command asks a few questions and writes a bundle with a hello world plugin:

cd ~/plugins
PrusaSlicer plugin init com.example.my-plugin

It creates the folder com.example.my-plugin with manifest.json and one Lua file. What you answered lands in manifest.json, where you can change it later. For the licence, Tab completes or lists the known SPDX identifiers.

The id is reverse-DNS and becomes the plugin’s identity in the marketplace for good, so pick it from one of your namespaces.

2. Run it in PrusaSlicer

PrusaSlicer loads plugins from the lua folder in its configuration folder (Help → Show Configuration Folder). Link the bundle there instead of copying it, and every edit is picked up on the next rescan:

ln -s ~/plugins/com.example.my-plugin "<configuration folder>/lua/com.example.my-plugin"

Then choose Plugins → Rescan. The plugin appears in the Plugins menu under the path its info.menu names.

3. What the Lua file holds

info = {
    id = "com.example.my-plugin.hello",
    type = "project.plugin",
    title = "Hello world",
    menu = "Minimal/Hello world",
    params = {
        { name = "num", label = "Your lucky number", type = "int", default = 42 },
    },
}

function execute(params)
    print("Hello no " .. params.num .. "!")
end

The info table

Key What it is
id The plugin’s own id, reverse-DNS like the bundle’s.
type The kind of plugin. Today only "project.plugin".
title The name PrusaSlicer shows.
menu Where it goes under Plugins, e.g. Calibration/My pattern.
params The values the person fills in before it runs (below).

Each entry of params becomes one control in the dialog PrusaSlicer opens before the plugin runs:

Key What it is
name The key the value has in the table execute receives.
label The control’s label.
type float or int (a number field) or bool (a checkbox).
default The value the control starts with.

The execute function

execute(params) runs when the person confirms the dialog. params holds what they entered, keyed by each parameter’s name, so the example reads its number as params.num.

4. Do something with the project

The api module builds geometry and the project takes it. This plugin adds a cube of the size the person asks for:

info = {
    id = "com.example.my-plugin.cube",
    type = "project.plugin",
    title = "Cube",
    menu = "Examples/Cube",
    params = {
        { name = "size", label = "Size [mm]", type = "float", default = 20 },
    },
}

function execute(params)
    local cube = api.make_cube(params.size, params.size, params.size)
    api.project:add_object({ mesh = cube })
end

api.make_cube returns a Mesh, and add_object takes an ObjectDefinition: a table whose mesh is the geometry, with an optional position, rotation and print settings.

What a plugin may touch

The plugin runtime is a sandbox on purpose:

  • The standard os and io modules are not there.
  • emboss_svg, load_stl and require reach only files in the plugin’s own folder.

So a plugin brings what it needs inside its bundle, and cannot read or change anything else on the computer.

Next