What is Winter
Winter is a PHP framework for APIs and web applications. Routes, parameter binding, validation and database work are declared with attributes, right in the code — no configuration files, no registries, no generated magic. And the application stays resident, serving requests on coroutines.
Who this is for
- Architects and leads evaluating the framework for a team: Philosophy and Ecosystem.
- Developers who want to write code: Installation and Quick start take you to a working route.
- Those already building — Key concepts puts the whole mental model in one place.
What the code looks like
A controller is a class extending the Controller stereotype; a route is an
attribute on a method. Nothing else needs registering:
<?php
namespace Main;
use Flytachi\Winter\Kernel\Http\Response\ResponseEntity;
use Flytachi\Winter\Kernel\Http\Stereotype\Controller;
use Flytachi\Winter\Kernel\Route\Annotation\GetMapping;
class MainController extends Controller
{
#[GetMapping]
public function index(): ResponseEntity
{
return ResponseEntity::ok('Hello, Winter');
}
}That is already a working GET / route. The full walkthrough is in the
Quick start.
Three principles
Briefly here, at length in the Philosophy.
Explicit beats implicit. Behaviour lives in the same file as the code it governs: an attribute on a method is the route. Nothing hides in a config file you have to remember to update when you rename something.
CLI instead of boilerplate. call make creates components, call mapping show
prints the routes, call cfg prepares the environment. There is no scaffolding to
copy by hand.
Performance by default. The application boots once and stays in memory; the expensive work — scanning the project, building the container, compiling the route table — happens before the first request rather than on every one.
Coming from Laravel or Symfony?
The concepts carry over — controllers, DI, middleware, repositories — so the code reads at a glance. Two differences are worth noticing immediately: the application does not die after a request, and a service is transient by default, not a singleton. Both are covered in Key concepts.
What it does
| Capability | What it looks like |
|---|---|
| Routing | #[GetMapping], #[PostMapping] on methods; the table builds itself |
| Request binding | #[PathVariable], #[RequestQuery], #[RequestJson], #[RequestForm], #[RequestFile] |
| Validation | #[Valid] plus 24 constraints: #[NotBlank], #[Size], #[Email], #[Uuid]… |
| Database (PPA) | Repositories and entities on attributes, a query builder, migrations from code |
| Container | Autowiring with no registration, three scopes, scope conflicts caught at boot |
| Background work | Processes, supervised daemon fleets, #[Scheduled], parallel #[Async] calls |
Console (call) |
Generators, your own commands, the server, shell completion |
| Observability | Channel-based logging, /actuator health endpoints |
What makes Winter different
Three decisions shape how it feels to work with:
The application is resident. Classic PHP builds its world on every request and tears it down afterwards. Winter starts once and serves requests on coroutines: while one waits on the database, the worker runs another. That is where the speed comes from — and where the new rules about state come from too.
Nothing is registered. At boot the framework walks the project and finds controllers, configurations and processes by itself. Write a class and it works. There are no lists to remember to extend.
The web layer is optional. The same code and the same container run an application with no HTTP at all: a scheduler, a queue, a set of console commands. What the application consists of is decided by one attribute on its entry class.
Where to start
mkdir my-app && cd my-app
composer require flytachi/winter-kernelFrom there it is a few steps to a running server:
- Installation — build the project from scratch and run it
- Quick start — your first route
- Key concepts — how it all fits together
Links
- Kernel: github.com/flytachi/winter-kernel
- Site: winterframe.net