plugin.toml reference
Every DNA plugin carries a plugin.toml file that tells DNA what kind of plugin it is, how to load it, and what it's allowed to touch.
plugin.toml lives at the root of a plugin folder inside ~/.dna/plugins/. It's a small, human-readable text file. DNA reads it when it starts up (or when you install a plugin) and uses it to register the plugin's nodes. If anything in the file is wrong, DNA refuses to load the plugin and tells you why — a typo fails loudly rather than silently doing nothing.
The [plugin] section
Every manifest starts with a [plugin] block describing the plugin itself.
[plugin]
name = "Fast Noise"
version = "0.1.0"
api_version = "1.0.0"
name — the display name shown in DNA.
version — your plugin's own version, your choice.
api_version — which DNA plugin API the plugin was built against. DNA checks this against the version it ships with and refuses plugins that aren't compatible, so you don't get mysterious crashes from a mismatched build.
Right after [plugin] you declare exactly one plugin type. A manifest must choose precisely one — no more, no fewer — or it won't load.
Choosing a plugin type
There are four kinds of plugin, each a small sub-section under [plugin].
Shader — adds image-effect nodes written in shader code. This is the lightest and safest type, and the one most authors reach for first.
[plugin.shader]
The section is just a marker — it has no fields. The actual shaders are listed separately in [[shader]] blocks (see below).
Python — runs a Python script. Point entry at the script file.
[plugin.python]
entry = "main.py"
Rust — loads a compiled Rust library. Give the library's base name; DNA adds the right file extension for your operating system.
[plugin.rust]
library = "libfast_noise"
Native — loads a compiled C-compatible library, same idea as Rust.
[plugin.native]
library = "libfast_noise"
Writing shader and node plugins is covered in Authoring a shader plugin and Authoring a node plugin. This page is just the manifest reference.
[[shader]] entries
A shader plugin lists one or more nodes, each in its own [[shader]] block (the double brackets mean "one of a list"). You need at least one.
[[shader]]
id = "custom.chromatic_aberration"
display_name = "Chromatic Aberration"
description = "Splits colour channels for a lens-fringe look"
category = "Stylize"
keywords = "lens, fringe, glitch"
file = "chromatic.wgsl"
language = "WGSL"
shader_type = "Fragment"
inputs = ["content"]
id (required) — the node's unique identifier, like
custom.chromatic_aberration. No two shaders in the plugin may share one.display_name (required) — the name shown on the node and in search.
description — a short line explaining what it does.
category — which group it appears under in the node search/palette.
keywords — extra search terms, comma-separated.
file (required) — the path to your shader source, relative to the plugin folder. It must end in
.wgslor.glsl, and can't point outside the plugin folder (no..or absolute paths — DNA rejects those for safety).language —
WGSL(the default) orGLSL.shader_type —
Fragment(the default, an image effect) orCompute.inputs — the named image inputs the node accepts. Defaults to a single input called
content. You can name up to four.
The [capabilities] section
By default a plugin's nodes run in a sandbox and can only touch the safe, everyday parts of DNA. If your plugin needs to do something more powerful, you declare it here. Anything you don't list, you don't get.
[capabilities]
gpu = true
state = true
filesystem = true
network = true
plugin_host = true
gpu — use the graphics card directly for heavy compute.
state — remember data between cooks (per-node memory).
filesystem — read files from disk.
network — open network connections.
plugin_host — load other plugins.
Every flag defaults to off, and a misspelled flag name makes the manifest fail to load rather than silently granting nothing — so you always know exactly what you asked for.
Capabilities are gated by the project's trust level. In a Restricted project, a plugin that requests any capability is refused outright — DNA won't even load it until you trust the project. Trusting a project is a deliberate choice you make; see Trust & Permissions and Capabilities & trust.
Declare only the capabilities you actually use. A plugin that asks for nothing loads everywhere with no trust prompt, which makes it far easier for other artists to drop into their projects.
A complete example
A small shader plugin, start to finish:
[plugin]
name = "Fast Noise"
version = "0.1.0"
api_version = "1.0.0"
[plugin.shader]
[[shader]]
id = "custom.fast_noise"
display_name = "Fast Noise"
description = "Animated value noise"
category = "Generate"
file = "noise.wgsl"
inputs = ["content"]
No [capabilities] section means no special permissions — so this one loads in any project without a trust prompt.