...

True Myth

Safe and idiomatic TypeScript types to handle null, error, and async code handling: Maybe, Result, and Task types that are really nice.
github-icon
GitHub
1.24kstar-icon
Created 8 years ago, last commit 15 hours ago
25 contributors
2.23k commits
Stars added on GitHub, month by month
8
9
10
11
12
1
2
3
4
5
6
7
2024
2025
Stars added on GitHub, per day, on average
Yesterday
+1star-icon
Last week
+0.4
star-icon /day
Last month
+0.5
star-icon /day
Last 12 months
+0.7
star-icon /day
npmPackage on NPM
Monthly downloads on NPM
8
9
10
11
12
1
2
3
4
5
6
7
2024
2025
No dependencies
README

True Myth provides safe, idiomatic null, error, and async code handling in TypeScript, with Maybe, Result, and Task types that are really nice.

Test coverage: 100% npm supported Node versions supported TypeScript versions Nightly TypeScript Run Stability: Active DNS by JS.org docs built with Typedoc

READMEAPI docsSourceIntro blog post

Overview

True Myth provides standard, type-safe wrappers and helper functions to help you with three extremely common cases in programming:

  • not having a value
  • having a result where you need to deal with either success or failure
  • having an asynchronous operation which may fail

You could implement all of these yourself – it's not hard! – but it's much easier to just have one extremely well-tested library you can use everywhere to solve this problem once and for all.

See the docs for setup, guides, and API docs!

Contents

Requirements

  • Node 20+
  • TS 5.3+
  • tsconfig.json:
    • moduleResolution: use "Node16" or later
    • strict: true
  • package.json
    • type: "module" (or else use import() to import True Myth into a commonJS build)

For details on using a pure ES modules package in TypeScript, see the TypeScript handbook's guide.

Compatibility

This project follows the current draft of the Semantic Versioning for TypeScript Types specification.

  • Currently supported TypeScript versions: 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, and 5.9
  • Compiler support policy: simple majors
  • Public API: all published, documented types not in a -private module and not marked as @internal or @private are public

Basic bundle size info

Size of the ESM build without tree-shaking (yes, these are in bytes: this is a pretty small library!):

file size (B) terser1 (B) terser and brotli2 (B)
-private/utils.js 888 321 166
index.js 644 352 122
maybe.js 18872 3637 908
result.js 15274 3927 972
standard-schema.js 5975 762 317
task/delay.js 3901 649 259
task.js 54755 7448 2025
test-support.js 473 142 89
toolbelt.js 3739 890 277
unit.js 656 58 57
total3 105177 18186 5192

Notes:

  • The unmodified size includes comments.

  • Thus, running through Terser gets us a much more realistic size: about 18.1KB to parse.

  • The total size across the wire of the whole library will be ~5.2KB.

  • This is all tree-shakeable to a significant degree: you should only have to “pay for” the types and functions you actually use, directly or indirectly. If your production bundle does not import or use anything from true-myth/test-support, you will not pay for it, for example. However, some parts of the library do depend directly on other parts: for example, toolbelt uses exports from result and maybe, and Task makes extensive use of Result under the hood.

    In detail, here are the dependencies of each module:

    Module Depends on
    index.js All, but as tree-shakeable as possible
    maybe.js unit.js, -private/utils.js
    result.js unit.js, -private/utils.js
    standard-schema.js task.js, result.js
    task.js result.js, unit.js, task/delay.js, -private/utils.js
    task/delay.js None
    test-support.js maybe.js, result.js
    toolbelt.js maybe.js, result.js, -private/utils.js

Inspiration

The design of True Myth draws heavily on prior art; essentially nothing of this is original – perhaps excepting the choice to make Maybe.of handle null and undefined in constructing the types. In particular, however, True Myth draws particular inspiration from:

Footnotes

  1. Using terser 5.37.0 with --compress --mangle --mangle-props.

  2. Generated by running gzip -kq11 on the result of the terser invocation.

  3. This is just the sum of the previous lines. Real-world bundle size is a function of what you actually use, how your bundler handles tree-shaking, and how the results of bundling compresses. Notice that sufficiently small files can end up larger after compression; this stops being an issue once part of a bundle.