Patch packages deliver small updates or fixes to existing packages without requiring a full package reinstall. They typically address minor issues such as:

  • Bug fixes: Correcting package defects without introducing new features.
  • Security patches: Fixing vulnerabilities to prevent exploits or attacks.
  • Performance improvements: Optimizing existing functionality for better efficiency.
  • Hotfixes: Urgent updates to resolve critical issues affecting users.
  • Minor enhancements: Small usability improvements or tweaks.

Patch packages allow for incremental updates to be applied efficiently.

The example packages used in the tutorial are the following:

Base Package ExampleDownload the full example Recipe Manager application package here: Recipe Manager (Tutorial App).json
Patch Package ExampleDownload the patch package example here: Recipe Manager (Example Patch).json

Patch package structure

The overall structure remains similar to a standard JSON package. However, a patch package requires additional properties that identify it as a patch package.

First, let’s take a look at a blank template for a patch package:

"package": {
    "key": "",
    "name": "",
    "type": "patch",
    "basePackageKey": "basePackageKey",
    "dependsOn": [
        {
            "packageKey": "basePackageKey"
        }
    ],
    "runAfter": {
        "packageKey": "basePackageKey"
    },
    "assets":
    {
        "...": [
            {
                "key": "",
                "action": "",
                ...
            }
        ]
    }
}

The following properties define what kind of package it is and which package it modifies:

PropertyPurpose
keyUnique key of the patch package.
nameName of the patch package, used mainly under the Resources > Packages section.
typePackage type, specifies the package to be a patch.
basePackageKeyKey of the package that this patch modifies.
dependsOnKey of the packages that the patch package depends on. This field is used in the case of multiple dependencies or to specify the base package version.
runAfterArray of keys of packages that must be installed first. Patch packages must run after the base package, otherwise the installation fails.

To specify which assets or components will be modified, you must define both the key of the asset/component and the action to be performed.

PropertyPurpose
keyIdentifies the asset or component the change applies to.
actionSpecifies how the asset or component changes using the action type. What it modifies is determined by the property’s position in the package.

Supported action values

Each value requires different mandatory properties on the asset or component.

ValueDescription
addAll mandatory properties have to be specified.
deleteOnly the key property of the modified asset or component is mandatory.
updateThe key property of the modified asset or component is mandatory, along with the properties that need updating.

Addressing modes

Every asset in a patch is written in one of two shapes, and the presence or absence of action selects between them. The two shapes look almost identical and behave very differently, so this is the rule to learn first.

ModeSelected byDescription
Action modeaction is present (add, update, delete)Applies that action to the asset. On update, every property you mention replaces the base value wholesale. A listed collection replaces the base collection rather than merging into it.
Reference modeaction is omittedDoes not change the asset itself. It navigates into the asset so the children you list can carry their own actions.

Use reference mode whenever you want to change part of an existing asset and leave the rest alone. Use action mode only when you mean to add a whole asset, delete a whole asset, or overwrite the properties you list.

Recursion rule

action on a node switches that node’s children to the plain, non-patch shape at every level below it. A child of an action-mode node can’t carry its own action. There is nothing for the property to bind to, so it’s ignored and the child is treated as literal content.

This is what makes the following patch destructive rather than additive:

"objectTypes": [
    {
        "action": "update",
        "key": "business_term",
        "attributeTypes": [
            { "action": "add", "key": "alternative_name" }
        ]
    }
]

The author means “add one attribute type”. What happens is that attributeTypes is overwritten with a one-element list, so every attribute type the base package registered on business_term is dropped. The nested "action": "add" never runs.

Written in reference mode, it does what the author intended:

"objectTypes": [
    {
        "key": "business_term",
        "attributeTypes": [
            { "action": "add", "key": "alternative_name" }
        ]
    }
]

From 2026.3, package validation reports both mistakes. A nested action that won’t run is an error. An update that removes entries the base package registered is also an error, naming each removed key.

When a patch target does not exist

An update or delete whose target isn’t present in the base package can’t carry out your intent at all. From 2026.3 that is a validation error rather than a warning. An add whose container is missing stays a warning.

An operation can be genuinely conditional: the patch targets several base versions, and only some of them have the asset. Mark that single operation with ifPresent:

