From 7a1eaa0d7fbefecd6f74d5302d5f345e93fc5c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Fri, 25 Sep 2026 22:21:50 +0000 Subject: [PATCH] :memo: Add an alternatives section Add a short README section under Alternatives, one heading per alternative (ts-pattern, Effect.Match, match-iz and plain switch), each saying what it is and what tiny-pattern-ts is or does differently. State the data-last, pipe-friendly shape in Description. - measure the footprint: ~0.2 kB minified + gzipped, not the unminified ~1.8 kB; ts-pattern is ~2 kB - correct match-iz: it ships types, it just cannot prove exhaustiveness - drop switchcase / ts-match (unmaintained) - check off the backlog task Resolves: backlog "Add comparison section vs. other TS pattern-matching libs" --- README.md | 41 ++++++++++++++++++++++++++++++++++++++++- backlog.tasks | 6 +++--- cspell.json | 3 ++- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 613224b..4fdd146 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,9 @@ assert.equal(phoneOutput, "PHONE: +1 555 0100"); The main goal of `tiny-pattern-ts` is to make pattern matching type-safe with a lean syntax. This is accomplished by being exhaustive and passing typed parameters per branch to the handlers — supported by an outstanding -autocomplete and a tiny footprint. +autocomplete and a tiny footprint. The matchers are data last and pipe-friendly: +build the handler map once, then apply the resulting matcher to values +(`match(value)`, or `pipe(value, match)`). See [development/library.md](./development/library.md) for the design decisions and [Caveats](#caveats) for the limits. @@ -284,6 +286,43 @@ provable exhaustiveness — to automate what a `switch` and a default arm alread cover. The type-level cost of supporting open universes is recorded in [development/library.md](./development/library.md#supported-universes). +## Alternatives + +### [`ts-pattern`](https://github.com/gvergnaud/ts-pattern) + +- is the full structural matcher — nested and partial patterns, guards, unions, + captures — exhausting at `.exhaustive()` +- has a fluent `.with(…)` chain that is heavy on syntax; tiny-pattern-ts is one + handler map +- is about 2 kB minified and gzipped; tiny-pattern-ts is 0.2 kB +- reach for it when you need a feature tiny-pattern-ts does not cover + +### [Effect's `Match`](https://effect.website/docs/code-style/pattern-matching/) + +- is the same piped matcher (`Match.type` / `Match.when` / `Match.exhaustive`), + but only as part of the `effect` ecosystem +- tiny-pattern-ts is standalone: no runtime dependency to buy into + +### [`match-iz`](https://github.com/shuckster/match-iz) + +- expresses patterns in the TC39 proposal's style, deciding each case at runtime +- is written in JavaScript with hand-maintained declarations, so its types do + not prove the cases exhaustive +- tiny-pattern-ts does: exhaustiveness is a compile-time guarantee, not an + `otherwise` fallback + +### plain `switch` (baseline) + +- is the zero-dependency baseline — pair it with + [`eslint-plugin-strict-pattern-matching`](https://www.npmjs.com/package/eslint-plugin-strict-pattern-matching) + for exhaustiveness +- is a statement, not an expression, so it cannot produce a value directly +- leaves the `never` guard to you; tiny-pattern-ts is an expression and does not + need one + +The [TC39 pattern-matching proposal](https://github.com/tc39/proposal-pattern-matching) +is still stage 1, so userland libraries remain the only option today. + ## License MIT © 2026 tmu. See [LICENSE](./LICENSE). diff --git a/backlog.tasks b/backlog.tasks index c91945d..17b88a8 100644 --- a/backlog.tasks +++ b/backlog.tasks @@ -27,9 +27,9 @@ Documentation: → previous section order: title, tagline, Synopsis, Description, Requirements, Examples, API, License, Contributing → previous Examples order: literal/exhaustive, typeof, structural/discriminated unions, when, any ☐ Create `examples/` directory with runnable snippets -☐ Add comparison section vs. other TS pattern-matching libs in Readme.md - ☐ Why do we do this? => exhaustiveness encoded type safe - ☐ Why this form? little syntax, data last, very small, autocomplete, strict typing in the handler; for more features use ts-pattern +✔ Add comparison section vs. other TS pattern-matching libs in Readme.md @done + ✔ Why do we do this? => exhaustiveness encoded type safe @done + ✔ Why this form? little syntax, data last, very small, autocomplete, strict typing in the handler; for more features use ts-pattern @done ✔ Write migration guide for users coming from discriminated unions @done (9/24/2026, 10:21:17 PM) ✔ Create backlog tasks for implementation @done (9/24/2026, 10:21:16 PM) ✔ Validate code fences in Markdown (start with README.md) — compile the TypeScript examples against `src/` so the docs cannot drift from the API @done diff --git a/cspell.json b/cspell.json index 35b7457..ef19897 100644 --- a/cspell.json +++ b/cspell.json @@ -45,7 +45,8 @@ "todotasks", "connor", "injective", - "injectivity" + "injectivity", + "userland" ], "ignorePaths": ["dist", "node_modules", "coverage", "*.svg", ".gitignore"] }