# Result-Type, a Result type implementation for PHP

> Result-Type is a small, MIT-licensed PHP package that implements the result type, so a function can return either a success value or a described failure instead of throwing. The README is thin on usage, so the value of the package is in the pattern it offers rather than in documented features.

**GrahamCampbell/Result-Type** — An implementation of the result type

- Repository: https://github.com/GrahamCampbell/Result-Type
- Website: https://gjcampbell.co.uk
- Stars: 555 · Forks: 11
- Language: PHP
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/grahamcampbell-result-type

## A result type is a return value that carries failure

Result-Type is, as its description says, an implementation of the result type, written in PHP and maintained by Graham Campbell.

The idea behind a result type is simple and it has been implemented in a dozen languages with a dozen names. A function that can fail returns a value that is either a success carrying a payload, or a failure carrying a description of what went wrong. The caller does not read the return value and then find out through an exception that something was wrong; the shape of the return value says whether it worked.

That distinction matters because exceptions and return values express different things. A return value of `false` does not say why it failed, and a return value of `null` cannot be distinguished from a legitimate null result. Exceptions carry a reason but travel as control flow, so a function that throws has to document which of its failure modes are expected and which are bugs, and every caller has to decide whether to catch.

The result type takes the middle position. The failure is data. It can be inspected, matched on, logged, passed around, and returned. The caller has to deal with it, because the compiler and the type system make the failure case part of the contract rather than something that can be forgotten.

What you get in exchange is that a failure cannot be silently dropped. There is no path where a function signals an error and the caller never finds out, because there is no exception to go uncaught and no sentinel to misread as a value.

The package is MIT licensed, it is on Packagist as `graham-campbell/result-type`, and the homepage given for the maintainer is gjcampbell.co.uk. The default branch of the repository is `1.2`, which is a detail worth noting on its own, because it means the maintained line of this package is a version branch rather than `main`.

## What the README actually covers, and what it does not

It is worth being plain about the documentation, because it shapes how you should approach this package.

The README has an installation section, a security section, a licence section and a section pointing at commercial support. That is the whole of it. There is no usage section, no example of constructing a success, no example of matching on a failure, no listing of the classes the package provides, and no description of what the result type looks like in this implementation.

So the API surface is not documented in the repository's front page. The repository layout shows where the answer lives: a `src/` directory with the implementation, a `tests/` directory, a `composer.json`, a `phpunit.xml.dist` for the test configuration, a `CHANGELOG.md` and a `LICENSE`.

That is a small, conventional PHP package layout with no surprises in it, and for a library whose entire job is one data structure, a small layout is expected. But it does mean the adoption cost is reading the source, not reading the documentation, and that is a real difference from the many PHP packages whose README shows a usage block before the licence.

The changelog link is the most useful of the linked documents for a new user, because the README points at it and because in a package this small the changelog is often where behaviour changes are recorded more precisely than a README would manage. The releases page and the security policy are linked in the same paragraph, and the contribution guidelines and code of conduct live under the `.github/` directory.

So the practical approach to evaluating this package is: read `src/` for the shape of the type, read `tests/` for the intended usage patterns, and read `CHANGELOG.md` for the history of the API. The README tells you nothing about any of that, and it would be wrong to pretend otherwise in a review.

## Installation and the PHP version range

The installation instructions are the conventional Composer one, and the version constraint in the command is worth noticing.

```bash
$ composer require "graham-campbell/result-type:^1.1"
```

The `^1.1` constraint means any version in the 1.x series from 1.1 upwards, and since the default branch of the repository is `1.2` and the most recent release is v1.2.0, that constraint resolves to the current line. It also means the constraint does not exclude a 1.1 release, which is the right way to write it if you want to allow the package to float within its major version and be upgraded by `composer update`.

The PHP requirement is stated separately and is wide: this version requires PHP 7.2.5 to 8.6.

That range is the interesting part. It starts at 7.2.5, which is an old PHP 7 patch release, and runs to 8.6, which is beyond the PHP 8 series most people are running today. A library supporting both ends of that span is telling you it does not depend on anything version-specific in the language, which is plausible for a package that implements a small data structure with no platform integration at all.

It also means the package is not a good excuse to pin your runtime. If your application is on PHP 8.1, you can use it, and if you are on PHP 7.2.5 you can too, which is unusual for anything written in the last few years. The cost of that breadth is that the package cannot use newer language features, so you should expect an implementation built from older idioms.

The Composer package name is `graham-campbell/result-type` with a hyphen, and the namespace and class names are the part you will need to look up in the source, since the README does not list them.

## Release cadence and the maintenance signals

The release history shows a package that ships in small increments and often.

The recorded releases are v1.2.0 on 2026-08-24, v1.1.5 on 2026-08-23 and v1.1.4 on 2025-12-27. The release titles follow the package's own convention of carrying the date, so the tags read V1.2.0 (24/08/2026), V1.1.5 (23/08/2026) and V1.1.4 (27/12/2025).

Two things stand out. The 1.1.4 and 1.1.5 releases are a day apart, which is consistent with a patch being released and then a follow-up the next day, a pattern you see with packages where the maintainer fixes something, publishes, and then handles a fallout issue. And the 1.2.0 release came the next day after that, so there was a burst of activity in August 2026, eight months after the previous release.

The last push to the repository was on 2026-08-24, which is the same day as the v1.2.0 release, and the project is not archived. So the branch is in step with the last release rather than carrying unreleased work.

The badges tell you about the tooling. There is a GitHub Actions test workflow, a StyleCI badge for code style, a Packagist downloads badge, a release badge and the MIT licence badge. StyleCI in particular means the style is enforced by a service rather than by a local hook, which for a package with a single maintainer is a sensible way to keep formatting consistent without asking contributors to install anything.

