jbboehr / yumemi
Static dimensional analysis for PHPStan, backed by a runtime unit-conversion engine for PHP.
Requires
- php: ^8.2
- ext-gmp: *
- doctrine/lexer: ^3.0
- symfony/polyfill-php84: ^1.34
Requires (Dev)
- ext-dom: *
- brick/varexporter: ^0.6
- friendsofphp/php-cs-fixer: ^3
- infection/infection: ^0.32.6
- jbboehr/phpbench-perfidious: dev-develop
- mrsuh/php-bison-skeleton: ^1.2
- phpbench/phpbench: ^1.7
- phpstan/phpstan: ^2.1
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^11.5
Suggests
- illuminate/cache: Enables optional unit-aware cache, lock, and rate-limiter stubs through yumemi-tags.neon (Laravel 11-13).
- illuminate/http: Enables optional unit-aware HTTP client and fake-upload stubs through yumemi-tags.neon (Laravel 11-13).
- phpstan/phpstan: Enables the bundled Yumemi unit types extension (extension.neon; develop against PHPStan 2.x).
This package is auto-updated.
Last update: 2026-08-03 07:07:17 UTC
README
Yumemi
PHP ordinarily treats meters, feet, and seconds as interchangeable numbers. Yumemi provides static dimensional
analysis for PHPStan on ordinary int and float values, backed by a runtime unit engine for exact rational
conversion and quantity arithmetic.
The PHPStan extension catches incompatible units without requiring runtime wrapper objects. When an application needs
real conversion, the runtime library supplies Units, exact Quantity values, and affine PointQuantity coordinates.
Both layers share one parser, unit catalog, normalization engine, and meaning for expressions such as meter / second.
Status: the PHPStan extension and runtime library are usable, but Yumemi does not yet have a tagged stable release.
Installation
Yumemi requires PHP 8.2 or later and the GMP extension. Until the first tagged release, install the development branch:
composer require jbboehr/yumemi:dev-master
Applications using the extension must install PHPStan separately as a development dependency:
composer require --dev phpstan/phpstan:^2.1
When phpstan/extension-installer is also installed as a development
dependency, Yumemi's primary PHPStan extension is registered automatically. Otherwise, include it from phpstan.neon:
includes: - vendor/jbboehr/yumemi/extension.neon
Keep Yumemi as a normal dependency when application code calls its runtime functions or classes. Static-analysis-only
projects with no runtime Yumemi usage may install it with --dev instead.
The extension-optional @yumemi-* annotation integration is deliberately opt-in. See
Extension-Optional Annotations for configuration and
tradeoffs.
Static Analysis
Use unit() to brand an ordinary native magnitude. PHPStan then propagates its unit through arithmetic while runtime
behavior remains unchanged:
<?php require 'vendor/autoload.php'; use function jbboehr\Yumemi\unit; /** @param unit_float<'meter / second'> $speed */ function storeTelemetrySpeed(float $speed): void {} $distance = unit(100.0, 'meter'); $elapsed = unit(10.0, 'second'); storeTelemetrySpeed($distance / $elapsed); //! expects unit_float<'meter / second'>, unit_float<'meter * second'> given storeTelemetrySpeed($distance * $elapsed); assert($distance / $elapsed === 10.0);
A //! comment records part of the PHPStan diagnostic expected on the following line in Yumemi's tested documentation.
It is documentation-test notation, not Yumemi syntax.
unit_int<'...'> and unit_float<'...'> work in ordinary PHPDoc positions. Yumemi also models runtime objects as
Quantity<'unit'> and coordinate points as PointQuantity<'unit'>, preserving their units through supported
arithmetic, conversion, and native extraction.
Runtime Conversion
Use Units and Quantity when the program must perform a conversion or retain an exact rational magnitude.
PointQuantity separately represents exact coordinates on affine scales such as Celsius:
<?php require 'vendor/autoload.php'; use jbboehr\Yumemi\Units; $length = Units::default()->quantity(1, 'foot')->to('meter'); assert($length->exactDecimalValueIn('meter') === '0.3048'); assert($length->unitToString() === 'meter');
Quantity arithmetic distinguishes symbolic reduction from catalog conversion. Addition, subtraction, and comparisons
convert compatible operands exactly; multiplication and division reduce the caller's chosen units. Explicit
normalize() and simplify() operations control definition substitution. PointQuantity conversion and comparison
apply affine offsets, point subtraction returns a multiplicative difference, and compatible quantities translate points.
Documentation
- Getting Started covers installation and the shortest complete examples.
- Core Concepts helps choose among branded native values, exact quantities, and coordinate points, then directs each operation to its authoritative reference.
- Recipes provides task-oriented examples for common integration and conversion workflows.
- PHPStan Reference defines branded types, operators, conversion helpers, generic quantities, configuration, optional annotations, diagnostics, and limitations.
- Unit Syntax defines expressions, name resolution, Unicode forms, and errors.
- Runtime Reference documents exact conversion, quantity and point arithmetic, native output, dimensions, formatting, and string forms.
- Built-in and Custom Units documents UDUNITS2 data, introspection, custom registries, and semantic capabilities.
Architecture, implementation status, and deferred work are tracked in the planning document. The broader feature comparison is in Pint parity.
License
Yumemi is licensed under the GNU Affero General Public License version 3 with the Romic Exception:
AGPL-3.0-only WITH romic-exception
The Romic Exception permits Yumemi to be linked or combined with other code without subjecting that other code to the AGPL merely because of the linking or combination. Modifications to the covered project remain subject to the Project License, including its source-availability requirements for modified versions made available over a computer network.
See LICENSE.md and docs/LICENSE_EXCEPTION.md for the complete terms. The generated UDUNITS2 catalog and portions of the parser grammar incorporate material under the UCAR License; see docs/UDUNITS-COPYRIGHT.
Contributions are accepted under the terms in CONTRIBUTING.md. Unless a contributor elects the CLA
route, each contribution is offered under AGPL-3.0-only WITH romic-exception OR Apache-2.0, at each recipient's
option, while the public project incorporates it under the Project License. The Apache-2.0 alternative applies only to
the contributor-authored portions and does not make the project as a whole available under Apache-2.0.
A contributor may instead elect the CLA, keeping the contribution publicly under the Project License while granting the Project Steward the additional rights specified there.
Alternative commercial licenses may be available from the Project Steward. Contact John Boehr at jbboehr@gmail.com.
