Skip to content

Dynamic pack API

A dynamic pack is a .sshowdynamic file that holds the declarations and shaders of several dynamics in one dynamic.json. The editor builds the fields of the Dynamic panel from the declarations, and draws paints and effects with the shaders.

ReferenceAdvancedAbout 10 minWebDesktop

The pack file

A dynamic pack is one .sshowdynamic file. It’s a zip file with a new name, with the manifest dynamic.json at the top level. An icon is optional.

Shaders aren’t separate files: they go in dynamic.json as text. The editor takes only dynamic.json and the icon from the package. Don’t zip the folder itself; select the files inside it and zip those.

One pack holds up to 32 dynamics. Each one is either a paint or an effect: paints show in a Fill or Stroke, and effects in Effects. The Basic, Retro, and Backgrounds packs use the same format. For how they look to the people who use them, see Dynamics.

Manifest (dynamic.json)

Its fields are almost the same as a plugin’s manifest. Instead of main, it has dynamics, which holds the dynamics. Unknown fields are ignored.

dynamic.json fields and rules
FieldRequiredRule
idRequiredLowercase reverse-domain format (com.example.waves). The rules are the same as a plugin’s, and plugins and dynamic packs share one set of ids. Up to 100 characters when publishing. Ids starting with app.sshow. are SSHOW’s.
nameRequiredThe pack name shown on the Extensions screen in Studio. In the picker of dynamics, it’s the title of the pack’s group. Up to 100 characters when publishing.
name_localizedOptionalThe name in another language, written as { "ko": "…" } for Korean. The editor and Studio show it when they’re in that language.
versionRequiredThree numbers joined by periods, x.y.z (1.0.0).
apiRequiredThe dynamic pack API version. It’s 1 now.
dynamicsRequiredThe array of dynamics, 1 to 32 of them. Dynamic fields
descriptionOptionalThe description shown on the Extensions screen and in the detail dialog. Up to 2000 characters when publishing.
description_localizedOptionalThe description in another language, written the same way as name_localized.
authorOptionalThe author. In the published list, the author is the submitting account, not this value.
iconOptionalThe name of the icon file in the package: png, svg, jpg, jpeg, or webp. Without one, the Extensions screen shows a wind icon.

Dynamic fields

What one entry of the dynamics array holds
FieldRequiredRule
nameRequiredThe name that points to the dynamic inside the pack, and the one documents remember it by. Lower camel case starting with a lowercase letter (meshGradient), up to 32 characters, unique in the pack.
labelRequiredThe name shown in the picker and in the Dynamic panel. Up to 48 characters.
label_localizedOptionalThe label in another language, written the same way as name_localized.
slotRequired“paint” is a pattern painted in a Fill or Stroke. “effect” changes an object’s pixels and shows in Effects.
animatedOptionaltrue if it moves over time. It’s false when left out, and then it doesn’t get uTime.
paramsRequiredThe array of parameters, up to 24. With none, use an empty array. Parameters
glslRequiredGLSL text that holds one function. Shaders
paddingOptionalOnly for an effect. How far the effect spreads outside the object, in px, written like { "plus": 4, "scale": { "size": 2 } }. plus is always added, and scale multiplies a number parameter’s value. It can reach up to 256 px with every parameter at its max.

Shaders

Write only one function in glsl. The editor adds the uniform declarations and the main function, so don’t write main, #version, #extension, or #include. These three are refused even inside a comment.

The vec4 you return is a color with premultiplied alpha. The src an effect gets is the same, so when you change a color, divide by alpha first and multiply again after.

A paint is drawn as a picture of up to 1024 px on each side, then stretched to the object’s size. On a large object, thin lines and small dots get thicker by as much.

Shaders compile on the device’s GPU when the pack goes in. If any one dynamic doesn’t compile, the whole pack stays out.

The functions a shader writes and the values the editor passes
NameMeaning
vec4 dynamicPaint(vec2 uv)The function for slot “paint”. uv is the position inside the painted box, from 0 to 1 both across and down.
vec4 dynamicEffect(vec2 uv, vec4 src)The function for slot “effect”. src is the original pixel at that position. Read pixels at other positions with texture(uTexture, uv).
uTimeTime in seconds, passed only when animated is true.
uInputSizeThe size of the input picture. xy is the width and height in px, and zw is their inverse, for moving by one pixel.
uOutputFrameThe area being drawn. zw is the width and height in px, and a paint’s position in px is uv * uOutputFrame.zw.
uTextureEffects only. The picture of the object.
uViewportScaleEffects only. The current zoom. Multiply values set in document px (such as a dot size) by it to get screen px.
u + parameter keyEach parameter is one uniform: capitalize the key’s first letter and put u in front (size → uSize). Numbers and booleans are float (off 0, on 1), and colors are vec3.

Parameters

Parameters show as fields under Parameters in the Dynamic panel. Values people change are saved in the document and reach the shader as uniforms.

