Migration from Bash/Zsh
Hash can load your existing shell configuration with a compatibility layer, making it easy to switch without losing your customizations.
Automatic Migration (First Run)
When you first launch Hash, it detects your previous shell and offers to load compatible settings:
Detected ~/.zshrc from your previous shell (zsh).
Would you like to load compatible settings?
[Y] Yes, load settings
[n] No, start fresh
[?] What does this do?
Choosing "Yes" sources your existing config with a compatibility layer. Aliases, environment variables, and functions work automatically. Zsh-specific features are silently skipped.
Manual Migration
You can run migration manually at any time:
Checking Migration Status
See what was imported and what was skipped:
Migration from ~/.zshrc (shell: zsh)
Imported:
23 aliases
8 environment variables
3 functions
Skipped: 14 items
Last import: 2024-01-15 10:30:00
Load vs Generate
Hash offers two approaches for using your existing shell config:
Load (default)
When you run hash migrate and choose "Yes", Hash records your config files and sources them directly at startup with compatibility filtering:
# Hash migration: shell config loaded from:
# ~/.zprofile
# ~/.zshrc
#
# Files are sourced at startup with bash syntax support.
# Run 'hash migrate generate' to create a standalone .hashrc
# Run 'hash migrate status' to see what was skipped
#
# Add your own customizations below:
Advantages:
- Changes to your
.zshrcare automatically picked up - You can keep using the same config for both shells during transition
- Zsh-specific commands are silently skipped at runtime
- Full bash syntax support including
[[,==, process substitution
Generate (standalone copy)
If you want a completely independent Hash config that doesn't depend on your old shell:
This extracts all compatible settings into a standalone ~/.hashrc file, with zsh-specific lines removed entirely.
Advantages:
- Clean break from your old shell config
- Faster startup (no compatibility filtering needed)
- Can safely delete or modify your
.zshrc
What Gets Imported
| Feature | Bash | Zsh | Notes |
|---|---|---|---|
| Aliases | ✓ | ✓ | Converted to functions (see note below) |
| Environment variables | ✓ | ✓ | export statements |
| Functions | ✓ | ✓ | POSIX-compatible syntax |
| PATH modifications | ✓ | ✓ |
Note: Aliases are converted to functions
Hash converts alias definitions to shell functions internally. This ensures that complex aliases with bash syntax (like && or ||) work correctly:
alias deploy='npm run build && npm run deploy'
# Hash internally converts to:
deploy() { npm run build && npm run deploy; }
This is transparent — you use the alias name normally, and it works as expected. The conversion happens because Hash parses each command independently, so traditional alias expansion isn't available. Functions provide the same functionality with full bash syntax support.
What Gets Skipped
| Feature | Reason | Hash Alternative |
|---|---|---|
bindkey | zsh-specific key bindings | Keybindings config |
setopt | zsh shell options | Hash config options |
compdef / zstyle | zsh completion system | Hash completion |
autoload | zsh function autoloading | Define functions directly |
| precmd hooks | zsh-specific | — |
Troubleshooting
Tool-specific workarounds
Some popular tools need Hash-specific setup:
direnv:
eval "$(direnv hook bash)"
zoxide:
eval "$(zoxide init bash)"
starship:
Hash has built-in Starship support. Set prompt.mode = "starship" in your config.toml instead of using eval.
Bash Syntax Support
Hash fully supports bash 5.x syntax, including features that are shared between bash and zsh:
[[...]]extended test construct==string comparison (inside[[ ]])=~regex matching- Process substitution:
<(cmd)and>(cmd) - Arrays and associative arrays
sourceandevalcommands work with bash syntax
This means your existing bash and zsh configs will work without modification. The compatibility layer handles shell-specific features automatically.
Parse errors
If you see parse errors from your rc file, it may contain syntax that's specific to zsh and not shared with bash. Run hash migrate status to see what was skipped, or use hash migrate generate to create a clean config.