~/.dotfiles-core

Cross-platform dotfiles, MIT licensed

One shell setup for macOS, Windows, and WSL

Four shells share one sh layer, and one manifest decides what gets linked where. The Mac and the Windows box stop drifting apart.

platforms
3
shells
4
symlinks
11
zsh on macOS: the installer's dry run
~/code/dotfiles-core on main
❯ ./scripts/install.sh
platform: macos
DRY RUN. Nothing will be changed. Re-run with --apply.
 
  shell    would link ~/.zshrc -> macos/zshrc
  prompt   would link ~/.config/starship.toml -> shared/starship.toml
  git      would link ~/.gitconfig -> shared/git/gitconfig
  git      would link ~/.config/git/ignore -> shared/git/ignore
  claude   would link ~/.claude/CLAUDE.md -> shared/claude/CLAUDE.md
  claude   would link ~/.claude/settings.json -> shared/claude/settings.json
 
6 links planned, 0 errors. Re-run with --apply.
scripts/modules.conf

One manifest, three home folders

Both installers and the check script read one flat file, so adding a link to every machine is one line. Files are linked, not copied.

scripts/modules.conf (excerpt)
# module | source | target | platforms
shell  | macos/zshrc          | ~/.zshrc                | macos
shell  | wsl/bashrc           | ~/.bashrc               | wsl
prompt | shared/starship.toml | ~/.config/starship.toml | macos,wsl
git    | shared/git/gitconfig | ~/.gitconfig            | macos,gitbash,wsl,windows
  • macOS

    zsh

    6 links

  • Windows

    Git Bash, PowerShell

    7 links from Git Bash, 6 from PowerShell

  • WSL

    bash

    6 links

shared/shell/

Four shells, one shared layer

The POSIX shells source the same sh files, so a function written once works in zsh on the Mac and in bash on Windows and WSL. PowerShell cannot source POSIX shell configuration, so it gets its own profile.

  • zsh

    macOS

    macos/zshrc

    sources shared/shell/

  • bash

    WSL

    wsl/bashrc

    sources shared/shell/

  • bash

    Git Bash on Windows

    windows/bashrc and windows/bash_profile

    sources shared/shell/

  • pwsh

    PowerShell on Windows

    windows/Microsoft.PowerShell_profile.ps1

    own profile, same prompt

What the shared layer gives every POSIX shell

Write a function once and use it on every machine. Starship stays quiet outside projects.

mkcd <dir>
Create a directory and enter it
up 3
Move up three directory levels
groot
Jump to the repository root
path
Print PATH, one entry per line
port 3000
Find the process using a port
serve [port]
Serve the current directory over HTTP
extract <file>
Extract common archive formats
ff <pattern>
Recursive search, skipping .git
sizes [dir]
Show entries ordered by size
update_all
Update npm, pipx, and the platform's package managers
--apply

Safe to run on a machine you care about

The installers change nothing until you ask, and they never delete a file.

  1. Dry run by default

    Every run prints the plan first. Only --apply, or -Apply in PowerShell, writes anything.

  2. Nothing is deleted

    An existing file is renamed to <target>.bak.<timestamp> before a link replaces it.

  3. Private stays local

    No Git identity or employer config in the repository. Every rc file sources an untracked *.local sibling last, so local values win.

  4. Clean uninstall

    --unlink removes only symlinks that point into this repository, and --restore puts the backups back.

quick start

Install

Clone it anywhere, read the dry run, then apply it.

macOS, WSL, and Git Bash

git clone https://github.com/marcop135/dotfiles-core.git ~/code/dotfiles-core
cd ~/code/dotfiles-core
./scripts/install.sh          # dry run: read the plan
./scripts/install.sh --apply  # then link it

Windows PowerShell

git clone https://github.com/marcop135/dotfiles-core.git ~/code/dotfiles-core
cd ~/code/dotfiles-core
.\scripts\install.ps1         # dry run: read the plan
.\scripts\install.ps1 -Apply  # then link it

  • Needs git and one supported shell. Starship is optional; without it the shell keeps its normal prompt.
  • Windows symlinks need Developer Mode or an elevated shell. The installers tell you when that is missing.
  • Install one module with --only shell, or skip one with --skip prompt.

Questions

What does it need to run?

Git and one supported shell: zsh on macOS, Git Bash or PowerShell on Windows, bash on WSL. No runtime or package manager to install.

What is not included?

Git identity, employer and client configuration, package lists, macOS system settings, and editor and terminal settings. Put your identity in ~/.gitconfig.local and anything private in the .local files.

How do I update it?

Run git pull and ./scripts/install.sh --apply again. The installer is idempotent: existing links stay as they are and new configuration gets linked.

How do I uninstall it?

Run ./scripts/install.sh --unlink --restore --apply. It removes only the symlinks that point into the repository and puts the backups back.

What does the Claude Code part do?

It links two user-level files, CLAUDE.md and settings.json. The settings turn off telemetry and the auto-updater, keep commands behind approval, and deny secret files, force-push, and pushes to main. The deny rules are a safety floor, not a sandbox.