Migration scripts

November 14, 2023

You can add initialization and migration scripts inside your module that are executed and can prepare data before the module starts.

Module lifecycle

When a new module is installed and moves to the resolve state, the system first checks if there are any scripts located in META-INF/patches folder ending with .resolved.[ext], where [ext] means any file extension. These scripts execute before the initial import of the module content is performed.

You can also execute scripts on the first startup of the module by ending the filename with .started.[ext].

When a new version of the same module is installed and resolved, new scripts execute. Scripts executed by previous versions won't be executed again. In general, it's a good practice to keep all script unmodified in each new version. You should only add new scripts to the existing scripts.

Scripts are sorted by name, regardless of extension type, and execute one after another based on this order. To control the execution order, prefix the script with the module version number and an additional number if you will execute multiple scripts. 

Supported scripts

All patches formats supported by Jahia can be used here. 

Groovy scripts

A Groovy script can execute any code exposed by the Jahia core. 

GraphQL scripts

GraphQL scripts are useful for modifying JCR content or executing admin operations. The file extension is .graphql  and must contain one single mutation with as many fields as you need.

mutation {
    jcr {
        addPermission: mutateNodesByQuery(query: "/jcr:root/permissions[not(developerTools/@jcr:primaryType='jnt:permission')]", queryLanguage: XPATH) {
            addChild(name: "developerTools", primaryNodeType: "jnt:permission") {
                addChild(name: "developerToolsAccess", primaryNodeType: "jnt:permission") {
        updateWebDesignerRole: mutateNodesByQuery(query: "select * from [jnt:role] where localname()='web-designer'", queryLanguage: SQL2) {
            mutateProperty(name: "j:permissionNames") {
                addValue(value: "developerToolsAccess")

SQL scripts

Use SQL scripts if the module initializes a schema in the database. These SQL files are specific to each database and you must create one file per database type. Add the SQL files in a subfolder named as the corresponding database type. For example, a module can provide the following scripts.



Provisioning scripts

Starting from Jahia, you can use provisioning scripts with the .yaml extension. With these scripts, you can modify the state of existing bundles, install new one, or create OSGi configurations.