PHPackages                             decodelabs/veneer - 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. decodelabs/veneer

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

decodelabs/veneer
=================

Automated static facades

v0.12.10(8mo ago)337.8k↓100%MITPHPPHP ^8.4CI passing

Since Sep 11Pushed 5mo ago2 watchersCompare

[ Source](https://github.com/decodelabs/veneer)[ Packagist](https://packagist.org/packages/decodelabs/veneer)[ RSS](/packages/decodelabs-veneer/feed)WikiDiscussions develop Synced 1mo ago

READMEChangelog (10)Dependencies (4)Versions (76)Used By (0)

Veneer
======

[](#veneer)

[![PHP from Packagist](https://camo.githubusercontent.com/394ab5ab92bf411d2b328fb5d9e898208ede481392e0f012039b31f60ce75aa7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6465636f64656c6162732f76656e6565723f7374796c653d666c6174)](https://packagist.org/packages/decodelabs/veneer)[![Latest Version](https://camo.githubusercontent.com/a65458d8d6d021ecea975c350cbd1ef67c106cfbc0445c2d2ef8e7b9abe757e6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6465636f64656c6162732f76656e6565722e7376673f7374796c653d666c6174)](https://packagist.org/packages/decodelabs/veneer)[![Total Downloads](https://camo.githubusercontent.com/021b6645bf385acd4169e76ce7f38a69ed29763c703d5972efa285ec4b3e67f0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6465636f64656c6162732f76656e6565722e7376673f7374796c653d666c6174)](https://packagist.org/packages/decodelabs/veneer)[![GitHub Workflow Status](https://camo.githubusercontent.com/32d5286648fb2e90c78c3f136bfc03a1ec2b37e5be16e743dd84c9d21203d3d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6465636f64656c6162732f76656e6565722f696e746567726174652e796d6c3f6272616e63683d646576656c6f70)](https://github.com/decodelabs/veneer/actions/workflows/integrate.yml)[![PHPStan](https://camo.githubusercontent.com/e25c14ce011edabdd0fbd2e10415b41cc5d66ed11ef3e5b7edd074c5bdd35a2d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d656e61626c65642d3434434331312e7376673f6c6f6e6743616368653d74727565267374796c653d666c6174)](https://github.com/phpstan/phpstan)[![License](https://camo.githubusercontent.com/390d9f7a73a77e4a4f1e4839a8f3747a7664900675efe2790f8457380419fa34/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6465636f64656c6162732f76656e6565723f7374796c653d666c6174)](https://packagist.org/packages/decodelabs/veneer)

### Create automated static frontages for your PHP objects.

[](#create-automated-static-frontages-for-your-php-objects)

Use Veneer to provide easy access to your most commonly used functionality without sacrificing testability.

---

Install
-------

[](#install)

This package requires PHP 8.4 or higher.

Install via Composer:

```
composer require decodelabs/veneer
```

Usage
-----

[](#usage)

Say you have a common library class you use regularly:

```
namespace Some\Random\Library;

// This is a library class you use regularly
class MyThing
{
    public function doAThing() {
        echo 'Done!';
    }
}
```

You can bind a static, automatically generated frontage by:

```
namespace App\Setup;

// This is your environment setup code
use DecodeLabs\Veneer;
use Some\Random\Library\MyThing;
use App\CoolThing;

Veneer::register(
    MyThing::class, // active object class
    CoolThing::class // frontage class
);

namespace Some\Other\Code;

use App\CoolThing;

// Your general userland code
CoolThing::doAThing();
```

### Plugins

[](#plugins)

Unfortunately PHP still doesn't have `__getStatic()` yet so we have to statically declare plugin names at binding time, but they're still useful for creating more expansive interfaces.

Define plugins as properties on your `FacadeTarget` with a `Plugin` attribute. By default, plugins require manual instantiation in the constructor, however you can flag it as `auto` to have it automatically built at bind time, or `lazy` if it doesn't need to be loaded straight away.

```
namespace My\Library
{
    use DecodeLabs\Veneer\Plugin;

    class MyThing {

        #[Plugin]
        public MyPlugin $plugin;

        #[Plugin(auto: true)]
        public MyPlugin $autoPlugin;

        #[Plugin(lazy: true)]
        public MyPlugin $lazyPlugin;

        public function __construct() {
            $this->plugin = new MyPlugin();
        }
    }

    class MyPlugin
    {
        public function doAThing(): string {
            return 'Hello from plugin';
        }
    }
}

namespace Some\Other\Code
{
    use My\Library\MyThing;

    MyThing::$plugin->doAThing(); // Hello from plugin
    MyThing::$autoPlugin->doAThing(); // Hello from plugin
    MyThing::$lazyPlugin->doAThing(); // Hello from plugin
}
```

Note, if your target class has a constructor with required parameters, you will need to add `decodelabs/slingshot` to your project to allow Veneer to instantiate it.

Lazy instantiation uses the new ghost and proxy functionality in PHP8.4 and will only instantiate the plugin when it is first accessed. Due to the limitations of lazy objects in PHP, you cannot create a lazy proxy for internal classes so you may find that plugins are referenced with a transparent `Plugin\Wrapper` class which resolves to the actual plugin instance when accessed. This usually isn't an issue unless you try to pass a plugin instance to a function that expects a specific class type, directly from the proxy. In these cases you should return the plugin instance from a method on the target class.

### Property Hooks

[](#property-hooks)

PHP 8.4 property hooks can be used in combination with Plugins, however be aware that they will conflict with auto and lazy instantiation. Hooks defined with the structure below will effectively act like a lazy loaded plugin, however with the additional benefits of being able to control how it is instantiated rather than relying on Slingshot.

```
namespace My\Library
{
    use DecodeLabs\Veneer\Plugin;

    class MyThing {

        #[Plugin]
        protected(set) MyPlugin $plugin {
            get => $this->plugin ??= new MyPlugin();
        }
    }
}
```

Hooks *can* be virtual (ie, don't require a value backed property), however the proxy will reference the first instantation of a virtual hook and your plugin instances will likely go out of sync.

Note, the `protected(set)` visibility in the example; it is not a requirement, but it is recommended to prevent direct write access to the property. If you need to replace a plugin instance, you should do so via `Veneer::replacePlugin($providerInstance, 'propertyName', $newPlugin)`. This allows Veneer to update the plugin in the static frontage proxy as well as the target instance.

Licensing
---------

[](#licensing)

Veneer is licensed under the MIT License. See [LICENSE](./LICENSE) for the full license text.

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance71

Regular maintenance activity

Popularity29

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity80

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 97.8% 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 ~29 days

Recently: every ~46 days

Total

74

Last Release

261d ago

PHP version history (5 changes)v0.1.0PHP ^7.2

v0.7.0PHP ^7.2|^8.0

v0.9.0PHP ^8.0

v0.10.23PHP ^8.1

v0.12.0PHP ^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/8a241d64d12b3b5ee94197862ec1ec30b82ed2efa34a0cd7f4c3565a021daddd?d=identicon)[betterthanclay](/maintainers/betterthanclay)

---

Top Contributors

[![betterthanclay](https://avatars.githubusercontent.com/u/1273586?v=4)](https://github.com/betterthanclay "betterthanclay (405 commits)")[![szepeviktor](https://avatars.githubusercontent.com/u/952007?v=4)](https://github.com/szepeviktor "szepeviktor (9 commits)")

---

Tags

facadefrontagephplibraryfacadetools

### Embed Badge

![Health badge](/badges/decodelabs-veneer/health.svg)

```
[![Health](https://phpackages.com/badges/decodelabs-veneer/health.svg)](https://phpackages.com/packages/decodelabs-veneer)
```

###  Alternatives

[tgmpa/tgm-plugin-activation

TGM Plugin Activation is a PHP library that allows you to easily require or recommend plugins for your WordPress themes (and plugins).

1.8k222.5k13](/packages/tgmpa-tgm-plugin-activation)[ph-7/qrcode-generator-php-class

Light QRCode PHP class (library). QR Code Generator using vCard 4.0 and the Google Chart AP

10415.5k2](/packages/ph-7-qrcode-generator-php-class)

PHPackages © 2026

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