Skip to main content
Winter Boot’s module system gives you a clean, attribute-driven mechanism for bundling infrastructure integrations — Redis, Kafka, Doctrine ORM, service discovery, and more — as self-contained, reusable units. Modules are discovered and loaded before the application starts, so each module can register its own beans, scan additional namespaces, and run any required initialisation without touching your application code. The WinterModule interface keeps the contract minimal: implement two lifecycle hooks and annotate your class with #[Module].

The WinterModule Interface

Every module must implement the WinterModule interface. The framework calls its two lifecycle methods during startup in a predictable order.
void
Called during the module loading phase. Use this hook to register beans, validate configuration, and verify required PHP extensions are present.
void
Called after all modules are loaded and the application context is fully ready. Use this hook to open connections, start background processes, or subscribe to events.

The #[Module] Attribute

Annotate every module class with #[Module]. This tells the framework how to scan the module’s namespaces and provides metadata used in log output.
When namespaces is left empty, the framework automatically registers the namespace derived from the module file’s location. Only provide explicit [namespace, directory] pairs when your module ships classes in directories outside its own file path.

Enabling Modules in application.yml

Declare modules in your application.yml under the top-level modules key. Each entry requires a module class name and an enabled flag.
application.yml
Modules are loaded in the order they appear in application.yml. If one module depends on beans registered by another, place the dependency first in the list.

First-Party Modules

All official modules live in the suvera/winter-modules monorepo. Install the entire collection with a single Composer command:
See the Modules overview for a full catalog with guidance on which module to pick for which use case.

Doctrine

Doctrine ORM and DBAL for entity management, DBAL, and multi-tenant datasources.

Redis

PhpRedis client templates for singles, clusters, arrays, sentinels, and token rings.

Memcache

Memcached and Memcache client templates for lightweight caching.

Kafka

Apache Kafka producer and consumer integration for event streaming pipelines.

SQS

Amazon SQS producer and consumer with IAM role and IRSA support.

S3

Amazon S3 and S3-compatible object storage from any bean.

OpenSearch

OpenSearch indexing, querying, and AWS SigV4-signed access.

DTCE

Distributed Task Computing Engine for cross-node background task orchestration.

Eureka

Service discovery via Consul and Netflix Eureka.

Memdb

Embedded in-memory servers (Redis, Ignite, Memcached, Hazelcast) managed by the app lifecycle. EXPERIMENTAL

Security

Application security policies for Winter Boot applications.

Building a Custom Module

Package any infrastructure concern — a third-party SDK, a custom cache layer, an internal service client — as a reusable, injectable module by following these steps.
1

Create the module class

src/Module/AcmeMyModule.php
2

Register beans inside init()

Use ApplicationContextData::getBeanProvider() to register beans that consumers can inject with #[Autowired]:
3

Read module configuration

The framework passes the raw moduleDef YAML entry to your #[Module] attribute. Use the ModuleTrait helper to retrieve it:
4

Enable the module in application.yml

application.yml
5

Install via Composer

See the suvera/winter-modules repository for real-world examples of how first-party modules are structured and tested — it is the best reference when building your own.