A modular dotfiles and environment management system that allows you to manage configurations, setups, and run scripts across different machines and environments.
curl https://raw.githubusercontent.com/tylerthecoder/owl/main/setups/owl/setup.sh | bashThis installs owl to ~/owl
- Then it runs
owl nest allwhich will prompt you to select a nest and then it will install the nest to you computer.
The machine is now ready. (might need a reboot)
Stored in setups/,
Modules that handle software installation and configuration:
- setup.json: Defines optional fields for a setup
name(string)links(array of { source, target, root? })rc_scripts(array of strings; supportscommon:andlocal:)menu_scripts(array of strings or objects withpathandname)install(string path to install script)services(array of { path, type } where type isuserorsystem; daemon-reload is triggered automatically when linking services)dependencies(array of setup names)only_own_menu_scripts(boolean, optional): When true on a nest, prevents inherited menu scripts from dependencies while keeping the nest's own menu scripts
Stored in nests/, nests are collections of setups that define a complete environment for a specific machine or purpose.
Each nest is just a root setup: it uses the same setup.json schema as any other setup, and typically declares other setups via dependencies.
Example nest setup.json:
{
"links": [
{ "source": "common:config/.vimrc", "target": "~/.vimrc" },
{ "source": "local:.xprofile", "target": "~/.xprofile" }
],
"dependencies": ["git", "zsh", "rust"],
"rc_scripts": ["common:fzf.sh", "common:base-aliases.sh", "local:.shenv"]
}Files that are symlinked from the repository to the home directory or system locations. They can be defined in setups or nests.
How owl uses it:
- Created during
owl setup <name> linkorowl nest link. - Existing targets are safely replaced (symlinks/files removed; non-empty directories are refused).
- If
root: trueis set for a link, owl will create parent directories and the symlink withsudo.
How to specify in setup.json:
{
"links": [
{ "source": "common:config/.vimrc", "target": "~/.vimrc" },
{ "source": "local:kitty.conf", "target": "~/.config/kitty/kitty.conf" },
{ "source": "setups/git/gitconfig", "target": "~/.gitconfig" }
]
}Path tokens:
common:<path>→common/<path>in the repolocal:<path>→ relative to the setup directory- paths without tokens resolve from the repo root (
owl_path)
Shell scripts that are sourced during shell initialization. They can be defined in setups or nests.
How owl uses it:
- Linked into
~/.config/owl/rc/asrc-<setup>-<filename>duringlink. owl-start.shsources all scripts in~/.config/owl/rc/.
How to specify in setup.json:
{
"rc_scripts": [
"common:fzf.sh",
"common:base-aliases.sh",
"local:rc.sh"
]
}Path tokens:
common:<file>→common/rc/<file>local:<file>→ relative to the setup directory
Scripts that appear in application menus (like rofi or dmenu). They can be defined in setups or nests.
How owl uses it:
- Linked into
~/.config/owl/menu-scripts/. Simple entries use the filename; detailed entries can set a customname.
How to specify in setup.json:
{
"menu_scripts": [
"common:emoji.sh",
{ "path": "local:cliphist.sh", "name": "clipboard" }
]
}Path tokens:
common:<file>→common/menu-scripts/<file>local:<file>→ relative to the setup directory
Systemd unit files to link and enable.
How owl uses it:
- Owl links service files to the appropriate systemd directory.
- During
systemd, owl enables and starts them (and triggers daemon-reload as part of enable).
How to specify in setup.json:
{
"services": [
{ "path": "common:greenclip.service", "type": "user" },
{ "path": "local:my-daemon.service", "type": "system" }
]
}Path tokens:
common:<file>→common/services/<file>local:<file>→ relative to the setup directory
Type values:
user(default) →~/.config/systemd/usersystem→/etc/systemd/system(requires sudo)
The simplified startup script that:
- Sets XDG environment variables (
XDG_CONFIG_HOME,XDG_CACHE_HOME,XDG_DATA_HOME,XDG_STATE_HOME) - Adds local bin to PATH
- Sources all scripts from
~/.config/owl/rc/
Note: All install scripts and rc scripts can rely on XDG variables being set when owl-start.sh is sourced in your shell profile.
owl nest link [--shallow]: Link files, rc scripts, menu scripts, and servicesowl nest install [--shallow]: Run install scripts with dependency resolutionowl nest systemd [--shallow]: Link and enable/restart servicesowl nest info [--shallow]: Show what would be linkedowl nest edit: Open the active root setup for editingowl nest switch: Switch the active nest interactively
owl setup <name> <link|install|systemd|info|edit|all> [--shallow]
owl config: Show current configurationowl sync: Sync repository (fetch, fast-forward, and optionally push changes)owl setups-validate: Validate all setups and nestsowl update [--recursive]: Update owl itself. Uses thesetups/owlinstall script.
Config stored in ~/.config/owl/config.json:
- owl_path: Location of this repository
- nest_path: Path to your active root setup directory (e.g.,
nests/<name>)
Build and test:
cargo build
cargo run -- nest link