deli-slicer
A CLI-first slicer front end for 3D printing.
deli keeps a print job as a plain-text deli.toml in the current directory. Each
subcommand edits that file and exits, so a print is set up with a few commands in a
shell and a file you can read, with nothing else to open. Slicing
is done in-process by PrusaSlicer's libslic3r, and the printer profiles come from
OrcaSlicer's repository, converted by deli, so neither slicer needs to be installed:
the printers OrcaSlicer knows are a deli setup away on a machine that has never had a
slicer on it.
A folder of models is the project, and there is nothing to save: every command
updates deli.toml as it goes. Come back months later, cd into the folder, and
deli send --print prints the same parts, placed the same way, with the same profiles
and settings.
Everything deli prints is plain text, with --json where a program wants data, and
every command is one a shell runs. That makes deli simple for humans to use directly or
through an AI: the repository ships a skill that briefs an assistant (see "Using deli
from an AI assistant"). When something needs seeing, deli view shows the parts and
the sliced G-code in your browser, and even there every change it makes is a deli
command you could have typed.
deli setup # once: tab completion, your printer, and how to reach it
deli add 3DBenchy.stl
deli slice # how long it will take, and how much filament
deli view # the sliced Benchy in your browser, layer by layer
deli send --print # to the printer, and start it
Status: early. Everything above works; deli converts and slices for most of the printers OrcaSlicer knows, but has printed on only two so far. See "Not done yet" at the end.
Motivation
deli came out of my frustrations with the slicers I was using:
- PrusaSlicer has no settings built in for my printer, an Elegoo Centauri Carbon.
- OrcaSlicer does, but it crashes often and generally does not like my PC.
- OrcaSlicer supports lots of printers, but it is somewhat focused on Bambu Lab's.
- I have two printers, the Elegoo and a Voron, and want to configure both easily. I found myself using both slicers, plus Cura now and then.
- Both have bewildering settings screens, mostly because there are so many settings and options. Most of them stay at their defaults, so finding a particular one means hunting and guessing, and the guess is often wrong.
So deli takes a printer's settings from OrcaSlicer, slices with PrusaSlicer's engine,
and has no window to open. Every printer is a profile in one library, chosen for each
print, so one tool can serve them all. A print is a short text file that holds only
what you changed, and you change a setting by its name: deli set infill 20%. When
the name is not quite right, deli suggests the ones that are close.
The longer story, with clips of each part, is in the blog post deli: A 3D Printer Slicer That Lives in My Shell.
Install
deli is a Python package with PrusaSlicer's slicing engine compiled in, on PyPI as
deli-slicer. On Linux (and Windows, in WSL:
see below) or macOS, with uv:
uv tool install deli-slicer
(pipx install deli-slicer does the same.) Without uv, one line installs it first,
then deli:
curl -LsSf https://raw.githubusercontent.com/dcruver/deli-slicer/main/install.sh | sh
Either way uv fetches Python 3.12 if you don't have it. Then run deli setup. Later,
deli update installs the latest release the same way (--check only says whether
there is one; deli update 0.17.0 a particular release), or run the
script again, with DELI_VERSION=0.17.0 in front of sh for a particular
release. deli status mentions a newer release when one is out, looking once a day;
deli config update_check false stops it looking.
The wheels
Each release is four wheels, one per platform with the engine inside, on PyPI and on
the release page; nothing needs
building, and pip install deli-slicer in an environment of your own takes them too.
The Linux wheels need glibc 2.28 or newer, which most distributions from 2019 on have:
Debian 10, Ubuntu 18.10, RHEL/Alma/Rocky 8, Fedora 29 and later. The macOS wheels need
macOS 11 (Apple Silicon) or 10.15 (Intel). All of them need Python 3.12 or newer.
uv itself runs on any of those Linuxes but needs macOS 13; on an older Intel Mac,
install Python 3.12 and use pipx install deli-slicer, or pip install deli-slicer in a
virtual environment of your own.
Releases up to 0.16.0 were on GitHub only, under the package name deli, which on PyPI
is another project. A deli that old cannot deli update past it: run the install line
above once more, which also clears the old package's environment away.
On Windows, in WSL
There is no Windows wheel; on Windows, deli runs in WSL, Windows' own Linux, with the Linux x86-64 wheel. In PowerShell, once:
wsl --install
Then, in the Ubuntu terminal it opens:
curl -LsSf https://raw.githubusercontent.com/dcruver/deli-slicer/main/install.sh | sh
It should work as on Linux (see below for how far that has been checked), with a few things to know:
- Your printer: give
deli setupits IP address, or a name your router knows. Names ending in.localoften don't resolve inside WSL. On Windows 11, WSL's mirrored networking (networkingMode=mirroredin.wslconfig) puts WSL on your network like any other program. deli view: open the address it prints in your Windows browser.- Your models: Windows' folders are under
/mnt/c/, soC:\Users\you\Downloadsis/mnt/c/Users/you/Downloads. Reading from there is slower than from WSL's own folders, but fine for a few models.
How far this has been checked: nobody has used deli on a Windows PC yet. What is
checked is automatic: for each release, a GitHub Actions job on one of GitHub's Windows
Server machines sets up WSL 2 with Ubuntu 24.04, installs the wheel with uv (not
with the one-line script), and runs deli's test suite, which slices but talks only to fake printers. deli setup
and deli send with a real printer, deli view in a Windows browser, the networking
notes above and models under /mnt/c/ are untested; they come from how WSL works, not
from trying them. If you run deli on Windows, an issue saying how it went would help.
Then let deli set itself up:
deli setup
It sets up tab completion for your shell, then asks for your printer's hostname or IP
address and asks the printer what it is: a Klipper printer says its nozzle, bed and
height, and setup lists OrcaSlicer's printers that fit; an Elegoo printer says its model,
and setup asks only the nozzle size. The printer is imported with Orca's process and
filament for it, named as the printer names itself (a Klipper printer's hostname, or
the address's first label), given the settings that fit what it reported (no taller
prints than its Z travel, the material passed to a PRINT_START that reads it), and its
address kept for deli send. A printer deli cannot reach is found by any words of its
name instead. A Bambu Lab printer is recognised, but deli cannot send to one yet. Run it
again to add or change a printer. Everything it does can also be done step by step, as
the next sections show.
From source
The first build compiles PrusaSlicer's dependencies (about 35 minutes) and then the
engine (about 15), and needs CMake, Ninja, a C++17 compiler and about 5 GB of disk.
PLAN.md has the details under "Dependency build"; the short version:
git clone https://github.com/dcruver/deli-slicer.git && cd deli-slicer
git submodule update --init --depth 1
ci/build-deps.sh # PrusaSlicer's dependencies, into build/deps
make install
make install installs deli as a uv tool pointing at the checkout, so git pull
updates it; after a change to the C++ binding, make reinstall. make wheel builds
a wheel in dist/ to give to someone else.
Shell completion
Completion covers commands, options, your printers and their nozzles, printers,
filaments and processes (yours and OrcaSlicer's), the parts of the current print,
setting names and their short names, and config keys. deli setup sets it up; by hand, it is one of:
eval "$(deli completion bash)" # in ~/.bashrc
eval "$(deli completion zsh)" # in ~/.zshrc
deli completion fish > ~/.config/fish/completions/deli.fish
deli setup puts bash's in ~/.local/share/bash-completion/completions/ when the
bash-completion package is installed, which loads it with nothing in ~/.bashrc, and
adds the line to ~/.zshrc only if you say yes.
Set up a printer
To slice, deli needs three things for your printer: the printer itself (bed size,
nozzle, start and end G-code), a process (layer height, speeds, infill: what
PrusaSlicer calls print settings) and a filament. You don't write any of them.
deli converts them from OrcaSlicer's
presets, which cover over a thousand printers, and choosing your printer gets all
three. You don't need OrcaSlicer installed. deli setup does the steps below for you;
this is what it does, and how to do more.
1. Find your printer
deli vendor # the vendors, with how many printers each
deli vendor Voron # one vendor's printers
deli vendor "voron 2.4" # or any part of a name: the printers that match
Orca's printer names end with the nozzle size, such as Voron 2.4 350 0.4 nozzle. Pick the one with the nozzle your printer has; most printers ship with 0.4 mm.
Vendor names are Orca's folder names, so Bambu Lab's printers are under BBL; the
list shows what a vendor's printers are called when it differs.
2. Choose it
deli printer "Voron 2.4 350 0.4 nozzle"
Any words of the name that are enough to tell it apart will do ("voron 350 0.4"), in
any order and any case. A printer that is not in your library yet is imported from Orca
as it is chosen, with the process and filament OrcaSlicer starts it with, and all three
become the defaults for new prints. Every choice ends with the same block, what the
print is now, with a note under anything that changed:
Imported printer 'voron-2.4-350-0.4-nozzle' from Orca 2.4.2's 'Voron 2.4 350 0.4 nozzle' (51 settings, 7 left out)
Imported process '0.20mm-standard-voron', Orca's default for this printer (94 settings, 16 left out)
and made it the default process for new prints on 'voron-2.4-350-0.4-nozzle'
Imported filament 'generic-pla-system', Orca's default for this printer (27 settings, 20 left out)
and made it the default filament for new prints on 'voron-2.4-350-0.4-nozzle'
Made 'voron-2.4-350-0.4-nozzle' your default printer for new prints
Printer voron-2.4-350-0.4-nozzle bed 350 x 350 mm, height 325 mm, nozzle 0.4 mm, firmware klipper
Filament generic-pla-system PLA, nozzle 220 °C, bed 55 °C
from your config for this printer
Process 0.20mm-standard-voron layers 0.2 mm, infill 15% cubic, perimeters 3
from your config for this printer
Parts none yet; add one with: deli add <file>
Sends to nowhere yet; set with: deli config printers.voron-2.4-350-0.4-nozzle.host <moonraker://...|elegoo://...|octoprint://...>
Settings none changed
deli status shows the block at any time.
You can slice now. The settings "left out" are ones PrusaSlicer's engine has no equivalent for; they need nothing from you. PRINTERS.md says which of Orca's printers deli has converted and sliced with, and why the rest fail. Slicing is not the same as printing well; see "Not done yet" for what has actually been printed.
Defaults are only filled in where you have none, so a second printer does not change
your default printer, and a filament you chose yourself stays chosen. Once imported, a
printer is in your library (~/.config/deli/), and choosing it again reads it from
there: a newer deli or a newer Orca never changes a printer under you.
A filament or process belongs to a printer: it is how a material, or a layer height,
prints on that machine's hotend and bed, which is why Orca keeps one per printer family
and names them Generic PLA @System, Elegoo PLA @ECC. deli keeps each under the
printer it was converted for, named without that tail: generic-pla under your Voron
and elegoo-pla under your Centauri are two files, each what Orca says for its
printer. deli filament lists the ones for the print's printer; choosing one another
printer has converts it for this one.
3. Other filaments and processes
deli filament # the filaments for your printer, the one in use marked
deli filament "Generic PETG @System" # choose one
deli process # the processes for your printer
deli process "0.15mm optimal" # choose one
deli filament lists the filaments made for the print's printer (or your default one),
with any you have used or loaded yourself, and marks the one in use and the default.
deli process does the same for processes, and deli printer lists your printers
first, each with its nozzles, then your printer's vendor's. It makes no difference
whether one has been used before: choose any of them by name, or words of it, and deli
fetches and converts it as needed, for your printer. Orca's Generic filaments (Generic PETG @System and so on) fit any printer; the
list counts them. --default makes a choice what new prints start with instead of
choosing it for this one.
deli import: more control
deli import orca printer|process|filament "<name>" converts one of Orca's presets
without choosing it, and says more about the conversion: the notes on what
deli did, and with -v every Orca setting left out. Run it again to replace a profile
with a fresh conversion, after a deli upgrade that fixes the converter, say.
--printer "<name>" converts a process or filament for another printer than the one it
says it fits, --printer-only imports a printer without its defaults, --name stores
it under another name and -o FILE writes the INI file instead.
Where the presets come from
deli reads Orca's presets from its GitHub repository at release 2.4.2, the release
PRINTERS.md was made from. A release never changes, so what is fetched
is kept in ~/.cache/deli/orca/ and read from there afterwards. Other sources:
deli import ... --ref main(or any tag) reads another version of Orca's presets, for printers newer than the release. Only releases are kept;mainis fetched each time.deli import ... --localreads the OrcaSlicer installed on this machine instead, including presets you have edited or created in Orca, which only exist there.--orca DIRadds a folder of Orca presets.
Listing every vendor makes one call to GitHub's API, which allows 60 an hour without signing in, and is then kept like the rest.
Without OrcaSlicer's presets
deli load takes a PrusaSlicer INI file from a path, a file:// URL or an https://
URL, including a link to a file's page on GitHub; --printer NAME says which printer a
filament or process is for (default: the print's, else your default printer):
deli load printer ~/Downloads/my-printer.ini --name my-printer # a PrusaSlicer export, say
deli load filament https://example.com/profiles/my-petg.ini # or a file someone hosts
deli printer my-printer # then choose it as usual
Without --name, a profile is named as the file names it (PrusaSlicer's
printer_settings_id and the like), and deli load says what that is.
A full PrusaSlicer export holds a printer, a process and a filament; deli load printer
keeps only the printer's settings, so load it once for each. This repository's
profiles/ has a few to try, converted from Orca's and checked to slice.
Anyone can host a printer this way: a PrusaSlicer INI file at any https:// address.
Imported or loaded, a file never carries a printer's network address or API key; those
go in your config (below).
Name your printer
Orca has a profile per nozzle, so its names are long and a nozzle change is another profile. deli lets you name the printer you have, and keep its nozzles under that name:
deli printer "voron 2.4 350 0.8" --name voron # your Voron, with its 0.8 nozzle in
deli nozzle 0.4 # you changed the nozzle: Orca's 0.4 profile comes in
deli nozzle # its nozzles, and which is in it
deli printer voron # this print goes on it, with whatever nozzle it has
The address, the settings you give it with deli set --printer voron, and deli send
all go by the printer's name, whatever nozzle is in. Each nozzle keeps its own profile
and the filament and process a new print starts with. deli setup names a printer after
its host name. A printer you never named is one named after its profile, as before.
Tell deli where your printer is
To send prints to it, deli needs its address:
deli config printers.voron.host moonraker://voron.local
And to change what new prints start with:
deli printer voron --default # the printer new prints start with
deli filament "Generic PETG @System" --default # the filament new prints on it start with, with this nozzle
deli process "0.15mm Optimal @Voron" --default # its usual process, with this nozzle
This writes ~/.config/deli/config.toml, which you can also edit by hand. host is
where deli send sends; its scheme says what kind of host the printer is:
moonraker:// (Klipper), octoprint:// or elegoo:// (Elegoo's Centauri Carbon)
(api_key alongside, if the host needs one). filament and process are what a new
print on that printer starts with, kept per nozzle, so you do not choose them again for
every print. They are defaults and nothing more: a print that chooses another filament
is sliced and sent like any other.
The three --default lines write the config's printer key (deli config printer <name> sets the same one), and the filament and process of the nozzle the print is
on (printers.<printer>.nozzles.<size>.filament, or printers.<printer>.filament for
a printer named after its one profile). A print started in a new directory, with
deli add say, takes all three, written into its deli.toml like any other choice. A
print that wants something else chooses it with deli printer, deli filament or
deli process as usual, and changing a default later leaves the prints you already have
alone. deli printer lists your printers first and marks your default, and
deli config shows everything that is set.
Print something
In a new directory:
deli add 3DBenchy.stl # STL, OBJ, 3MF or AMF; the print starts with your default printer, filament and process
deli add https://example.com/boat.zip # or fetched from the web: a model file, a zip of them, a page linking to them, or a Printables model (--file picks one of several)
deli printer "bambu p1s 0.4" # another printer for this print, by any words of its name; its filament and process come with it
deli filament "generic petg" # another filament than its default, converted for this printer
deli set infill 20% # or any PrusaSlicer setting by name
deli supports organic # automatic supports, for a model that needs them: on, off, grid, snug, organic
deli scale 150% # a bigger boat
deli scale z 60mm # or one side to a size, the others left as they are: z is up, however the part is turned
deli rotate 45 # turned on the bed
deli mirror x # or its mirror image, for the other side of a pair
deli move 60 80 # put it there instead of in the middle
deli pause 40 # pause once layer 40 is done: change the filament for a two-colour boat
deli view # the Benchy on the bed in your browser, live; the shell stays free
deli slice # how long it takes, how much filament, and where it lies on the bed; the view then shows it layer by layer
deli send # uploads it, slicing first if needed; add --print to start printing
deli status # the print at a glance: printer, filament, process, parts, where it sends, settings, G-code
deli printer, deli filament, deli process and deli nozzle show the same block
after a change, with a note under each row that changed: what it was, and why the
filament or process followed the printer.
Several pairs go in one command, deli set infill_pattern rectilinear infill 100%,
checked together, each against the print with the pairs before it applied, and written
only when every one passes: a density only some patterns allow may follow its pattern,
and a batch with a bad pair changes nothing.
deli set with nothing after it lists the settings this print changes, each with what
its profile had, so the few things you changed are never lost among the hundreds you
didn't. Settings that come from the printer, filament or process are not in that list;
to look one up, give its name, and deli says where its value comes from:
$ deli set
fill_density = 20% (the process '0.30mm-standard-elegoo-cc-0.6-nozzle' has 15%)
layer_height = 0.25 (the process '0.30mm-standard-elegoo-cc-0.6-nozzle' has 0.3)
$ deli set temperature
temperature is not changed by this print; the filament 'elegoo-pla-ecc' has 210
$ deli set fuzzy_skin
fuzzy_skin is not changed by this print; PrusaSlicer's default has none
deli unset layer_height goes back to the profile's value. Several settings go in one
command, deli set infill 20% walls 3, and deli unset alone lists what there is to
remove. When you know roughly what a setting is called, give that: deli set temp
lists every setting with temp in its name, each with its value and where it comes from.
A value can come from a file, @ in front of its name, which is how to give G-code:
deli set --printer voron start_gcode @start.gcode
deli set start_gcode # shows it as lines
deli keeps the text, not the file's name, written as lines in deli.toml or your config,
so it reads and edits like G-code there:
[printers.voron.settings]
start_gcode = '''
M190 S{first_layer_bed_temperature[initial_extruder]}
M109 S[first_layer_temperature]
PRINT_START EXTRUDER=[first_layer_temperature] BED={first_layer_bed_temperature[initial_extruder]} MATERIAL=[filament_type]
'''
On the command line a line break is \n, as PrusaSlicer writes it. A filament's start and
end G-code are one value per extruder in PrusaSlicer, ; between them; a value you give is
one extruder's, comments and all, and several extruders' are written quoted as PrusaSlicer
does ("..." ; "...").
A setting you want on every print, whichever printer, goes in your config instead of
the print, with --global:
deli set --global infill 20% # for every print, in ~/.config/deli/config.toml
deli set --global # list those
deli unset --global infill # back to each print's profile
It lies under every print's own settings, which still win, so deli set infill 30% in
one directory changes that print alone, and the listing says which is which. A global
setting changes a print's G-code like any other change: deli send slices again first.
A printer that is not quite Orca's any more, after upgrades and modifications, keeps its differences the same way, under its name; so does a spool that prints best a little off its profile, or a process you always adjust:
deli set --printer voron max_print_height 310
deli set --printer voron start_gcode "..."
deli set --filament generic-pla temperature 215 # this print's printer's PLA (or your default printer's)
deli set --process "0.20mm Standard" walls 3
deli set --printer voron --filament generic-pla filament_max_volumetric_speed 30 # another printer's
deli set --printer voron # list a profile's
A filament's or process's settings are the printer's, as the filament itself is: the
pressure advance and the volumetric cap that suit a material in one hotend are not
right in another, so they are kept under the printer (printers.voron.filaments.generic-pla.settings).
A hotend's own limit, the most it can melt whatever the material, is a different
setting, max_volumetric_speed, and goes under the printer (deli set --printer voron max_volumetric_speed 30): the engine applies it beside the filament's, the lower
winning. deli set --printer refuses the filament's cap, which there would silence
every filament's own.
They go in your config beside Orca's profile, not into it, so every print with that
profile has them, and a deli import of a newer Orca profile keeps them. This is deli's
custom profile: Orca's base plus your changes. The layers, each winning over the one
before: the chosen profiles; your global settings; the printer's; the filament's; the
process's; the print's own. A name can be any part of it that only one profile in your
library has.
A print can hold several models, each added the same way, and copies of one:
deli add 3DBenchy.stl --count 4 prints four, arranged on the bed for you. With more
than one model, scale, rotate, mirror and move take the model's name first
(deli scale 3DBenchy 150%).
A model can come from the web: deli add <url> fetches it into the directory, adds it
like any file, and records the address as the part's source in deli.toml. The
address may be of the model file itself, of a zip holding model files, or of a page
linking to them, such as a file's or a folder's page on GitHub; with several model files
to choose from, deli lists them and --file NAME picks one. Adding the same address
again adds a copy. A Printables model's page (printables.com/model/...) works too:
the page itself only opens in a browser, but deli asks the site's API for the model's
files and their links, which it hands out without a login. Other model sites do not have
such a route: Thingiverse's pages and links refuse anything but a browser, and
MakerWorld, Thangs, Cults3D and MyMiniFactory want an account before handing out a file.
For those, download the file in your browser and deli add it; support for a site is
added when it turns out to have a way in like Printables', one site at a time.
The G-code is kept in deli's cache (~/.cache/deli/gcode/), not beside deli.toml:
deli send and deli view find it there, and deli send slices again by itself when
the print has changed since. deli slice -o FILE (or -o DIR, -o . for here) also
writes a copy where you want it, to put on an SD card or open in another program.
After the time and filament, deli slice says where the print lies on the bed and how
far it is from each edge, and prints as warning: lines anything PrusaSlicer's engine
complained about while slicing (a tree support that lost a branch, say), each once.
Supports are PrusaSlicer's automatic ones. deli supports on uses the style the
process came with (Orca's tuning for the printer carries over); organic, snug or grid pick one and turn them on; --angle 45 supports
overhangs steeper than that, and --buildplate-only keeps them off the part itself.
deli supports alone says what is in force and where it comes from. Underneath these
are ordinary settings (support_material, support_material_style, ...), so
deli set shows them and deli unset supports turns them off.
Parts are arranged on the bed for you, a single part in the middle. deli move 60 80
puts the middle of a part at x 60, y 80 instead, in millimetres from the bed's origin
(the axes deli view draws). The first time something on a plate is moved, everything
else on that plate keeps where it is, given a place of its own (deli move says so), so
that moving one thing never moves another; moved parts and copies that would overlap are
refused.
deli move z -0.25 sinks a part a quarter of a millimetre into the bed, which is what
a part resting on an edge or a lip needs to get a first layer; what is below the bed
is not printed. deli move auto gives the placing back, and deli translate is the
same command under another name. A part with copies is moved a copy at a time:
deli move box --copy 2 60 80 places the second, and deli rotate box --copy 2 x 90
turns it alone (rotating the part turns every copy). deli arrange has every part and
copy arranged again, as before any was moved; deli arrange --plate 2 only what was
moved on plate 2, which stays there.
What does not fit on the bed goes on a second plate, and so on, as many as it takes, and
deli slice writes a G-code file for each (stand-plate1.gcode, stand-plate2.gcode)
and says what is on each and how long it takes. deli move box plate 2 keeps a part to
plate 2, its place (deli move box 60 80) then on that plate, and deli move box --copy 3 plate 2 keeps only the third copy there; deli move box auto lets it go on
the first plate it fits on again. A print that fits on one plate never
mentions plates. deli send uploads every plate; deli send --plate 2 --print uploads
plate 2 and starts it, since a printer prints one plate at a time.
deli pause 30 has the printer pause once layer 30 is done, to drop in a magnet or a
nut, or to change the filament: deli has no separate colour-change command, because a
pause is where you change it. What is written is the printer's own pause G-code (on
many printers M600, the filament-change command itself; deli set pause_print_gcode
changes it). Layers are counted as the slider in deli view counts
them, so slide to the last layer you want printed before the pause and use that
number. deli slice reports each pause with its height, and refuses a pause after a
layer the print does not have. On a print with several plates, deli pause 30 --plate 2
pauses plate 2; without --plate a pause is the first plate's.
deli view opens a page in your browser and gives the shell straight back; the page
follows the print as you change it. It shows the parts on the bed and, once deli slice
has run and for as long as the G-code is still the print's, every extrusion in it,
supports included, coloured by what it is for. The parts are then drawn faint over the
extrusions, or hidden: Model in the legend shows or hides them, and they come up by
themselves for the tools that need them. When the print has changed since it was
sliced, or has never been, the page shows the parts and says so, with a Slice button
that runs deli slice and shows what it printed. Sending stays in the shell. A print
with several plates has a button for each, and the page shows one plate at a time.
The slider at the bottom goes through the layers, each with the time it takes, cutting
the parts at the same height; a box shows only that layer. With no G-code it cuts the
parts at a height instead, to show their inside. The colours turn lighter where the
print pauses. The legend says how long each kind of extrusion takes, and travel; click
one to hide or show it. "Colour by" colours the print by speed, flow (mm³/s) or layer
time instead, from blue for the least to red for the most, which shows at a glance what
is slow. The times are PrusaSlicer's estimate from reading the G-code back, as its own
G-code viewer makes it, and can be a minute or two from the one deli slice reports.
Overhangs shows in red the faces supports would hold up (at the print's
support_material_threshold, or the angle PrusaSlicer works out when it is 0).
Click a part to select it, Shift-click to add another, or click a part's name in the box
for every copy of it; a tool used on a selected part acts on the whole selection, one
command per copy, and Remove gives the deli remove that takes the selection out. Click the
empty bed, Clear or Esc to select nothing.
Dragging, Rotate, Lay flat and Mirror change the print with deli's own commands: drag a part over
the bed for its deli move (a copy is moved by itself, with --copy; a drag that would put
it off the bed or on another part offers nothing); with Rotate (or R) drag a part around to
turn it on the bed, by 15°, or 1° with Shift, for its deli rotate ... z (and, for one not
yet placed, the deli move that keeps it where it is); or with Lay flat click a face of one
for the deli rotate that lays that face on the bed (that copy's only); with Mirror click a side of one
for the deli mirror along that side's axis (a side for left to right, the top for top to bottom); Arrange, once something has been
moved, gives deli arrange (--plate N for the plate shown, on a print of several); Pause here, beside the layer slider, does the same for deli pause at that
layer. The page shows the command, and Apply runs it (Copy, to run it yourself); either
way deli.toml changes as the command says and the page follows. Once the print is
sliced, and deli knows the printer's address, Send and Print run deli send for the
plate shown (Print, which starts the printer, asks once more). Only the page at the
address deli view printed can apply commands. To measure, press Measure (or M) and
click two points on the parts or the print: the line follows the pointer from the first,
and the page shows the distance between them and along each axis, snapping to a corner
of a part when you click near one. Esc clears; a right-click clears and puts the tool
down. The mm / in switch, below the print's description, shows every length on the page (sizes,
places, layer heights, measurements) in millimetres or inches; commands stay in
millimetres. Supports, beside the tools, gives deli supports on or off.
The page is served in the background until it has been closed for ten
minutes, or until deli view --stop. When the printer's profile asks for a thumbnail,
deli slice draws one into the G-code for the printer's screen.
deli printer, deli filament, deli process, deli set, deli supports,
deli scale, deli rotate, deli mirror, deli move and deli pause without arguments show what
is chosen. deli remove, deli unset, deli scale 100%, deli rotate 0, deli mirror off,
deli move auto, deli arrange and deli pause off undo things. Everything is in deli.toml, which
is plain TOML you can edit, comment and commit:
pause = [40]
[printer]
name = "voron-2.4-350-0.4-nozzle"
sha256 = "9510435c7c2100a23514b823aaab26fc37e9efe6a7e8031c1a2e03ecb687192c"
[[part]]
file = "3DBenchy.stl"
scale = [1.5, 1.5, 1.5]
rotate = [0, 0, 45]
at = [60, 80]
[settings]
fill_density = "20%"
support_material = 1
support_material_auto = 1
support_material_style = "organic"
The filament and the process have tables like the printer's. The hash records which
version of the printer the print was set up with; if the printer in your library
changes, deli slice says so and deli printer <name> accepts the new version.
Before a first real print: deli send without --print only uploads, so you can
check the file arrived and start it from the printer's own screen.
Commands
deli setup [--printer NAME] [--host ADDRESS] [--shell bash|zsh|fish] [--no-completion] |
tab completion, your printer and its address, asked for once; the options answer the questions in advance |
deli printer|filament|process [name] |
choose one for this print, by its name or any words of it, from your library or else OrcaSlicer's (imported as it is chosen, under Orca's name or --name NAME; a printer brings its default process and filament), or list your library's; --default makes it the default for new prints instead |
deli status [--json] |
the print at a glance: printer, filament, process, parts, where it sends, settings changed, G-code and its file; and, looked up once a day, whether a newer deli is out (deli config update_check false stops that). --json gives the same as data |
deli nozzle [size] |
the nozzles of this print's printer, or put one in: its profile comes from Orca if need be, and the print moves to it |
deli vendor [vendor|printer] |
list printer vendors, a vendor's printers, or the printers a name is part of |
deli import orca <kind> "<name>" |
convert an OrcaSlicer preset into your library without choosing it |
deli load <kind> <source> [--name NAME] [--printer NAME] |
copy a PrusaSlicer INI file into your library, under its own name or --name; a filament or process under the printer it is for |
deli add <file|url> [--count N] [--file NAME] |
add a model, or more copies of it; a URL is fetched here first, --file choosing among several in an archive, on a page or in a Printables model |
deli remove <part> [--count N|--copy N] |
take a part out, or its last N copies, or one copy by its number |
deli set [setting] [value] / deli unset |
change, show or list this print's settings; several pairs at once, checked together and written only when every one passes; --global, --printer NAME, --filament NAME or --process NAME for every print's with that profile, in your config; @FILE reads a value, G-code say, from a file, @- from standard input |
deli supports [on|off|organic|snug|grid] |
automatic supports; --angle N, --buildplate-only or --everywhere |
deli scale [part] [x|y|z] <factor> |
110%, 1.1, or 30mm with an axis; the axis is the bed's, as the part lies once rotated |
deli rotate [part] [x|y|z] <degrees> |
about z when no axis is given |
deli mirror [part] [x|y|z|off] |
the part's mirror image along the bed's axis, as it lies once rotated; the same axis again, or off, puts it back |
deli move [part] [--copy N] <x> <y> |
where the part's middle goes on the bed, or one copy's; z -0.25 sinks it, plate 2 keeps it to plate 2, auto has it arranged again. deli translate is the same command |
deli arrange [--plate N] |
arrange every part and copy again, or one plate's, forgetting where they were moved |
deli pause [off] [layer ...] [--plate N] |
pause after a layer, counted as the slider in deli view counts them; also how to change filament mid-print |
deli slice [-o FILE|DIR] [--json] |
slice, and say how long it takes, how much filament, where it lies on the bed and how far from the edges; -o writes a copy of the G-code, --json gives the figures as data. Parts that do not fit go on further plates, a file each |
deli view [--port N] [--no-browser] [--stop] |
the parts on the bed in your browser; after deli slice, the sliced print with its supports, layer by layer. Served in the background until the page has been closed for ten minutes, or --stop; --no-browser prints the address instead of opening one |
deli send [FILE] [--print] [--level] [--plate N] [--name NAME] |
upload to the printer in your config, slicing first if the print has changed; every plate, or --plate N; --name for what to call it there; --level with --print has an Elegoo printer level its bed first. A printer that is printing is said to be, not sent to; exit code 3 when it cannot be reached, 4 when it is busy |
deli config [key] [value] [--unset KEY] |
your default printer, your printers' addresses and default filament and process, and the settings for every print and for each profile; --unset removes a key |
deli completion bash|zsh|fish |
shell completion |
deli update [version] [--check] |
install the latest release from GitHub over this one, or say whether there is one |
deli <command> --help has the details.
Using deli from an AI assistant
deli is a good fit for a coding assistant that runs shell commands: every command
takes its arguments on the command line, prints plain text and exits (deli status --json and deli slice --json give the same as data), and a print is a file the
assistant can read. The repository ships a skill, a short briefing in
skills/deli/SKILL.md, that tells an assistant how deli
thinks, the usual workflow, the rules it should keep (never deli send --print
unless asked; never deli setup, which asks questions) and where the settings are.
It follows the Agent Skills format, so it works with
Claude Code, Codex, OpenCode, Pi and the other tools that read SKILL.md files.
To install it for yours:
npx skills add dcruver/deli-slicer # into whichever agents you have
or copy skills/deli/ into the folder your tool reads skills from
(~/.claude/skills/, ~/.codex/skills/, ~/.config/opencode/skills/, ...).
Within this checkout, Claude Code finds it through .claude/skills/deli.
Not done yet
Things that a user would notice, roughly in the order they matter:
- Two printers have printed deli's G-code so far: an Elegoo Centauri Carbon and a
Voron 2.4 running Klipper, both with profiles converted from Orca's and the files sent
with
deli send --print(to the Centauri, and to Moonraker). On the Centauri, a cube in PLA printed well; a Benchy in PETG-CF stopped at itsdeli pause, parked the head, carried on when resumed and ran to the end, but came out stringy, from a spool that was probably damp. On the Voron, a Benchy in PLA and a two-part desiccant canister in PETG with a 0.8 mm nozzle printed cleanly (the canister's thread, designed for a 0.4, did not survive the nozzle, which is no slicer's fault). One print with organic supports, a phone stand on the Centauri, came out rough where the supports touched it and on overhangs left unsupported; converted profiles give overhangs no extra fan yet (PLAN.md).deli sendto OctoPrint has only been tested against a fake. If you print with another printer, please say how it went (see CONTRIBUTING.md). - Converted profiles differ from Orca in small ways. The first layer's layer-change
G-code is skipped; one bridge speed instead of two; no brim where Orca would add one
automatically.
PLAN.mdhas the full list with measurements. - What printers' screens show is barely checked. The G-code carries the
M73remaining-time lines and, for converted printers, the comment lines Orca's files end with (the profile'sgcode_footer), where some firmware reads the layer count. The Centauri Carbon shows the layer count; its remaining time has not been watched yet. - Other printers. Of the 1,001 printers OrcaSlicer 2.4.2 ships, 789 convert and slice a test cube; PRINTERS.md lists every one, and why the rest fail. Only the Centauri Carbon and the Bambu Lab P1S have been compared with Orca's own output.
- Bambu printers can't be sent to.
deli senddoes not speak Bambu's LAN or cloud protocols; write the G-code out withdeli slice -o .and copy it over by hand (SD card, or another program's send). - No Windows wheel. On Windows, deli runs in WSL (above); a
wheel of its own needs
deli view's background server ported first. - Settings apply to the whole print, not to one part.
- Supports are PrusaSlicer's automatic ones; painted supports need a 3MF painted elsewhere, which is untested.
- One filament per print. A change by hand at a
deli pauseis the only kind; filament-change G-code for multi-material printers is not converted. - No STEP files. PrusaSlicer reads them through a library deli does not ship.
- Only Printables among the model sites.
deli add <url>takes any address that serves a model file, a zip or a page linking to files, and Printables through its API. Thingiverse needs a browser, and MakerWorld, Thangs, Cults3D and MyMiniFactory an account; a site is added when it has a way in without one. - Hosts: PrusaLink, Duet and the others PrusaSlicer knows are not supported by
deli send; the Centauri Carbon 2's newer protocol is not either.
Engine
PrusaSlicer 2.9.6's source is vendored as a git submodule at vendor/PrusaSlicer.
deli links its libslic3r into a Python extension module; nothing of PrusaSlicer's
GUI is built. PLAN.md has the build details and the project's current state.
Contributing
DESIGN.md says how deli is meant to work and why; CONTRIBUTING.md says how to build it, test it and send a change, and what help is most wanted (printing with a printer that has not printed deli's G-code yet, above all). CHANGELOG.md lists what changed in each release.
License
AGPL-3.0-only, the same licence as the PrusaSlicer code it links. See LICENSE.
The profiles in profiles/ are derived from OrcaSlicer's, which are AGPL-3.0 too. The
libraries compiled into deli's wheels, and the three.js the viewer bundles, are listed
with their licences in THIRD-PARTY-NOTICES.md.
Metadata
Release files for deli-slicer 0.17.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| deli_slicer-0.17.0-cp312-abi3-manylinux_2_28_x86_64.whl | CPython 3.12 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| deli_slicer-0.17.0-cp312-abi3-manylinux_2_28_aarch64.whl | CPython 3.12 | abi3 | Linux glibc 2.28+ ARM64 | Details |
| deli_slicer-0.17.0-cp312-abi3-macosx_11_0_arm64.whl | CPython 3.12 | abi3 | macOS 11.0+ ARM64 | Details |
| deli_slicer-0.17.0-cp312-abi3-macosx_10_15_x86_64.whl | CPython 3.12 | abi3 | macOS 10.15+ x86-64 | Details |
Total release size: 84.3 MB
Release files / deli_slicer-0.17.0-cp312-abi3-manylinux_2_28_x86_64.whl
| Download URL | deli_slicer-0.17.0-cp312-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 25.2 MB |
| Tags | CPython 3.12 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
01303d190ccae47186bf6492099899061aa10fc23340761f0b14aebea603d7b0
|
|
BLAKE2b-256 checksum How to use checksums |
8213841eed53060f908f111bbc7267b6d86970370c0bde662861aa6fb4460451
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logRelease files / deli_slicer-0.17.0-cp312-abi3-manylinux_2_28_aarch64.whl
| Download URL | deli_slicer-0.17.0-cp312-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 23.5 MB |
| Tags | CPython 3.12 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
3bd4b90a00ebe13facd92f3c01df68025c024750d40c59dc95f0020818acf0ef
|
|
BLAKE2b-256 checksum How to use checksums |
f6a75059110ba2a6473f2a6925eb695a4f6b6d31ae8af18c19fd2539cc5d7dde
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logRelease files / deli_slicer-0.17.0-cp312-abi3-macosx_11_0_arm64.whl
| Download URL | deli_slicer-0.17.0-cp312-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 16.8 MB |
| Tags | CPython 3.12 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d849cdbbbae1b5e7fccf3bb42943cbe0e9c9744e3594f9f218a9586bb4b3aaa8
|
|
BLAKE2b-256 checksum How to use checksums |
4b7efd0aa1caf4a22688431fda770b9add1939cf6ca5355c29860e8e2669479f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logRelease files / deli_slicer-0.17.0-cp312-abi3-macosx_10_15_x86_64.whl
| Download URL | deli_slicer-0.17.0-cp312-abi3-macosx_10_15_x86_64.whl |
|---|---|
| Size | 18.9 MB |
| Tags | CPython 3.12 abi3 macOS 10.15+ x86-64 |
|
SHA-256 checksum How to use checksums |
ecdae671e7f88812352c0bf95e9475fc4e2080215e0612bf1fc0e7928239e6e8
|
|
BLAKE2b-256 checksum How to use checksums |
1f3cc52da6bb6109a44b76ecf610cc118dec59926aabe9cda025f0b9b4e0b118
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logSecurity for deli-slicer 0.17.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 4 files in this release have been uploaded with provenance metadata.
Attestation for deli_slicer-0.17.0-cp312-abi3-manylinux_2_28_x86_64.whl
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.