Summary
Several behaviours that affect anyone writing personal Lua startup scripts under Darktable 5.6.0 (Flatpak, Linux) are undocumented or incorrect in the current README. Discovered through hands-on debugging. Submitting as a doc issue in case it is useful to others or to the maintainers for a README update.
1. Lua version is 5.4, not the host system version
Darktable 5.x bundles its own interpreter. The system lua -v (often 5.1 or 5.3) is irrelevant. Confirmed for 5.6.0 Flatpak:
flatpak run --command=find org.darktable.Darktable /app -name "liblua*.so.*"
# → /app/lib/liblua.so.5.4.6
goto, <const>, bitwise operators all work inside Darktable scripts.
2. require "myscript" in the user luarc silently fails under Flatpak
The README's "Enabling" section says to add require "myscript" to the user luarc. This works for native installs but silently does nothing under Flatpak.
Why: Darktable Flatpak ships a system luarc (/app/share/darktable/luarc) that loads tools/script_manager. Because script_manager detects it is running from the system data directory (system_based = true), the user's ~/.var/.../config/darktable/luarc is loaded via loadfile() rather than require(), and at that point the Lua package.path does not include the user lua/ directory. Any require "myscript" in the user luarc silently fails — no error, no load.
3. The correct approach: personal/ subfolder + darktablerc entry
script_manager scans USER_LUA_DIR but only processes scripts that are inside a named subfolder (the pattern requires at least one /). A .lua file placed directly in lua/ is silently ignored.
Working approach:
mkdir -p ~/.var/app/org.darktable.Darktable/config/darktable/lua/personal
cp myscript.lua ~/.var/app/org.darktable.Darktable/config/darktable/lua/personal/
Then add one line to darktablerc:
lua/script_manager/personal/myscript=TRUE
Key format: lua/script_manager/<folder>/<script-name-without-.lua>.
The script can also be enabled through the Darktable UI (Lua Scripts panel → personal folder → toggle), which writes the darktablerc entry automatically.
4. dt.films.new(path) creates empty film rolls — use dt.database.import(path) instead
dt.films.new(path) creates the film_roll database entry but does not scan for images. The resulting roll is empty. Darktable prunes empty film rolls on exit, so the call appears to succeed (no Lua error) but nothing persists after the session.
dt.database.import(path) is the correct call when the intent is to import images:
-- When given a directory path, returns a table of imported image objects
local ok, result = pcall(dt.database.import, path)
if ok then
local n = type(result) == "table" and #result or (result ~= nil and 1 or 0)
-- n images imported, film roll created with content
end
5. Minimal working template for a personal startup script
-- lua/personal/myscript.lua
-- Loaded by script_manager; runs when lighttable becomes active.
local dt = require "darktable"
local function run()
-- dt.films, dt.database.import, etc. are all ready here
end
dt.register_event("myscript", "view-changed",
function(event, old_view, new_view)
if new_view.id == "lighttable" and
(old_view == nil or old_view.id == "none") then
pcall(run)
end
end
)
6. Debugging gotcha: Snap/Flatpak LD_LIBRARY_PATH crash
On systems with Snap installed, running flatpak run org.darktable.Darktable -d lua from a terminal may crash immediately:
symbol lookup error: /snap/core20/current/lib/x86_64-linux-gnu/libpthread.so.0:
undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE
Workaround:
env -u LD_LIBRARY_PATH flatpak run org.darktable.Darktable -d lua 2>&1 | grep lua
Suggested README additions
- Note under the Flatpak section that
require "myscript" only works for scripts inside the cloned lua-scripts repository; personal scripts need the personal/ subfolder + darktablerc approach.
- A brief "Personal Scripts" subsection covering the above.
- A note in the API docs (or script_manager docs) that
dt.films.new() does not import images and dt.database.import() should be used instead.
Happy to help draft specific text if useful.
Summary
Several behaviours that affect anyone writing personal Lua startup scripts under Darktable 5.6.0 (Flatpak, Linux) are undocumented or incorrect in the current README. Discovered through hands-on debugging. Submitting as a doc issue in case it is useful to others or to the maintainers for a README update.
1. Lua version is 5.4, not the host system version
Darktable 5.x bundles its own interpreter. The system
lua -v(often 5.1 or 5.3) is irrelevant. Confirmed for 5.6.0 Flatpak:goto,<const>, bitwise operators all work inside Darktable scripts.2.
require "myscript"in the user luarc silently fails under FlatpakThe README's "Enabling" section says to add
require "myscript"to the user luarc. This works for native installs but silently does nothing under Flatpak.Why: Darktable Flatpak ships a system luarc (
/app/share/darktable/luarc) that loadstools/script_manager. Because script_manager detects it is running from the system data directory (system_based = true), the user's~/.var/.../config/darktable/luarcis loaded vialoadfile()rather thanrequire(), and at that point the Luapackage.pathdoes not include the userlua/directory. Anyrequire "myscript"in the user luarc silently fails — no error, no load.3. The correct approach:
personal/subfolder + darktablerc entryscript_manager scans
USER_LUA_DIRbut only processes scripts that are inside a named subfolder (the pattern requires at least one/). A.luafile placed directly inlua/is silently ignored.Working approach:
Then add one line to
darktablerc:Key format:
lua/script_manager/<folder>/<script-name-without-.lua>.The script can also be enabled through the Darktable UI (Lua Scripts panel → personal folder → toggle), which writes the darktablerc entry automatically.
4.
dt.films.new(path)creates empty film rolls — usedt.database.import(path)insteaddt.films.new(path)creates the film_roll database entry but does not scan for images. The resulting roll is empty. Darktable prunes empty film rolls on exit, so the call appears to succeed (no Lua error) but nothing persists after the session.dt.database.import(path)is the correct call when the intent is to import images:5. Minimal working template for a personal startup script
6. Debugging gotcha: Snap/Flatpak
LD_LIBRARY_PATHcrashOn systems with Snap installed, running
flatpak run org.darktable.Darktable -d luafrom a terminal may crash immediately:Workaround:
Suggested README additions
require "myscript"only works for scripts inside the cloned lua-scripts repository; personal scripts need thepersonal/subfolder + darktablerc approach.dt.films.new()does not import images anddt.database.import()should be used instead.Happy to help draft specific text if useful.