The editor gives every paint and effect its own opacity, so don’t make opacity a parameter.

What one parameter holds
FieldRule
keyLower camel case starting with a lowercase letter, up to 32 characters, unique in the dynamic. time, texture, opacity, viewportScale, inputSize, inputPixel, inputClamp, outputFrame, globalFrame, and outputTexture are names the editor uses, so they can’t be keys.
label · label_localizedThe field’s name. Up to 48 characters.
typeOne of number, color, and boolean.
defaultFor a number, a value between min and max; for a color, #rrggbb; for a boolean, true or false.
min · max · stepRequired for a number. step must be greater than 0. Saved values are held to this range before they reach the shader.
unitA unit for a number, up to 8 characters. For an angle, use °.

Try it

There are two ways to check a pack in the editor after you change it. You can drop the file anywhere, and the Windows desktop app can also watch a folder.

Drop the file

Web · Desktop

Drag the .sshowdynamic file onto the editor canvas. Nothing announces it: choose Dynamic in a Fill, Stroke, or Effects, and its dynamics show under the pack’s name. If a pack with the same id is already there, the new file replaces it. A dropped pack lives only in the editor you have open now, so it’s gone when you reload.

Drop the fileDropping waves.sshowdynamic on the canvas shows no message, but clicking Dynamic from the + button of Fills shows the new Waves pack at the end of the picker, and picking its Ripple card spreads ripples over the rectangle. Video: Dragging waves.sshowdynamic in from the right and dropping it on the canvas only turns off the dashed outline, with no message. Choosing Dynamic from the + button next to the rectangle’s Fills shows a new Waves pack group below Basic and Backgrounds in the picker, and picking its Ripple card spreads ripples over the rectangle.

Watch a folder

Desktop app (Windows)

Open settings.json the same way as for a plugin’s folder watching. Set "dynamics.devPath" to the absolute path of the folder that holds dynamic.json, save, and restart the app. Add the key if it isn’t there. From then on, each time you save a file in the folder, the pack goes into every open editor again. It can be on together with "plugins.devPath".

A refused pack stays out without a word

If a declaration breaks a rule or a shader doesn’t compile, the pack stays out with no message. If the pack doesn’t show in the picker, choose the file in the developer console. It points out what breaks the rules, and sends nothing until you click “Send for review”. The console can’t check whether shaders compile, so undo your changes bit by bit to find the cause.

Publish

A published pack goes into Dynamics on the Extensions screen in Studio, where anyone can install it. Publishing works the same way and follows the same rules as publishing a plugin, and a person reviews every version.

  1. Choose the package

    Open the developer console and click “Choose a file” in the “Send for review” panel. When you choose the .sshowdynamic file, the console reads it at once and shows its name and version. If it breaks a rule, it says what to fix.

  2. Send it for review

    Check the consent box and click “Send for review”. The pack appears in the “Your extensions” list, marked “Dynamic pack”, as “In review”.

  3. Check the result

    A reviewer tries the pack in the editor, and for a new version compares its pictures side by side with the published version’s. The result comes by notification and email. An approved version is published right away.

Rules for new versions

What a new version of a published pack may and may not change
ChangeWhat happens
Remove a dynamicRefused, because documents that use it would break.
Change a dynamic’s slotRefused.
Remove a parameter, or change its typeRefused.
Narrow a number parameter’s rangeRefused, because saved values would be cut. Only lower min and raise max.
Add a dynamic or a parameterAllowed.
Change a default, a label, or a shaderAllowed. Documents that already use it change their look too, though, so add a dynamic whose look changes under a new name.

When something goes wrong

  • Why doesn’t a pack I dropped show in the picker?

    It was refused because it breaks a rule or a shader doesn’t compile. Choose the file in the developer console, and it points out what breaks the rules. Effects are in Effects, not in a Fill.
  • Why does a pack I fixed and dropped again stay the same?

    When a pack with the same id is already there, the new file replaces it only if it keeps the rules for new versions. If you removed or changed a dynamic or a parameter, reload the editor and drop the file again.
  • Why do I get “The package doesn’t meet the rules. Fix this and try again:”?

    The reason follows it, in English, starting with the name of the manifest field or dynamic entry. Fix that field and choose the file again. For a new version, also check the rules for new versions.
  • Why can’t others see a paint?

    A dropped pack is only in your editor. Use it in a cloud project, and the Dynamic panel shows “This pack isn’t published, so others won’t see this dynamic”. Publish the pack, and others get it too. To show it before publishing, share a .sshow file from Save a Copy in the editor’s Menu: the pack goes inside the file, so it draws as is. A file from Download .sshow on a Studio card doesn’t carry the pack.
  • Where do I see shader errors?

    The editor doesn’t show shader errors. First check that a very small function goes in, then grow it a little at a time, dropping the file each time.
Was this page helpful?

Updated 10/30/2026 · The videos on this page were recorded in the current editor.

Popular