dev-doc/New_Module_Guide.md
This guide walks you through the process of creating a new Image Operation (IOP) module in darktable.
Create a new C file in src/iop/. Use the template useless.c as a reference.
Example: src/iop/mymodule.c
For a full API reference, see IOP_Module_API.md.
src/iop/CMakeLists.txtAdd your module file to the list:
add_iop(mymodule "mymodule.c")
src/common/iop_order.cAdd your module to all relevant pipeline order lists (e.g., legacy_order, v30_order, v50_order, v30_jpg_order, v50_jpg_order).
You must decide where your processing should happen (before or after which other operations).
// Example: placing it after exposure
{ { 12.0f }, "exposure", 0 },
{ { 13.0f }, "mymodule", 0 },
You must also inject your module into dt_ioppr_get_iop_order_list(), which runs dynamically when upgrading or falling back. Find the _insert_before section and add your module:
_insert_before(iop_order_list, "module_it_should_run_before", "mymodule");
Troubleshooting "missing iop_order for module" Fatal Error:
If darktable crashes on startup with [dt_init] ERROR: iop order looks bad, aborting. and logs missing iop_order for module mymodule, it means your module was registered in CMakeLists.txt but the iop string name does not perfectly match its placement in iop_order.c. Make sure:
"mymodule") in every iop_order table array._insert_before() rule in dt_ioppr_get_iop_order_list().mymodule.c)dt_iop_mymodule_params_t
DT_MODULE_INTROSPECTION macro. See introspection.md for metadata tags and versioning.dt_iop_mymodule_gui_data_t (if needing GUI).name(): unique internal name.default_colorspace(): usually IOP_CS_RGB or IOP_CS_LAB.process(): The core logic.See IOP_Module_API.md — Required Functions for details.
description(): Tooltip description.flags(): IOP_FLAGS_SUPPORTS_BLENDING, etc.default_group(): Which tab it belongs to (Technical, Grading, etc.). See Module_Groups.md.gui_init(): Create widgets.gui_update(): Sync widgets from params.commit_params(): If you need to precalculate data for processing.See IOP_Module_API.md — Optional Functions for the full list.
In gui_init():
dt_bauhaus_slider_from_params(self, "param_name") to create sliders linked to your params.For the full GUI architecture (layout API, event flow, thread safety, widget reparenting), see GUI.md.
Ensure your module is in the correct place in iop_order.c.
Note: Pipeline ordering affects commit_params() execution order. Modules that share state (e.g., via dev->chroma) depend on earlier modules having committed first. See pixelpipe_architecture.md for details.
By using dt_bauhaus widgets, shortcuts are automatically supported.
Implement default_group() to place your module in the right tab.
IOP_GROUP_TECHNICAL: Technical corrections.IOP_GROUP_GRADING: Color/Tone grading.IOP_GROUP_EFFECTS: Aesthetic effects.To allow your widgets to be used in the QAP:
dt_bauhaus widgets../build.sh./build/bin/darktable -d pipe