# boxed: Option, Result and Future types for TypeScript

> boxed is a small TypeScript library of functional building blocks, offering Option, Result, Future, AsyncData, Lazy and a few container utilities with an immutable, chainable API. It ships no runtime dependency and interoperates with native JavaScript values.

**bloodyowl/boxed** — Essential building-blocks for functional & safe TypeScript code

- Repository: https://github.com/bloodyowl/boxed
- Website: https://boxed.cool/
- Stars: 767 · Forks: 26
- Language: TypeScript
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/bloodyowl-boxed

## What the library is made of

boxed provides essential building blocks, in the form of types and functions, so you can write functional and safe TypeScript code. The description on the npm package is utility types for functional TypeScript, and the author is Matthias Le Brun.

The contents are listed explicitly. Option<Value> for a value that may not be there. Result<Ok, Error> for an operation that may have failed. Future<Value> for a value that will arrive later. AsyncData<Value> for a value with a loading state. Lazy<Value> for a deferred computation. And then some utilities, Deferred, Dict and Array.

That is a small surface, and the size is the point. The package has no runtime dependencies at all, and the only peer dependency is TypeScript itself, listed as optional with a version of 5.0.0 or above. The published files are the licence, the dist directory and the README, so what you install is the library and nothing else.

The version is 3.4.0, and the package is published publicly to the npm registry.

The repository also carries a benchmark/ directory, a docs/ directory that backs the boxed.cool documentation site, a HISTORY.md changelog, and a src/ plus test/ layout. The test and type-check configuration is split across three tsconfig files, one for the main build, one for CommonJS and one for the tests.

## The five design principles and what they commit you to

The README lists five principles, and they are worth reading as a contract rather than as a list of virtues.

The first is to provide utility types that make data manipulation and storage easier. The second is immutability, and the README notes that all the provided types are immutable. The third is a good development experience, which it unpacks as a chaining API and reliable types. The fourth is simple interoperability, meaning you can convert back and forth to JavaScript native types. The fifth is compatibility with ts-pattern, using the patterns the library provides.

Each of those has a cost that the principle does not mention, and the costs are what a reader should weigh.

Immutability means every operation returns a new value, which is what makes the types safe but also means hot paths allocate. The chaining API is what makes the code readable but it is also a second method vocabulary to learn on top of the language's own. Interoperability is what lets you get data out of the library and back into plain JavaScript, and it is also the escape hatch that lets a team drift back to nullable values one call at a time.

The ts-pattern compatibility is the most interesting, because it means boxed is not asking to be the only way you match on values. The dev dependencies list ts-pattern at a version 5 release, and the library provides the patterns for it, so the two work together rather than competing.

## Installing the package

The package is on npm under the scoped name, and the README gives both package managers.

```bash
$ yarn add @bloodyowl/boxed
# --- or ---
$ npm install --save @bloodyowl/boxed
```

The scoped name is the one thing to note. @bloodyowl/boxed is a scope the author controls, so installing it requires your npm configuration to permit that scope, which is the default for public packages but matters in a locked-down corporate registry setup.

The bundle size is tracked with a bundlephobia badge in the README, which is a reasonable proxy for a library with no runtime dependencies. The README does not quote a figure, so check it on bundlephobia before committing to it in a size-sensitive bundle.

The documentation lives at boxed.cool, and the licence is MIT with the file in the repository root.

## The build, the type checking and the benchmark harness

The package scripts show how the library is produced, and they are small enough to read as a whole.

```json
    "build": "yarn clean && tsc && tsc -p tsconfig.cjs.json",
    "typecheck": "tsc --noEmit",
    "prepack": "bun test && bun run build",
```

The build cleans the dist directory, compiles with the main tsconfig and then compiles again with the CommonJS config, which is how the package ends up with both an ESM entry point at dist/src/Boxed.js and a CommonJS one at dist/cjs/src/Boxed.js, each with its own type declarations. The prepack script is the important one for a consumer: it runs the test suite with bun and then builds, so a published tarball cannot be produced without the tests having passed.

Type checking is a separate script using tsc with noEmit, and there is a second one scoped to the test configuration, so the test files are type checked under their own settings rather than the library's.

The benchmark script is the interesting part for judging the performance claims.

```json
    "benchmark": "node benchmark/src/option && node benchmark/src/result && node benchmark/src/future && node benchmark/src/future-result"
```

Four separate benchmark programs, one each for Option, Result, Future and the Future plus Result combination, run in sequence. The benchmark/ directory holds them, and the dev dependencies include the benchmark package with its type definitions. No results are quoted in the README, so the numbers are something you have to generate for your own target.

