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(10mo ago)337.9kMITPHPPHP ^8.4CI passing

Since Sep 11Pushed 1mo ago2 watchersCompare

[ Source](https://github.com/decodelabs/veneer)[ Packagist](https://packagist.org/packages/decodelabs/veneer)[ RSS](/packages/decodelabs-veneer/feed)WikiDiscussions develop Synced 3w 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

53

—

FairBetter than 96% of packages

Maintenance76

Regular maintenance activity

Popularity28

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity81

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

306d 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 (409 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

[symfony/dependency-injection

Allows you to standardize and centralize the way objects are constructed in your application

4.2k447.1M9.0k](/packages/symfony-dependency-injection)[illuminate/contracts

The Illuminate Contracts package.

706127.7M12.5k](/packages/illuminate-contracts)[illuminate/container

The Illuminate Container package.

31180.7M2.3k](/packages/illuminate-container)[symfony/type-info

Extracts PHP types information.

20062.9M225](/packages/symfony-type-info)[ecotone/ecotone

Enterprise architecture layer for Laravel and Symfony — CQRS, Event Sourcing, Durable Workflows (Sagas, Orchestrators), Projections, and Outbox messaging via PHP attributes.

562565.8k42](/packages/ecotone-ecotone)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

749284.3k35](/packages/civicrm-civicrm-core)

PHPackages © 2026

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