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"

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"]

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

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.

See also