Adobe Experience Manager (AEM) File Transfers for Developers

There are several different ways to handle file transfers between AEM and your local file system. In this post, I’m going to go over a couple command line tools to transfers files between my local file system and AEM 6.5: AEM repo tool and FileVault VLT.

AEM repo tool

Follow the instructions at Adobe-Marketing-Cloud / tools / repo to install on your system. For Linux, I used curl to install the repo bash script since it is just a single file. e.g.,

curl -L -o $HOME/bin/repo

chmod +x $HOME/bin/repo

Add the repo script to your environment PATH as needed.

zip and unzip required by repo. Install these in Ubuntu using apt-get install zip unzip.



Property Value
server http://localhost:4502
credentials admin:admin

If your server and/or credentials differ from the defaults, in your project folder, create a .repo file with your AEM server location and credentials. e.g.,


For projects located in a GNU/Linux environment like WSL (Windows Subsystem for Linux), transfer files to a localhost AEM (Adobe Experience Manager) instance running on the Windows file system by using a Windows Localhost Resolver. The .repo configuration file would look like this given win.localhost specified for the Windows hostname to add or update.

.repo (default credentials)


Specify the AEM JCR path to transfer from. Unlike vlt, you can only perform an action on a single path. There is not an option for a batch transfer that can use a filter.

If your local file system already has an AEM project, for example that was installed using Maven. Instead of repo checkout, you can use repo get or repo put for incremental folder and file transfers.

cd myproject

repo checkout /apps/weretail

This will create a jcr_root folder containing the checked out folders and files.

  • myproject
    • jcr_root
      • apps
        • weretail
    • .repo

Use the put command to transfer updated files into the AEM JCR.

cd jcr_root/apps/weretail/components/content/heroimage

repo put heroimage.html

Use the -s option with a command to specify a different server to interact with. For example, transfer to the publish instance on port 4503.

repo put -s http://localhost:4503 heroimage.html


Command Alias Description
checkout Intial checkout of server content on file system
diff Show differences, same as ‘localdiff’ from local
get Download server content to local file system
localdiff Show differences done locally compared to server
put Upload local file system content to server
serverdiff Show differences done on the server compared to local
status st list status of modified/added/deleted files

For help on a command, use repo <command> -h. e.g., repo -h get. For the entire help contents, repo -h.

IDE Integration

Adobe-Marketing-Cloud / tools / repo / README contains a good bit of information on how to integrate the commands into various IDE’s including Visual Studio Code and IntelliJ. These integration methods should also work for the FileVault VLT commands.

VS Code

Create a tasks.json for the current workspace. e.g., .vscode/tasks.json

Select Terminal > Configure Tasks > Create tasks.json file from template > Others.

