Question
I installed Node.js using Homebrew on macOS Mojave. After that, PHP stopped working. When I run the following command:
php -v
I get this error:
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib
Referenced from: /usr/local/bin/php
Reason: image not found
I also tried uninstalling both node and icu4c, but the problem still remains. What causes this error, and how can I fix PHP so it works again?
Short Answer
By the end of this page, you will understand what a dyld: Library not loaded error means on macOS, why Homebrew package upgrades can break PHP, how shared libraries like icu4c are linked, and the practical steps to diagnose and repair broken Homebrew installations.
Concept
On macOS, many programs do not contain every piece of code they need inside a single executable file. Instead, they depend on shared libraries at runtime. When you run a command like php -v, macOS uses the dynamic loader (dyld) to find and load the libraries PHP was built against.
In this case, PHP is trying to load this file:
/usr/local/opt/icu4c/lib/libicui18n.62.dylib
That file belongs to the Homebrew package icu4c, which provides ICU libraries used for Unicode and internationalization features.
The error happens because PHP was built or linked against a specific ICU version (62), but that exact file no longer exists. This often happens when:
- Homebrew upgrades
icu4cto a newer version - A package was removed or relinked
- PHP still points to an older library path
- Homebrew dependencies became inconsistent after installing or upgrading another package
This matters because many command-line tools and server applications depend on shared libraries. If dependency versions move but binaries are not rebuilt, programs can stop working even though the program itself was not directly changed.
The core idea is:
- Your PHP binary is fine as a file
- Its runtime dependency link is broken
- The fix is usually to reinstall or relink the dependency or rebuild PHP against the current library version
Mental Model
Think of PHP as a worker showing up to do a job with a list of helper tools it expects to find in a toolbox.
- PHP = the worker
dyld= the person checking the toolbox before work startsicu4clibrary file = one of the required tools
If the worker says, "I need tool version 62," but the toolbox only contains version 63 or 64, work cannot start.
So the problem is not that the worker disappeared. The problem is that the exact helper tool PHP expects is missing.
In Homebrew terms:
- Homebrew installs and upgrades packages
- Some packages depend on others
- If one dependency changes version, the dependent package may need to be rebuilt or reinstalled
Syntax and Examples
The most useful commands here are diagnostic shell commands.
Check which PHP is being used
which php
php -v
This tells you the binary path and whether it starts correctly.
Inspect Homebrew package status
brew list --versions php icu4c node
brew info php
brew info icu4c
This shows which versions are installed and whether Homebrew still knows about them.
Reinstall the missing dependency and PHP
brew reinstall icu4c
brew reinstall php
This is the most common fix because it ensures:
icu4cis present- PHP is rebuilt or relinked against the current ICU library version
Refresh Homebrew metadata first
brew update
brew upgrade
brew reinstall php
Use this if your Homebrew state is old or inconsistent.
Example repair workflow
brew update
brew reinstall icu4c
brew reinstall php
php -v
If successful, php -v should print the PHP version instead of the dyld error.
Step by Step Execution
Consider this command sequence:
brew reinstall icu4c
brew reinstall php
php -v
Here is what happens step by step:
-
brew reinstall icu4c- Homebrew downloads or uses a cached copy of the
icu4cpackage. - It installs the current ICU libraries under the Homebrew Cellar.
- It updates the
optsymlink so packages can refer to the active version.
- Homebrew downloads or uses a cached copy of the
-
brew reinstall php- Homebrew reinstalls PHP.
- During installation, PHP is linked against the currently installed
icu4cversion. - Symlinks such as
/usr/local/bin/phpare updated.
-
php -v- The shell finds the
phpexecutable. - macOS runs
dyldto load all shared libraries PHP needs. - Because the expected ICU library is now available and correctly linked, PHP starts normally.
- The shell finds the
Small trace example
Broken state:
php -v
Real World Use Cases
This concept appears often in real development environments.
Local development setups
You install or upgrade one tool with Homebrew, and another tool breaks because both share dependencies.
Examples:
- PHP breaks after
icu4cchanges - Python packages fail after OpenSSL upgrades
- Database clients stop working after library updates
CI and build servers
A build image updates system packages, but cached binaries still expect old shared libraries.
Native extensions
Language runtimes such as PHP, Python, Ruby, and Node may use compiled extensions that depend on system libraries.
Command-line tools
Utilities installed with package managers often depend on dynamic libraries. A missing version can prevent the tool from launching at all.
Web server environments
If Apache, Nginx helpers, or PHP-FPM are linked against outdated libraries, local or staging servers may fail to start.
Real Codebase Usage
In real projects, developers usually handle this kind of issue with repeatable environment management rather than one-off fixes.
Common patterns
Reinstall after dependency upgrades
If a shared library changes, reinstall dependent packages:
brew reinstall php
brew reinstall wget
brew reinstall imagemagick
Verify the active binary
Developers often check for path issues before debugging deeper:
which php
which node
which python3
This helps detect when an old binary is still first in PATH.
Use guard checks in setup scripts
Teams often include validation commands in onboarding scripts:
php -v || echo "PHP is broken"
brew doctor
Keep package manager state healthy
Useful maintenance commands:
brew update
brew doctor
brew cleanup
Prefer reproducible environments
In larger codebases, developers may avoid system dependency drift by using:
- Docker containers
- Version managers
- Project-specific setup scripts
Common Mistakes
1. Reinstalling the wrong package only
A common mistake is reinstalling node because the problem appeared after installing Node.js.
brew reinstall node
That may not help, because the broken package is actually PHP or one of PHP's dependencies.
Better approach
Reinstall the dependency and the dependent package:
brew reinstall icu4c
brew reinstall php
2. Assuming uninstalling fixes broken links
Removing packages can make the situation worse if another package still depends on them.
Broken approach:
brew uninstall icu4c
If PHP still expects icu4c, uninstalling it guarantees PHP cannot start.
3. Ignoring which binary is actually running
You may have multiple PHP installations.
which php
If this points to an old binary, reinstalling another PHP may not solve the issue.
4. Manually creating fake library files
Some users try to hack around the problem with manual symlinks from one version to another.
Example of a risky workaround:
Comparisons
| Approach | What it does | When to use it | Risk level |
|---|---|---|---|
brew reinstall icu4c | Reinstalls the missing library | When the library package is missing or corrupted | Low |
brew reinstall php | Rebuilds or relinks PHP against current dependencies | When PHP references an old library version | Low |
brew unlink php && brew link php --force | Refreshes Homebrew symlinks | When the installed PHP is correct but symlinks are stale | Medium |
| Manual symlink hack | Pretends one library version is another | Only as a temporary emergency workaround, if ever | High |
| Uninstall random packages | Removes software without fixing links |
Cheat Sheet
Quick diagnosis
which php
php -v
brew list --versions php icu4c
brew info php
brew info icu4c
brew doctor
Most common fix
brew update
brew reinstall icu4c
brew reinstall php
php -v
Refresh symlinks
brew unlink php
brew link php --overwrite --force
Useful ideas to remember
dyldis macOS's dynamic loader.dylibfiles are dynamic librariesicu4cprovides ICU Unicode/internationalization libraries- A missing versioned library usually means a package upgrade changed the dependency version
- Reinstalling the dependent package is often necessary after a dependency upgrade
- Check
which phpbefore assuming the correct binary is being used
Red flags
- Manually faking library versions with symlinks
- Uninstalling dependencies without checking what uses them
- Assuming the last package you installed is the package that is broken
FAQ
Why did PHP break after installing Node with Homebrew?
Installing Node may have triggered Homebrew to upgrade or relink shared dependencies. PHP then tried to load an older ICU library version that no longer existed.
What does dyld: Library not loaded mean on macOS?
It means the executable started, but macOS could not find one of the shared libraries it needs at runtime.
What is icu4c used for?
icu4c provides ICU libraries for Unicode, locales, collation, and other internationalization features used by many programs, including PHP.
Is uninstalling icu4c a good fix?
Usually no. If PHP depends on it, removing it will not solve the problem. Reinstalling it and PHP is a better approach.
How do I know if I have multiple PHP versions installed?
Run:
which php
ls -l $(which php)
This shows which binary your shell is using.
Should I manually create a symlink from a newer ICU version to the missing one?
Usually no. Library versions may not be binary compatible, so this can cause crashes or harder-to-debug errors.
What command usually fixes this fastest?
In most cases:
brew update
brew reinstall icu4c
brew reinstall php
Mini Project
Description
Create a small shell-based troubleshooting checklist for diagnosing broken Homebrew runtime dependencies on macOS. This project helps you practice the exact commands developers use when tools like PHP fail because of missing shared libraries.
Goal
Build and run a short diagnostic workflow that identifies the active PHP binary, checks Homebrew package state, and repairs a broken PHP installation.
Requirements
- Check which
phpbinary is currently being used. - Verify whether
phpandicu4care installed by Homebrew. - Run a Homebrew health check.
- Reinstall the dependency and PHP.
- Confirm that
php -vworks after the repair.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.