PHPackages                             niklan/composer-directories - 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. niklan/composer-directories

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

niklan/composer-directories
===========================

Composer plugin that automatically creates directories defined in your composer.json.

1.0.0-alpha4(2w ago)0481—0%MITPHPPHP &gt;=8.2CI passing

Since Mar 5Pushed 2w agoCompare

[ Source](https://github.com/Niklan/composer-directories)[ Packagist](https://packagist.org/packages/niklan/composer-directories)[ RSS](/packages/niklan-composer-directories/feed)WikiDiscussions main Synced today

READMEChangelog (4)Dependencies (6)Versions (5)Used By (0)

Composer Directories
====================

[](#composer-directories)

A Composer plugin that automatically creates directories and symlinks defined in your `composer.json` during `install` and `update` commands. Directories are always created before symlinks.

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

[](#installation)

```
composer require niklan/composer-directories
```

Usage
-----

[](#usage)

Add configuration to the `extra` section of your `composer.json`:

```
{
    "extra": {
        "ensure-directories": [
            "web/sites/simpletest/browser_output",
            "var/log",
            "var/files/public",
            {"path": "var/files/private", "permissions": "0700"}
        ],
        "symlinks": {
            "var/files/public": "web/sites/default/files"
        }
    }
}
```

Both features work independently -- you can use directories, symlinks, or both.

### Directories

[](#directories)

- String entries use the default permission `0775` (`drwxrwxr-x`), matching the [Drupal default](https://git.drupalcode.org/project/drupal/-/blob/aea47fe1b2bf7945548988ca14d069b83273f2a5/core/lib/Drupal/Core/File/FileSystem.php#L27).
- Object entries accept a `path` and an optional `permissions` string in [octal format](https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation).
- All paths are relative to the project root (where `composer.json` is located).

### Symlinks

[](#symlinks)

- Keys are targets, values are link paths. Both are relative to the project root.
- If a symlink already exists and points to the correct target, it is left as-is. If it points elsewhere, it is replaced.
- If a non-symlink file/directory exists at the link path, it is skipped with a warning.
- On Windows, directory junctions are used instead of symlinks (no admin rights needed).

### Verbose output

[](#verbose-output)

Run `composer install -v` to see skipped directories and symlinks that already exist:

```
> post-install-cmd: Niklan\ComposerDirectories\DirectoriesPlugin->onPostCommand
  Directory exists: var/files/private
  Directory exists: var/files/private/translations
  Directory exists: var/files/public
  Directory exists: var/files/temporary
  Directory exists: var/log
  Symlink exists: web/sites/default/files

```

### Security

[](#security)

Paths that resolve outside the project root (e.g., `../../../etc`) are rejected with a warning. This applies to both directories and symlinks (target and link).

Development
-----------

[](#development)

### Requirements

[](#requirements)

- PHP 8.2+
- Composer 2.x

### Setup

[](#setup)

```
composer install
```

### Linting

[](#linting)

```
# Run all linters
composer lint

# Run individually
composer phpcs    # PHP CodeSniffer (PSR-12 + Slevomat)
composer phpstan  # PHPStan (level 10)
```

### Auto-fix code style

[](#auto-fix-code-style)

```
composer phpcbf
```

### Testing

[](#testing)

```
composer phpunit
```

### Run everything

[](#run-everything)

```
composer test
```

License
-------

[](#license)

MIT

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance96

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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 ~0 days

Total

4

Last Release

17d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ef8e55f87a49952ce429ba13d2dffaa5583720254890162e4311d44b07dd3a67?d=identicon)[Niklan](/maintainers/Niklan)

---

Top Contributors

[![Niklan](https://avatars.githubusercontent.com/u/2356744?v=4)](https://github.com/Niklan "Niklan (6 commits)")

---

Tags

composer-plugindirectoriesmkdirensure-directories

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/niklan-composer-directories/health.svg)

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

###  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.

2984.2M13](/packages/vaimo-composer-patches)[mnsami/composer-custom-directory-installer

A composer plugin, to help install packages of different types in custom paths.

1444.9M44](/packages/mnsami-composer-custom-directory-installer)[typisttech/imposter-plugin

Composer plugin that wraps all composer vendor packages inside your own namespace. Intended for WordPress plugins.

157245.4k2](/packages/typisttech-imposter-plugin)[drupal-composer/preserve-paths

Composer plugin for preserving custom paths and supporting nested packages

271.1M5](/packages/drupal-composer-preserve-paths)[arokettu/composer-license-manager

License management plugin for Composer

61202.5k](/packages/arokettu-composer-license-manager)[liborm85/composer-vendor-cleaner

Composer Vendor Cleaner removes unnecessary development files and directories from vendor directory.

35326.3k1](/packages/liborm85-composer-vendor-cleaner)

PHPackages © 2026

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