PHPackages                             somework/composer-symlinks - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. somework/composer-symlinks

ActiveComposer-plugin[Utility &amp; Helpers](/categories/utility)

somework/composer-symlinks
==========================

Create relative symlinks based on getcwd() and relative data

2.2.0(7mo ago)521.2k↓25%10[1 PRs](https://github.com/somework/composer-symlinks/pulls)1MITPHPPHP &gt;=7.4CI passing

Since Oct 30Pushed 3mo ago2 watchersCompare

[ Source](https://github.com/somework/composer-symlinks)[ Packagist](https://packagist.org/packages/somework/composer-symlinks)[ RSS](/packages/somework-composer-symlinks/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (3)Dependencies (4)Versions (35)Used By (1)

ComposerSymlinks
================

[](#composersymlinks)

Its provide a simple Composer script to symlink paths. Compatible with Composer v2.

Installation
------------

[](#installation)

To install the latest stable version of this component, open a console and execute the following command:

```
$ composer require somework/composer-symlinks

```

Usage
-----

[](#usage)

### 1. Define symlinks

[](#1-define-symlinks)

Create the symlinks definition adding a `somework/composer-symlinks` section inside the `extra` section of the composer.json file.

The behaviour of the plugin can be tuned via the following configuration keys:

KeyDefaultDescription`skip-missing-target``false`Do not fail when the target does not exist.`absolute-path``false`Create symlinks using the real path to the target.`throw-exception``true`Throw an exception on errors instead of just printing the message.`force-create``false`Remove any existing file or directory at the link path before creating the symlink.`cleanup``false`Remove symlinks that were created previously but are no longer present in the configuration.`windows-mode``junction`Windows-only strategy: `symlink` (require Developer Mode/administrator), `junction` (fallback to junction/hardlink/copy), or `copy` (mirror the target without links).You can set personal configs for any symlink. For personal configs `link` must be defined

```
{
    "extra": {
        "somework/composer-symlinks": {
            "symlinks": {
                "common/upload": "web/upload",
                "common/static/dest": {
                    "link": "web/dest",
                    "skip-missing-target": false,
                    "absolute-path": true,
                    "throw-exception": false
                }
            },
            "force-create": false,
            "skip-missing-target": false,
            "absolute-path": false,
            "throw-exception": true,
            "cleanup": true
        }
    }
}
```

When `cleanup` is enabled the plugin keeps a registry of every symlink it created in the file `vendor/composer-symlinks-state.json`. On the next run the registry is compared with the current configuration: entries missing from the configuration are deleted from both the registry and the filesystem. The file is recreated automatically and can safely be ignored by VCS.

### Placeholder syntax

[](#placeholder-syntax)

Symlink paths support the following placeholders which are expanded before validation:

PlaceholderDescription`%project-dir%`Absolute path to the project root (current working directory during Composer execution).`%vendor-dir%`Absolute path to the Composer vendor directory.`%env(NAME)%`Value of the environment variable `NAME`. Missing variables expand to an empty string.Placeholders allow the resulting paths to be absolute while the original configuration remains portable. Direct absolute paths without placeholders are still rejected by default to avoid accidental misuse.

### 2. Refresh symlinks

[](#2-refresh-symlinks)

Symlinks are created automatically on `composer install`/`update`, but you can trigger the process manually with the built-in command:

```
$ composer symlinks:refresh
```

Add the `--dry-run` flag to preview the operations without touching the filesystem:

```
$ composer symlinks:refresh --dry-run
```

The legacy environment variable `SYMLINKS_DRY_RUN=1` is still honoured during Composer hooks for backwards compatibility.

### 3. Inspect symlink status

[](#3-inspect-symlink-status)

Audit the current state of the configured links without modifying the filesystem:

```
$ composer symlinks:status
```

The command compares the configuration with the registry file and the actual filesystem. The report highlights missing links, mismatched targets, and stale entries that are present in the registry but no longer configured. Use the `--strict` option to make the command exit with a non-zero code when problems are detected (ideal for CI pipelines), and `--json` to obtain a machine-readable summary:

```
$ composer symlinks:status --json --strict
```

### 4. Execute composer

[](#4-execute-composer)

DO NOT use --no-plugins for composer install or update

### Dry run

[](#dry-run)

Set environment variable `SYMLINKS_DRY_RUN=1` to preview created links without modifying the filesystem.

Example output:

```
$ SYMLINKS_DRY_RUN=1 composer install --no-interaction
  [DRY RUN] Symlinking /tmp/sample/linked.txt to /tmp/sample/source/file.txt
```

### Uninstalling

[](#uninstalling)

Running `composer remove somework/composer-symlinks` will trigger the plugin's `uninstall()` hook. The hook reads the registry file and removes every stored symlink from the filesystem before deleting the registry itself. This ensures that no links created by the plugin are left behind when the package is removed.

### Typical error messages

[](#typical-error-messages)

MessageMeaning`No link passed in config`The `link` option was missing for a symlink definition.`No target passed in config`The key of the `symlinks` map was empty.`Invalid symlink target path`The target path was absolute but should be relative.`Invalid symlink link path`The link path was absolute but should be relative.`The target path ... does not exists`The target file or directory was not found.`Link ... already exists`A file/directory already occupies the link path.`Cant unlink ...`The plugin failed to remove a file when using `force-create`.`Failed to create symlink ... Enable Windows Developer Mode ...`Windows denied symlink creation. Enable Developer Mode or set `windows-mode` to `junction`/`copy`.Run `composer symlinks:status` after encountering an error to obtain a detailed report of which links are missing or pointing to unexpected targets.

### Windows compatibility

[](#windows-compatibility)

On Windows, creating symlinks requires either Administrator privileges or that the system is running in Developer Mode. When native symlinks are not available, the plugin falls back automatically (default `windows-mode` value) to NTFS junctions for directories and hardlinks/copies for files. You can opt into different behaviours by setting `extra.somework/composer-symlinks.windows-mode`to one of:

- `symlink` – always attempt a real symlink. Failures explicitly mention enabling Developer Mode or switching to a fallback strategy.
- `junction` (default) – try a symlink first, then use junctions for directories and hardlinks/copies for files when permissions prevent symlink creation.
- `copy` – skip symlinks altogether and mirror the target contents at the link path.

Regardless of the chosen mode, relative symlinks use Unix-style `/` separators internally which Windows resolves correctly.

License
-------

[](#license)

This component is under the MIT license. See the complete license in the [LICENSE](LICENSE) file.

Reporting an issue or a feature request
---------------------------------------

[](#reporting-an-issue-or-a-feature-request)

Issues and feature requests are tracked in the [Github issue tracker](https://github.com/somework/composer-symlinks/issues).

###  Health Score

53

—

FairBetter than 97% of packages

Maintenance71

Regular maintenance activity

Popularity33

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 93.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~206 days

Recently: every ~652 days

Total

15

Last Release

235d ago

Major Versions

0.3.1 → 1.02018-02-20

1.3.2 → 2.0.02025-06-07

PHP version history (3 changes)0.1PHP &gt;7.0

2.0.0PHP &gt;=8.0

2.1.0PHP &gt;=7.4

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/19801428?v=4)[Igor Pinchuk](/maintainers/somework)[@somework](https://github.com/somework)

---

Top Contributors

[![somework](https://avatars.githubusercontent.com/u/19801428?v=4)](https://github.com/somework "somework (27 commits)")[![pandmitr](https://avatars.githubusercontent.com/u/6427560?v=4)](https://github.com/pandmitr "pandmitr (2 commits)")

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/somework-composer-symlinks/health.svg)

```
[![Health](https://phpackages.com/badges/somework-composer-symlinks/health.svg)](https://phpackages.com/packages/somework-composer-symlinks)
```

###  Alternatives

[vaimo/composer-patches

Applies a patch from a local or remote file to any package that is part of a given composer project. Patches can be defined both on project and on package level. Optional support for patch versioning, sequencing, custom patch applier configuration and patch command for testing/troubleshooting added patches.

2994.3M16](/packages/vaimo-composer-patches)[mglaman/composer-drupal-lenient

1317.4M15](/packages/mglaman-composer-drupal-lenient)[drupal/core-composer-scaffold

A flexible Composer project scaffold builder.

5341.9M446](/packages/drupal-core-composer-scaffold)[drupal/core-project-message

Adds a message after Composer installation.

2122.6M172](/packages/drupal-core-project-message)[olvlvl/composer-attribute-collector

A convenient and near zero-cost way to retrieve targets of PHP 8 attributes

184108.8k8](/packages/olvlvl-composer-attribute-collector)[lullabot/drainpipe

An automated build tool to allow projects to have a set standardized operations scripts.

41716.4k2](/packages/lullabot-drainpipe)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