The dev dependencies also list effect and fp-ts, which tells you the author benchmarked against the two major functional TypeScript libraries rather than only against a hand-rolled baseline.

## Where boxed is the wrong choice

The first limitation is that the library is small on purpose, which means it is not a framework. There is no error type hierarchy to speak of, no context propagation, no tracing, no scheduling abstraction and no effect system. The README promises building blocks, and that is exactly what you get. A team that needs those things should be looking at Effect or fp-ts, and the dev dependencies confirm the author knew the comparison.

The second is the second-library problem. If your organisation has already standardised on Effect or fp-ts, adding boxed means two idioms of monad handling in one codebase, and the more trained one usually wins, leaving boxed as a second way of doing the same thing. That is a maintenance cost with no offsetting benefit unless the team genuinely wants to avoid the larger dependency.

The third is immutability cost. Every transformation allocates. For a library used in a data-processing hot path rather than at the edges of an application, that is a real cost, and the benchmark harness is there precisely because the author expected the question.

The fourth is that the type-level story depends on the TypeScript version. The peer dependency is TypeScript 5.0.0 or above, and the dev dependencies use TypeScript 6. The library leans on inference, and inference is where TypeScript changes between versions most, so a future compiler release can change how the chaining API resolves even when the library itself has not changed.

The fifth is release cadence and versioning signals. The package version is 3.4.0, there are no GitHub releases, and the last push to the repository was on 2026-09-14. The HISTORY.md changelog is the version history, and a library at 3.x with a changelog rather than tags is a project to watch rather than to hard-depend on without pinning.

## Licence, maintenance and the cost of adopting it

The project is under the MIT licence, with the LICENSE file at the root of the repository and the same declared in the package metadata. The author is Matthias Le Brun, and the homepage is boxed.cool.

The repository is not archived and the last push was on 2026-09-14, so the code is being worked on. The CHANGELOG is the file named HISTORY.md, and the version numbers follow semantic versioning with the 3.x line current.

The dependency cost is the standout. A library with no runtime dependencies and a single optional peer dependency on the compiler itself adds essentially nothing to a bundle and nothing to a vulnerability scan beyond the package itself. That is a genuine advantage over the larger functional libraries, and for a codebase that only needs Option and Result, it is probably the deciding factor.

The other cost is conceptual, and it is the one to weigh before adopting. Introducing Option and Result is not a mechanical refactor. Every call site that previously returned a nullable value now has to handle the absence case, and a codebase that adopts these types in the middle of a project ends up with three ways of expressing the same idea until the old paths are removed. The library is small enough to try in one module, which is the sensible way to evaluate it.

## Conclusion

boxed suits a TypeScript team that wants the Option and Result pattern with a small dependency footprint and a chainable API, since it adds no runtime code beyond its own types and functions. It does not suit a codebase already standardised on Effect or fp-ts, since two functional libraries in one project is a cost of its own. Verify the TypeScript version first, at 5.0 or above, and check whether the ts-pattern compatibility in the design principles is something you actually want to depend on.

## FAQ

### How do I install boxed?

Install the scoped package with yarn add @bloodyowl/boxed or npm install --save @bloodyowl/boxed. The package has no runtime dependencies and its only peer dependency is TypeScript, listed as optional and requiring version 5.0.0 or above.

### What types does the boxed library provide?

The README lists Option<Value>, Result<Ok, Error>, Future<Value>, AsyncData<Value> and Lazy<Value>, plus utilities named Deferred, Dict and Array. The library describes itself as essential building blocks for functional and safe TypeScript code.

### Does boxed work with ts-pattern?

Yes. Compatibility with ts-pattern is one of the five design principles in the README, using the patterns the library provides, and ts-pattern appears in the dev dependencies at a version 5 release.

### How is the boxed package built and tested?

The build script cleans the dist directory and compiles twice, once for ESM and once for CommonJS with separate type declarations. The prepack script runs the test suite with bun and then the build, so a published tarball cannot be produced without the tests passing, and a separate script type checks the test configuration.

## Sources

- [bloodyowl/boxed on GitHub](https://github.com/bloodyowl/boxed)
- [Issues](https://github.com/bloodyowl/boxed/issues)
- [License: MIT](https://github.com/bloodyowl/boxed/blob/main/LICENSE)
- [Project website](https://boxed.cool/)
- [README](https://github.com/bloodyowl/boxed/blob/main/README.md)

---

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