{
    "action": "update",
    "ifPresent": true,
    "key": "optional_attribute",
    "name": "New name"
}

ifPresent applies only to the operation it’s written on. Use it deliberately: it turns off the check that tells you a patch silently did nothing.

Action property’s position

The placement of the action property determines what will be modified.

Assets level

Dawiso’s JSON editor offers an optional action property on all assets, which you can use to add, delete, or modify them. You can, for example, create new attribute types, add new translations, or delete existing object types.

Example: Adding a new attribute type.

This example adds a new attribute type that stores the calorie count. The value is a number, sorted as an integer rather than a string. For more information, refer to the full list of attribute type features.

Click here to show the example.
"assets": {
   "attributeTypes": [
       {
           "action": "add",
           "key": "calories_count",
           "name": "Calories Count",
           "features": [
               {
                   "key": "is_number"
               },
               {
                   "key": "sort_by_number"
               }
           ]
       }
   ]
},

Property level

Hidden action, also called a referent, can also be applied at the property level for a more granular patch. You can, for example, assign object types to an application, delete components from an object type template, or update attribute names.

Example 1: Assigning a newly created attribute to an object type.

Click here to show the example.
"objectTypes": [
   {
       "key": "recipe",
       "attributeTypes": [
           {
               "action": "add",
               "key": "calories_count"
           }
       ]
   }
]

Example 2: Adding a new component to an object type template.

Click here to show the example.
"objectTypes": [
    {
        "key": "recipe",
        "templates": {
            "main": {
                "rightArea": [
                    {
                        "action": "add",
                        "addToEnd": true,
                        "type": "panel",
                        "title": "title.panel.calories",
                        "values": [
                            {
                                "type": "attributes",
                                "values": [
                                    "calories_count"
                                ]
                            }
                        ]
                    }
                ]
            }
        }
    }
],

Patch package structure exceptions

Patching components

Before applying a patch, ensure that all components used in the base package are defined in the components asset with:

  • A unique key, so they can be modified.
  • A component ID, which determines where new components will be added:
    • addBeforeComponentId, addAfterComponentId: Use the properties to determine the component’s precise position in the template.
    • If you don’t have component IDs defined, you can use these properties to add the component to the beginning or end of a template:
      • addToStart
      • addToEnd

All four positioning properties are recognised only on a component that carries "action": "add". On a component in reference mode there is nothing for them to bind to. Since 2026.3 that is reported as a validation error rather than silently ignored. The version stays out of the validated state until you either add "action": "add" together with the component’s type, or remove the positioning property.

A component that declares action: "add" or action: "update" must also declare its type. Without it the component can’t be resolved and the whole entry is dropped from the patched template. From 2026.3 this is a validation error rather than a silent drop.

Component IDs must be unique within the base package. Components are addressed by path, so if two of them share one path, a patch targeting that path hits an arbitrary one. That is why a duplicate on a path the patch addresses is reported as an error.

When patching components, the entire component must be patched. The only exception is when modifying a component inside a panel, splitter, etc. (in other words, visual components).

Patching arrays of strings

This applies to reference mode only. To change individual elements of a string array in the base package, the patch represents that array as an array of objects so each element can specify its own action. The element’s value goes in a value property, not key.

Under "action": "update" the same property stays a plain array of strings and the object syntax is rejected. An update replaces the whole array anyway, so a per-element action would have nothing to mean.

Example: Adding a new object type.

In the base package, object types are listed in an array of strings in the applications asset:

Click here to show the example.
"applications": [
    {
        "key": "app",
        ...
        "objectTypeKeys": [
            "cuisine",
            "recipe",
            "ingredient_category",
            "ingredient"
        ],
        ...
    },
    ...
],

In the patch package, specify the object type key in a value property for each element you want to add, as well as the action in an array of objects.

"applications": [
    {
        "key": "app",
        "objectTypeKeys": [
            {
                "action": "add",
                "value": "new_objectType"
            }
        ]
    }
]

Preview the applied patch

Each patch package version has a detail page. Select the:

  • Applied Preview tab for the resolved package definition as JSON.
  • Applied Preview Graph tab for the same resolution as an interactive diagram of the patch chain.

For details on reading the chain graph, see Patch Packages — Advanced Guide.