Folder actions will be performed on the folder of the currently opened file.

    "version": "2.0.0",
    "tasks": [
            "label": "put file",
            "type": "shell",
            "command": "repo put -f ${file}",
            "problemMatcher": []
            "label": "put folder",
            "type": "shell",
            "command": "repo put -f ${fileDirname}",
            "problemMatcher": []
            "label": "get file",
            "type": "shell",
            "command": "repo get -f ${file}",
            "problemMatcher": []
            "label": "get folder",
            "type": "shell",
            "command": "repo get -f ${fileDirname}",
            "problemMatcher": []
animation: AEM repo tool, Visual Studio Code - Run Task > Put Folder
Put folder task using the AEM repo tool with Visual Studio Code.

I like to use the keyboard to run a task. For example, open the command palette using Ctrl+Shift+p, or on OS X, ⌘ command+Shift+p and enter “tasks”. Then use the arrow and enter keys to select a task.

Tasks configured with "type":"shell" are run in a non-interactive shell without a profile or RC. VS Code attempts to get environment variables from the same environment VS Code is running under. On OS X, I’ve experience an intermittent issue with the repo command not found despite it being in my PATH. To check which PATHS are available to the shell, create a task that will echo them. For example,

"tasks": [
        "label": "path echo",
        "type": "shell",
        "command": "echo $PATH"

One way to resolve this is by adding the PATH to your project .vscode/settings.json. For example,

        "PATH": "/usr/local/bin:${env:PATH}"

For more information on Visual Studio Code integration, refer to the VS Code Task documentation.

FileVault VLT

The Apache Jackrabbit FileVault VLT command line tool maps the contents of an AEM Java Content Repository (JCR) to your file system.

To get the latest FileVault, clone or download the jackrabbit-filevault repo from github.

In AEM versions 6.3 and earlier, you could install FileVault from its archive in the crx-quickstart/opt/filevault/ folder of your AEM instance. For example, AEM 6.3, includes both filevault-3.1.38.tgz and

Next, build FileVault using Maven. e.g.,

cd jackrabbit-filevault

mvn clean install

Check the documentation for build requirements. At the time of this writing, Maven 3.3.9 (or higher) with Java 8 (or higher) required. I used openjdk version 1.8.0_232 and Maven 3.6.2 when building.

The initial build will take a few minutes, for example:

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for Apache Jackrabbit FileVault (Reactor Project) 3.4.1-SNAPSHOT:
[INFO] Apache Jackrabbit FileVault (Parent Project) ....... SUCCESS [  9.574 s]
[INFO] Apache Jackrabbit FileVault Core Bundle ............ SUCCESS [02:31 min]
[INFO] Apache Jackrabbit FileVault Diff (Diff utilities) .. SUCCESS [  1.549 s]
[INFO] Apache Jackrabbit FileVault JCR Remoting Service ... SUCCESS [  1.658 s]
[INFO] Apache Jackrabbit FileVault RCP Server Bundle ...... SUCCESS [  1.224 s]
[INFO] Apache Jackrabbit FileVault Documentation .......... SUCCESS [  0.066 s]
[INFO] Apache Jackrabbit FileVault Sync Service ........... SUCCESS [  1.611 s]
[INFO] Apache Jackrabbit FileVault Platform Interaction ... SUCCESS [  0.947 s]
[INFO] Apache Jackrabbit FileVault Command Line Interface . SUCCESS [  2.600 s]
[INFO] Apache Jackrabbit FileVault Package Hook Example ... SUCCESS [  2.040 s]
[INFO] Apache Jackrabbit FileVault Package Hook Sling Example SUCCESS [  0.350 s]
[INFO] Apache Jackrabbit FileVault Validation ............. SUCCESS [  3.375 s]
[INFO] Apache Jackrabbit FileVault (Reactor Project) ...... SUCCESS [ 13.789 s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  03:15 min
[INFO] Finished at: 2019-12-06T18:42:47-05:00
[INFO] ------------------------------------------------------------------------


Extract the archive from the vault-cli/target directory in the build.

For example,

cd vault-cli/target

tar xfz vault-cli-3.4.1-SNAPSHOT-bin.tar.gz

If you like, rename the directory for the PATH so it does not contain -SNAPSHOT. e.g.,

mv vault-cli-3.4.1-SNAPSHOT vault-cli-3.4.1

Add the bin directory which contains vlt and vlt.bat to your environment PATH. For example, in Linux, this can be done in the users .profile.

export PATH=$PATH:$HOME/aem/jackrabbit-filevault/vault-cli/target/vault-cli-3.4.1/bin

Once you’ve updated your environment PATH to include the bin directory, verify using the vlt command (you may have to logout for your PATH changes to take effect).

vlt --help


Using vlt co, you can checkout files from the AEM JCR.

Note: this example will checkout all of the files. In a default AEM 6.5 author instance, there are over 2 GB’s of files.

cd jcr_root

vlt --credentials admin:admin co --force http://localhost:4502/crx

The credentials only need to be specified on the initial checkout and are added to ~/.vault/auth.xml for subsequent operations.

Checkout Filter

A META-INF manifest folder exists alongside the jcr_root. Create this folder if needed and add a vault/filter.xml file. Now you can checkout just the directories you specify in this filter instead of the entire JCR.

  • myproject
    • jcr_root
    • META-INF
      • vault
        • filter.xml
<?xml version="1.0" encoding="UTF-8"?>
<workspaceFilter version="1.0">
  <filter root="/apps/weretail"/>
  <filter root="/apps/we-retail-communities"/>
  <filter root="/apps/we-retail-screens"/>
  <filter root="/content/we-retail"/>

Typically, the /content filter paths will contain a mode="merge" attribute to prevent existing content on the server from being overwritten. e.g., <filter root="/content/we-retail" mode="merge"/>.

Import Modes

  • replace Content is overwritten or deleted as needed by replacing the existing with the imported content.
  • merge Content is not modified, only new content is added.
  • update : Existing content is updated, new content is added and none is deleted.

Refer to the documentation for more info.

Save the filter and run vlt checkout. Use --force to overwrite the previous checkout as needed. e.g.,

cd jcr_root

vlt co --force http://localhost:4502/crx


Update and commit a file back into the AEM JCR to test the operation. For example,


<sly data-sly-use.heroImage="we.retail.core.model.HeroImage">
  <div class="${heroImage.classList} jumbotron"
     style="background-image: url('${(properties.fileReference || properties.fileName) ? heroImage.image.src : '' @ context='uri'}');">
    <div class="container cq-dd-image">
      <div class="we-HeroImage-wrapper">
        <p class="h3">${properties.heading}</p>
        <strong class="we-HeroImage-title h1">${properties.title || currentPage.title}</strong>

        <h3 style="font-weight:bold;text-shadow: 2px 2px 4px #000000;">
          VLT TESTING

        <p data-sly-test="${properties.buttonLabel && properties.buttonLinkTo}">
          <a class="btn btn-primary btn-action" href="${properties.buttonLinkTo @ extension = 'html'}" role="button">${properties.buttonLabel}</a>

Commit the change with the -v option (verbose output) to see what is being transferred. e.g.,

vlt ci -v apps/weretail/components/content/heroimage/heroimage.html

Verify the update, e.g.,

View a page that has the heroimage component as published, http://localhost:4502/content/we-retail/us/en.html?wcmmode=disabled

VLT Commands

Command Alias Description
add Puts files and directories under version control
checkout co Checkout a Vault file system
commit ci Send changes from your working copy to the repository
console Run an interactive console
delete del, rm Remove files and directories from version control
diff di Display the differences between two paths
export Export the Vault filesystem from the jcr
format Formats vault docview files
import Import a Vault filesystem into the jcr
info Displays information about a local file
propget pg Print the value of a property on files or directories
proplist pl Print the properties on files or directories
propset ps Set the value of a property on files or directories
rcp Remote copy of repository content
resolved res Remove ‘conflicted’ state on working copy files or directories
revert rev Restore pristine working copy file (undo most local edits)
status st Print the status of working copy files and directories
sync Control vault sync service
update up Bring changes from the repository into the working copy

For help on a command, use vlt --help plus the name of the command. e.g., vlt --help commit

comments powered by Disqus