Skip to content

Project Configuration

What vdl.config.vdl Does

vdl.config.vdl tells vdl generate which plugins to run, which schema each plugin should read, where generated files should be written, and which plugin-specific options should be passed in.

The file is itself written in VDL. VDL reads a constant named config from this file.

const config = {
  version 1
  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/ts"
    }
  ]
}

The file must be named exactly:

vdl.config.vdl

Minimal Configuration

const config = {
  version 1
  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/json-schema"
    }
  ]
}

This configuration:

  • uses config format version 1
  • runs one plugin
  • analyzes ./schema.vdl
  • writes generated files under ./gen/json-schema

Top-Level Fields

Field Required Description
version yes Configuration format version. Currently use 1.
cleanOutDir no Whether VDL cleans output directories before writing new files.
plugins no List of plugin runs to execute.
remotes no Authentication settings for private plugin hosts.
hooks no Host shell commands run before or after generation.

version

Set version to 1.

const config = {
  version 1
}

VDL rejects unsupported config versions.

plugins

plugins is an array of plugin configurations.

const config = {
  version 1
  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/go"
      options {
        package "contracts"
      }
    }
  ]
}

Each plugin entry has these fields:

Field Required Description
src yes Plugin JavaScript source.
schema yes Path to the .vdl schema this plugin should process.
outDir yes Directory where plugin output files should be written.
generateHeader no Whether VDL adds generated-file header comments. Default is true.
options no Plugin-specific string options passed through as-is.

Plugin Sources

src can use one of three forms.

GitHub Shorthand

src "varavelio/[email protected]"

This resolves to:

https://raw.githubusercontent.com/varavelio/vdl-plugin-go/v0.1.3/dist/index.js

Rules:

  • use owner/repo@ref
  • the repository name must start with vdl-plugin-
  • the plugin artifact must exist at dist/index.js
  • prefer release tags or full commit hashes for reproducibility

Local JavaScript File

src "./plugins/my-plugin.js"

Local plugin paths must point to .js files and must start with . or /.

Use this while developing a plugin locally or for private in-repo generators.

Remote HTTPS URL

src "https://example.com/plugins/my-plugin/index.js"

Remote plugin URLs must point to .js files. HTTPS is required by default.

For local development, insecure HTTP can be enabled with VDL_INSECURE_ALLOW_HTTP=true.

schema

schema points to the VDL file the plugin should compile.

schema "./schema.vdl"

The path is resolved relative to vdl.config.vdl and must end with .vdl.

Different plugins can process the same schema:

const config = {
  version 1
  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/go"
    }
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/json-schema"
    }
  ]
}

outDir

outDir is the root directory for files returned by a plugin.

outDir "./gen/go"

Plugins return relative file paths like types.go or models/user.ts. VDL writes them under outDir.

VDL validates generated paths so plugins cannot write outside outDir.

If two plugin outputs try to write the same final file path in one generation run, generation fails.

options

options is a map of string values passed to the plugin.

options {
  package "contracts"
  strict "true"
  importExtension "js"
}

All option values are strings. If a plugin option behaves like a boolean, pass values such as "true" or "false" according to that plugin's documentation.

Options are plugin-specific. Always check the plugin README or available plugins guide.

generateHeader

By default, VDL adds generated-file headers when writing plugin outputs.

const config = {
  version 1
  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/go"
      generateHeader false
    }
  ]
}

Use generateHeader false only when a target format cannot safely contain comments or when the plugin already handles headers.

cleanOutDir

By default, VDL replaces configured output directories with the newly generated files.

const config = {
  version 1
  cleanOutDir true
  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/ts"
    }
  ]
}

Set cleanOutDir false to merge generated files into existing directories without deleting files that are not part of the current output.

const config = {
  version 1
  cleanOutDir false
  plugins [
    {
      src "./plugins/custom.js"
      schema "./schema.vdl"
      outDir "./gen/custom"
    }
  ]
}

Use merge mode carefully. Old generated files may remain if a plugin stops producing them.

remotes

Use remotes when a plugin is hosted behind authentication.

const config = {
  version 1
  remotes [
    {
      host "github.com/my-org/private-vdl-plugin"
      auth {
        github {
          tokenEnv "GITHUB_TOKEN"
        }
      }
    }
  ]
  plugins [
    {
      src "my-org/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/private"
    }
  ]
}

host should not include https:// or http://.

When multiple remotes match a plugin URL, VDL uses the most specific host.

Supported authentication forms:

  • GitHub token
  • custom header
  • bearer token
  • basic auth

Each remote auth entry should define exactly one authentication method.

GitHub Token

remotes [
  {
    host "github.com/my-org/private-vdl-plugin"
    auth {
      github {
        tokenEnv "GITHUB_TOKEN"
      }
    }
  }
]

VDL reads the token from the named environment variable and sends it as a bearer token.

Custom Header

remotes [
  {
    host "plugins.example.com"
    auth {
      header {
        nameEnv "PLUGIN_HEADER_NAME"
        valueEnv "PLUGIN_HEADER_VALUE"
      }
    }
  }
]

Bearer Token

remotes [
  {
    host "plugins.example.com"
    auth {
      bearer {
        tokenEnv "PLUGIN_TOKEN"
      }
    }
  }
]

Basic Auth

remotes [
  {
    host "plugins.example.com"
    auth {
      basic {
        userEnv "PLUGIN_USER"
        passEnv "PLUGIN_PASS"
      }
    }
  }
]

hooks

Hooks run shell commands on the host machine.

const config = {
  version 1
  hooks {
    preGenerate ["npm run check"]
    postGenerate ["npm run format"]
  }
  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/ts"
    }
  ]
}

Hook behavior:

  • preGenerate commands run before plugins. The first failure stops generation.
  • postGenerate commands run after files are written. Failures are printed as warnings and do not roll back generated files.
  • commands run from the directory containing vdl.config.vdl
  • hooks are skipped when VDL_SKIP_HOST_HOOKS or VDL_CLOUD is truthy

Lock File

Remote plugin downloads are cached and recorded in vdl.lock.

The lock file stores hashes for remote plugin artifacts so VDL can detect unexpected changes.

Commit vdl.lock when your project depends on remote plugins.

Complete Example

const config = {
  version 1
  cleanOutDir true

  hooks {
    preGenerate ["npm run check"]
    postGenerate ["npm run format"]
  }

  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/go"
      options {
        package "contracts"
        strict "true"
      }
    }
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./gen/json-schema"
      options {
        outFile "schema.json"
        root "User"
      }
    }
  ]
}

Common Patterns

Generate data models and documentation from the same schema:

const config = {
  version 1
  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./generated/types"
    }
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./generated/docs"
    }
  ]
}

Generate Go models and Go RPC code into separate packages:

const config = {
  version 1
  plugins [
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./internal/contracts"
      options {
        package "contracts"
      }
    }
    {
      src "varavelio/[email protected]"
      schema "./schema.vdl"
      outDir "./internal/rpcclient"
      options {
        target "client"
        package "rpcclient"
        typesImport "example.com/project/internal/contracts"
      }
    }
  ]
}

Troubleshooting

If vdl generate cannot find the config file, make sure the file is named exactly vdl.config.vdl.

If a plugin source fails to resolve, check whether src is a local .js path, an HTTPS .js URL, or a valid GitHub shorthand.

If a private plugin fails to download, check the matching remotes entry and the required environment variables.

If generated files disappear, check cleanOutDir. The default behavior is to replace output directories.