Skip to content
repoverlay 0.17.0 is out now.Release notes

Creating & Sharing Overlays

Package existing files into an overlay, then share it so others can apply it.

The create command packages files from your current repository into an overlay and saves them to your overlay repository:

Terminal window
# Auto-detect org/repo from git remote
repoverlay create my-overlay
# Explicit target path
repoverlay create microsoft/vscode/ai-config

Use --include to specify which files to include:

Terminal window
repoverlay create my-overlay --include .claude/ --include CLAUDE.md --include .envrc

Without --include, repoverlay launches an interactive file selector that detects AI configs, gitignored files, and untracked files as candidates.

Terminal window
# See what would be created without writing anything
repoverlay create my-overlay --dry-run
# Overwrite an existing overlay
repoverlay create my-overlay --force

If you don't have an overlay repository set up, or want to create an overlay in a local directory, use --output:

Terminal window
repoverlay create --output ./my-overlay
repoverlay create --output ./output --include .envrc --include .claude/

create --output performs two actions:

  1. Writes overlay files to the specified directory
  2. Auto-applies the overlay to your repository (symlinks replace originals, state saved, .git/info/exclude updated)

To see what would be created and applied without modifying your repository, use --dry-run:

Terminal window
# Preview: see what files would be created and applied
repoverlay create --output ./my-overlay --dry-run

This shows you the overlay contents and what would be applied, without writing files or mutating your repository.

Create a repoverlay.ccl in the root of your overlay directory to control how files are applied:

overlay =
name = my-config
description = Shared editor and environment config
/= Rename files when applying
mappings =
.envrc.template = .envrc
vscode-settings.json = .vscode/settings.json
/= Symlink entire directories as a unit
directories =
= .claude
= scratch

The overlay.name field sets the name used in status, remove, and other commands. If omitted, the directory name is used. The optional overlay.description field documents what the overlay is for, for people reading the overlay config.

The mappings section renames files during apply. Each entry maps a source filename to a destination path. This is useful when the overlay uses different filenames than the target repo expects.

One source file can map to multiple destinations — repeat the key with a different destination each time:

mappings =
config.json = .vscode/settings.json
config.json = .zed/settings.json

The directories section lists directories to symlink (or copy) as a unit rather than walking individual files. This is important for directories like .claude/ where the entire tree should be managed atomically.

repoverlay uses CCL (Categorical Configuration Language) for configuration files. CCL uses = for key-value pairs and indentation for nesting. Lines starting with /= are comments.

Overlays in the in-repo library can build on each other instead of duplicating files. Two keys in repoverlay.ccl control this:

Inherit every file from a single parent overlay:

extends =
overlay = base-config

The parent's files, mappings, and directories are all inherited. Chains are allowed (a child can extend a parent that itself extends a grandparent), and repoverlay detects cycles.

Cherry-pick specific files from other overlays:

includes =
=
overlay = tools
files =
= .editorconfig
= scripts/lint.sh

You can list several includes entries, and included overlays are resolved recursively — they may use extends or includes themselves.

When the same destination path comes from more than one place, the highest-precedence version wins:

  1. The overlay's own files
  2. Files from extends
  3. Files from includes (later entries override earlier ones)

An overlay repository organizes overlays by target project:

my-overlays/
├── microsoft/
│ └── FluidFramework/
│ ├── claude-config/
│ │ ├── CLAUDE.md
│ │ └── .claude/
│ └── dev-tools/
│ └── .envrc
└── tylerbutler/
└── tools-monorepo/
└── ai-config/
└── CLAUDE.md

The structure is <target-org>/<target-repo>/<overlay-name>/. When someone runs repoverlay apply org/repo/overlay-name, repoverlay resolves the overlay from this directory structure.

A global overlay applies to any repository, regardless of its git remote. Global overlays live in a reserved @global/ namespace alongside the per-project <org>/<repo>/ directories:

my-overlays/
├── microsoft/
│ └── FluidFramework/
│ └── claude-config/
└── @global/
└── dotfiles/
└── .gitconfig

Create one with the --global flag (it takes a bare name and skips git-remote detection):

Terminal window
repoverlay create dotfiles --global

Global overlays are listed for every repository under a Global heading in repoverlay browse, displayed as */<name>, and applied by their bare name:

Terminal window
repoverlay apply dotfiles

When a global overlay and a repo-scoped overlay share a name, the repo-scoped overlay wins (structured org/repo/name resolves before @global/name within a source; sources are still tried in priority order).

Global overlays don't change how overlays work — any overlay is technically applicable to any repository. You can apply an overlay defined for repo A onto repo B; resolution only cares about file paths and conflicts, not which repo an overlay was created for. The @global namespace simply makes that intent explicit and lets an overlay resolve for every repository without needing an org/repo match.

Once you've created overlays in a repository, push it to GitHub:

Terminal window
cd ~/my-overlays
git push origin main

Others can then apply your overlays using your GitHub username:

Terminal window
# Interactive selection
repoverlay apply tylerbutler

Direct three-part references use the target repository's org and repo plus the overlay name (<target-org>/<target-repo>/<overlay-name>), and resolve against configured sources — so consumers add your overlay repository as a source first:

Terminal window
repoverlay source add tylerbutler/my-overlays
# Applies the ai-config overlay defined for tylerbutler/tools-monorepo
repoverlay apply tylerbutler/tools-monorepo/ai-config

Or browse without applying:

Terminal window
repoverlay browse tylerbutler