The topics list contains a single entry, `hacktoberfest`, which is a useful signal about the shape of the contribution base: this is a small package that has been used as a Hacktoberfest target, so expect contributions in that tradition, small and scoped, rather than large feature work.

The licensing is MIT, which is permissive and carries no obligation on a commercial user beyond keeping the notice.

## Where a result type fits against the alternatives

The alternatives in PHP are well known and the difference between them is about where the failure lives.

Exceptions are the default. They carry a reason, they can carry a stack trace, and they unwind the stack, which is exactly right for exceptional conditions. The weakness is that they are invisible in the signature, so a caller reading the function definition cannot tell whether it throws, and a library of functions that all throw in some paths is hard to reason about at the call site.

Sentinel return values are the other default. `false`, `null` and `-1` are cheap and universal, and they carry no reason. A caller who needs to know why has to consult an out parameter, read a global, or check a separate status field, and that convention is exactly the kind of thing that decays.

A result type sits between them. The failure is returned, so it is visible in the signature, but it is a value rather than a control-flow event, so it composes: you can return a result from a function that returns a result, and you can match on the failure to convert it into an exception at the boundary where that is the right behaviour.

The cost is honest and worth naming. Every caller has to handle the failure case, and in PHP that handling is not compiler-enforced the way it would be in a language with algebraic data types, because PHP has no sum types. So the result type is a convention with a strong set of types behind it, and it depends on the discipline of the codebase to be used consistently. That is a real difference from languages where the compiler forces the case.

There is also the option of not adding a dependency at all. A project can define its own small result class, which is perhaps fifty lines, and control the naming and the semantics exactly. The argument for using this package is that it is a maintained, tested, versioned implementation of a thing that is easy to get subtly wrong, and that a shared implementation means the same semantics across the codebase.

## The gaps you should expect

Three things a buyer of this package should know before committing to it.

The first is the documentation gap, already covered, and it is the one that will cost you the most time. There is no usage section, so the first hour with this library is spent reading `src/` and `tests/`. For a package this small that is survivable, but it is a real cost and it is the main reason to look at the alternatives before settling on it.

The second is the version branch convention. The default branch is `1.2`, not `main`, and the tags run through 1.2.0. That is a deliberate choice by the maintainer, who publishes version branches for each minor release. It means that when you upgrade, you read the `CHANGELOG.md` and check the branch you are on rather than assuming a single trunk, and it means a patch release can arrive without a minor bump.

The third is the shape of the guarantee in PHP. Because the language has no sum types, a result type in PHP is a set of classes plus a convention. The library can give you well-typed success and failure values, and it can give you combinators that handle them correctly, but it cannot stop a caller from ignoring a returned failure the way it cannot stop a caller from swallowing an exception. Any claim that adopting this makes error handling safe should be read with that in mind.

On support, the README notes that the maintainers of `graham-campbell/result-type` and thousands of other packages work with Tidelift to deliver commercial support and maintenance for open source dependencies, and that this package is available as part of the Tidelift Subscription. That is a real option if your organisation needs a support contract rather than a community, and it is a reminder that the maintenance burden here sits with one person.

For security issues, the README gives a specific address, security@tidelift.com, and says vulnerabilities will be promptly addressed.

## Conclusion

Result-Type suits a PHP codebase that wants failures to be part of a function's signature rather than exceptions thrown at runtime, and it suits a team that wants one small, stable dependency instead of an application framework's error handling. It does not suit a project that expects a documented API, because the README covers installation and licensing only and you will be reading `src/` and `tests/` to learn the surface. Verify first that the PHP version range in your deployment, 7.2.5 to 8.6, covers the interpreter you run, that the release you install is on the `1.2` default branch rather than an older `1.1` line, and that you are willing to change calling conventions across the code that uses the library.

## FAQ

### What is the Result-Type package?

It is a PHP package implementing the result type, so a function can return either a success value or a described failure instead of throwing an exception. It is MIT licensed, maintained by Graham Campbell, and published on Packagist as graham-campbell/result-type.

### How do I install Result-Type?

Require it with Composer: composer require "graham-campbell/result-type:^1.1". The constraint allows any 1.x release from 1.1 upwards, and this version requires PHP 7.2.5 to 8.6.

### Does the Result-Type README show how to use the library?

No. The README covers installation, security reporting, licensing and commercial support, and links to the changelog, the releases, the security policy and the contribution guidelines. The API itself is in the src directory with usage patterns in the tests directory, so you read those rather than a usage section.

### How often is Result-Type released?

The recorded releases are v1.2.0 on 2026-08-24, v1.1.5 on 2026-08-23 and v1.1.4 on 2025-12-27, with the release titles carrying the date. The last push to the repository was on 2026-08-24, the same day as the 1.2.0 release, and the default branch is 1.2.

### What licence is Result-Type under and how do I report a security issue?

It is licensed under the MIT License, with the licence file at the root of the repository. Security vulnerabilities should be emailed to security@tidelift.com, and the project says they will be promptly addressed, with the full policy linked from the README.

## Sources

- [GrahamCampbell/Result-Type on GitHub](https://github.com/GrahamCampbell/Result-Type)
- [License: MIT](https://github.com/GrahamCampbell/Result-Type/blob/1.2/LICENSE)
- [Project website](https://gjcampbell.co.uk)
- [README](https://github.com/GrahamCampbell/Result-Type/blob/1.2/README.md)
- [Releases](https://github.com/GrahamCampbell/Result-Type/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/grahamcampbell-result-type
