Watch our latest talk from KubeCon + CloudNativeCon EU 2024!
Carvel Logo

Declaratively state directory's contents

Sync any number of data sources into a consistent structure by writing a YAML definition. Share the definition or generated lockfile and ensure that your whole team is working under the same expectations.


Provide the desired final structure of the directory and let vendir handle how to get there. No more manually cloning repositories,checking multiple sources for updates, or trying to remember CURL flags while fetching content over HTTP.


Like the rest of the Carvel suite, vendir was made to accomplish its task and do no more. Sync your files then use them however you like without restrictive permissions or wrestling your tools for ownership.


Ensure that the same files will be collected across all invocations by syncing from the generated lockfile, with tags and URLs replaced by resolved SHAs, and digests.


Support Various Sources

Specify the source of a managed directory from a git repository at a given revision, a docker image, a helm chart, or many others

Take Portions of a Source

Retain only what you need and leave the rest, keeping your directory bloat-free regardless of upstream changes, with additional rules for common files (e.g. a licensing file)

Leave Subdirectories Untouched

vendir allows you to mark paths as manually managed, leaving your files safely unmodified while reaping the benefits of a synced folder

Basic Usage

Create vendir.yml (as shown below) in the root of your project and populate it with configuration describing what to fetch. In this example we want vendir to "own" config/_ytt_lib directory and download app ytt library into config/_ytt_lib/app directory.

kind: Config
- path: config/_ytt_lib
  - path: app
      ref: origin/develop
    newRootPath: app

Execute vendir sync command to download specified assets.

$ vendir sync
Fetching: config/_ytt_lib + app (git from

  --> git init
  Initialized empty Git repository in /tmp/build/ary23/foo/.vendir-tmp/incoming/git/.git/
  --> git config credential.helper store --file /tmp/build/ary23/foo/.vendir-tmp/incoming/git-auth/.git-credentials
  --> git remote add origin
  --> git fetch origin
   * [new branch]      develop    -> origin/develop
  --> git -c advice.detachedHead=false checkout origin/develop
  HEAD is now at 916fba7... adding action for marking issues as stale and closing stale issues
  --> git submodule update --init --recursive
  --> git rev-parse HEAD
  --> git describe --tags 916fba7952afcfabf6ef2ac218c605364f395f1d
  fatal: No names found, cannot describe anything.
  --> git log -n 1 --pretty=%B 916fba7952afcfabf6ef2ac218c605364f395f1d
  adding action for marking issues as stale and closing stale issues

  Signed-off-by: Joao Pereira <>

Lock config

- contents:
  - git:
      commitTitle: adding action for marking issues as stale and closing stale issues...
      sha: 916fba7952afcfabf6ef2ac218c605364f395f1d
    path: app
  path: config/_ytt_lib
kind: LockConfig


Let's examine what vendir placed into our directory.

$ tree .
|-- config
|   `-- _ytt_lib
|       `-- app
|           |-- deployment.yml
|           |-- hpa.yml
|           |-- ingress.yml
|           |-- refs.lib.yml
|           |-- service.yml
|           `-- values.yml
|-- vendir.lock.yml
`-- vendir.yml

3 directories, 8 files

Getting started

To help you get started, see the documentation.