The Puli logo.

Puli: Universal Packages for PHP

Puli (pronounced “poo-lee”) is a universal package system for PHP. Puli aims to replace “bundles”, “plugins”, “modules” and similar specialized packages of different frameworks with one generic, framework independent solution.

The Puli Package

A Puli package is a directory that contains PHP code, non-PHP files and a puli.json file. The puli.json file configures how your application and other Puli packages access and load the contents of your package.

        ... PHP files ...
        ... non-PHP files ...

Puli packages are typically installed with Composer. Add a composer.json to the package and distribute it on Packagist. Then your package can be installed with the composer command line utility:

$ composer require vendor/my-package

Features of Puli Packages

Resource Access

Puli provides a naming convention (so called Puli paths) to access non-PHP files (YAML, XML, CSS, HTML, images and more) from a Puli package:

// views/index.html.twig in the "batman/blog" package
echo $twig->render('/batman/blog/views/index.html.twig');

The path is resolved by reading path mappings from the puli.json files of your installed Puli packages. Authors of these packages, such as the author of the “batman/blog” package, map prefixes to actual directories with the Puli Command Line Interface (CLI):

$ php puli.phar map /batman/blog res


Puli packages may act as consumers and as providers of resources and PHP classes. For example, a translator package (the consumer) may request translation files from other installed packages (the providers).

Puli's resource discovery mechanism.

Consumers, like our translator, give a name to the resources they want to load, such as “thor/translations”. This name is called a binding type. Other packages (the resource providers) assign their translation files to this type. This is called binding. In the end, you as the user of both packages only need to pass Puli’s Discovery to the Translator class:

$translator = new Translator($discovery);

The translator then loads all bound translation files from the discovery without any further configuration.

Package Overrides

Puli packages may override other packages. For example, your application or a specialized theme package may replace the style.css file provided by a generic package “batman/blog” by a custom version:

$ php puli.phar map /batman/blog/css/style.css res/css/blog/style.css

Resource URLs

Puli publishes CSS files, JavaScript files and images bundled in your packages and generates their public URLs for you. You can pass Puli paths to simple utility functions to generate URLs in your PHP or HTML code:

<img src="{{ resource_url('/batman/blog/public/logo.png') }}" />

Puli paths can be marked public with the Puli CLI:

$ php puli.phar publish /batman/blog/public localhost /blog/

Here, we published the /batman/blog/public directory to the sub-directory /blog/ of the server “localhost”. That server must also be defined with the Puli CLI:

$ php puli.phar server --add localhost public_html

This command registers the server “localhost” with the directory public_html used as document root. Now Puli has enough information to generate your URLs:

<img src="/blog/logo.png" />

Resource Installation

If you want, you can use Puli also to install your public resources on the server. If the server is your localhost, Puli creates simple symbolic links or file copies in your document root:

$ php puli.phar publish --install
Installing /batman/blog/public into public_html/blog via symlink...

For the final release of Puli, this functionality will be moved to plugins for Gulp, Brunch or similar asset management tools.

Getting Started

Read Installation to get started with Puli.


Puli’s core packages maintain Puli’s infrastructure for you.

Package Source Current Version Next Stable Release
The Puli Manager GitHub 1.0.0-beta10 late 2016
The Command Line Interface GitHub 1.0.0-beta10 late 2016
The Composer Plugin GitHub 1.0.0-beta10 late 2016


The Puli components provide the interface between your PHP code and Puli.

Component Source Current Version Next Stable Release
The Repository Component GitHub 1.0.0-beta10 late 2016
The Discovery Component GitHub 1.0.0-beta9 late 2016
The URL Generator Component GitHub 1.0.0-beta4 late 2016


Puli’s extensions provide integration with different third-party tools.

Extension Source Current Version Next Stable Release
The Symfony Bridge GitHub 1.0.0-beta4 late 2016
The Symfony Bundle GitHub 1.0.0-beta10 late 2016
The Twig Extension GitHub 1.0.0-beta8 late 2016


Contributions to Puli are very welcome!

If you find issues in the documentation, please let us know:


If you are having problems, send a mail to or shout out to @PuliPHP on Twitter.


Puli, its extensions and this documentation are licensed under the MIT license.