Skip to content


Liquigraph provides a CLI. It is a good fit for users working on non-JVM applications or with a standalone Neo4j deployment directly.


Make sure a JRE is set up on the machine running the CLI.

For Neo4j 3.x, the minimal JRE version is 8.

For Neo4j 4.x, the minimal JRE version is 11.

CLI download

Please refer to the download section to download the CLI first.

The rest of the tutorial assumes a Unix OS and will therefore show examples with


  • Homebrew (Mac OS) users need to replace with liquigraph.
  • Windows users need to replace with liquigraph-cli.bat.

Let's now make sure the CLI runs without any issue:

./ --help
Usage: liquigraph [options]
  * --changelog, -c
      Master Liquigraph changelog location.
     Prefix with 'classpath:' if
      location is in classpath
// [...] omitted for brevity
    --help, -h
      Get this help
    --password, -p
      Graph DB password (remote only)
    --username, -u
      Graph DB username (remote only)
    --version, -v
      Show the version

Basic concepts

Liquigraph requires a single entry point, also known as a change log file. This file can include other change log files and/or define change sets.

Every change set is executed in a separate transaction. They define at least 1 Cypher query. These Cypher queries define the data (or indices/constraints) that will be created, modified or deleted from the target database.


Neo4j disallows mixing index/constraint with regular "data" operations within the same transaction. Such a transaction will always fail. As a consequence, index/constraint operations must be defined in separate Liquigraph change sets.

Change sets are uniquely identified by their ID and author name. By default, they also are:

  • incremental: they are allowed to run only once.
  • immutable: their queries are not allowed to change.

Learn how to change these defaults, and more, in the reference documentation.

First migrations

Change log creation

Save the following change log file:

<?xml version="1.0" encoding="UTF-8"?>
<changelog xmlns:xsi=""
    <changeset id="sentence-initialization" author="florent-biville">
        <query>CREATE (n:Sentence {text:"Hello monde!"}) RETURN n</query>
    <changeset id="sentence-correction" author="florent-biville">
        <query>MATCH (n:Sentence {text:"Hello monde!"}) SET n.text="Hello world!" RETURN n</query>

The change log defines two change sets, which are executed in order, in separate transactions:

  1. The first change set defines a single query, which creates a node, with a Sentence label and a simple textual property called text.
  2. The second change set defines a single Cypher query as well, which finds the node pattern and updates the text property accordingly.

If the Cypher syntax looks unfamiliar, feel free to follow this official tutorial.


The location of this file will be called CHANGELOG_FILE throughout the rest of the tutorial.


Contrary to Liquibase, Liquigraph only supports XML for defining change logs.

Connection URI

To keep things simple, we will assume a standalone Neo4j server is running on your machine, via Neo4j Desktop or Docker for instance.

The connection URI will be jdbc:neo4j:bolt://localhost, username neo4j and the password changeme.

Depending on Neo4j versions, Neo4j server typology and Liquigraph client, connection URI can vary greatly. The configuration is covered in much greater details in the reference documentation.

Dry run

It is a good practice to first execute a dry run.

A dry run does not alter your database. The database needs to be online, so that Liquigraph can properly detect which change sets are to be selected (based on whether they already ran, whether they match the execution context ...).

It helps you make sure that:

  • your connection settings are correct
  • the selected change sets are the ones you expect

Besides the connection and change log settings, a temporary directory needs to be specified via the option --dry-run-output-directory (short version: -d). In dry-run mode, Liquigraph generates a Cypher file into this directory. The Cypher file contains the queries of the change set that would be executed against the configured Neo4j database.

./ --username neo4j \
                --password changeme \
                --graph-db-uri jdbc:neo4j:bolt://localhost \
                --changelog CHANGELOG_FILE \
                --dry-run-output-directory /path/to/directory


  • You can leave the password value out, and a secure prompt will appear.
  • You can also read the password from a file with ./ [...] --password < password.txt.

This should result in a successful execution with a file named output.cypher in /path/to/directory:

less /path/to/directory/output.cypher
//Liquigraph changeset[author: florent-biville, id: sentence-initialization]
//Liquigraph changeset[executionContexts: none declared]
CREATE (n:Sentence {text:"Hello monde!"}) RETURN n
//Liquigraph changeset[author: florent-biville, id: sentence-correction]
//Liquigraph changeset[executionContexts: none declared]
MATCH (n:Sentence {text:"Hello monde!"}) SET n.text="Hello world!" RETURN n


  • Contrary to Liquibase, Liquigraph only includes the queries of the matching change sets. Cypher queries executed for Liquigraph internal purposes are not included.
  • Printing to the standard output is also currently unsupported.


Once the dry run is successful, you can finally execute the migrations. The CLI invocation remains almost the same, only the dry run directory parameter needs to go away:

./ --username neo4j \
                --password changeme \
                --graph-db-uri jdbc:neo4j:bolt://localhost \
                --changelog CHANGELOG_FILE

You can then check the data has been added in Neo4j Browser with the following Cypher query:

MATCH (sentence:Sentence) RETURN sentence.text AS text

The result should be "Hello world!".

You can re-run the same Liquigraph command several times and observe that the graph remains unchanged. In other words, the following Cypher query:

MATCH (sentence:Sentence) RETURN COUNT(sentence)

... should indeed always return 1.

Good to know

If you ever run a less specific Cypher query such as MATCH (n) RETURN n, you will see that more node and relationships are returned. This is normal: Liquigraph persists the change log history in the same database. The change log history graph structure is covered in much more details in the reference documentation.