{"id":13792157,"url":"https://github.com/aidenybai/pattycake","last_synced_at":"2025-05-15T20:00:45.703Z","repository":{"id":197504754,"uuid":"692520695","full_name":"aidenybai/pattycake","owner":"aidenybai","description":"Zero-runtime pattern matching","archived":false,"fork":false,"pushed_at":"2024-01-29T05:07:21.000Z","size":293,"stargazers_count":839,"open_issues_count":3,"forks_count":8,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-12T17:38:42.151Z","etag":null,"topics":["adt","match","match-with","matching","pattern","pattern-matching","switch","ts-pattern","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aidenybai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-09-16T18:23:43.000Z","updated_at":"2025-05-08T08:18:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"8bdbd2df-5948-4722-84b4-c148b065c77a","html_url":"https://github.com/aidenybai/pattycake","commit_stats":null,"previous_names":["aidenybai/pattycake"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Fpattycake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Fpattycake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Fpattycake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Fpattycake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aidenybai","download_url":"https://codeload.github.com/aidenybai/pattycake/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254414457,"owners_count":22067263,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adt","match","match-with","matching","pattern","pattern-matching","switch","ts-pattern","typescript"],"created_at":"2024-08-03T22:01:08.816Z","updated_at":"2025-05-15T20:00:45.406Z","avatar_url":"https://github.com/aidenybai.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003e ⚠️ Note: this is highly experimental software. Here be dragons 🐉\n\n# 🎂 pattycake\n\n**Zero-runtime pattern matching. (~10-12x faster 🔥)**\n\nPattycake is an optimizing compiler for [ts-pattern](https://github.com/gvergnaud/ts-pattern) that lets you have your cake (expressive pattern matching), and eat it too (zero runtime overhead).\n\n## Install\n\n```bash\nnpm install pattycake\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eNext.js\u003c/summary\u003e\n\n```js\n// next.config.js\nconst pattycake = require('pattycake');\n\nmodule.exports = pattycake.next({\n  // your next.js config\n});\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eVite\u003c/summary\u003e\n\n```js\n// vite.config.js\nimport { defineConfig } from 'vite';\nimport pattycake from 'pattycake';\n\nexport default defineConfig({\n  plugins: [pattycake.vite()],\n});\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eCreate React App\u003c/summary\u003e\n\n```js\nconst pattycake = require('pattycake');\n\nmodule.exports = {\n  webpack: {\n    plugins: { add: [pattycake.webpack()] },\n  },\n};\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eWebpack\u003c/summary\u003e\n\n```js\nconst pattycake = require('pattycake');\n\nmodule.exports = {\n  plugins: [pattycake.webpack()],\n};\n```\n\n\u003c/details\u003e\n\n## About\n\n`ts-pattern` is a great library that brings the ergonomics of pattern matching from languages like Rust and OCaml to Typescript, but at the cost of being orders of magnitude slower.\n\n`pattycake` compiles ts-pattern's `match()` expressions into an optimized chain of if statements to completely eliminate that cost. In our initial benchmarks, it outperforms `ts-pattern` by usually ~10-12x.\n\nIn essence, `pattycake` converts a `ts-pattern` `match()` expression like this:\n\n```typescript\nlet html = match(result)\n  .with(\n    { type: 'error', error: { foo: [1, 2] }, nice: '' },\n    () =\u003e '\u003cp\u003eOups! An error occured\u003c/p\u003e',\n  )\n  .with({ type: 'ok', data: { type: 'text' } }, function (data) {\n    return '\u003cp\u003e420\u003c/p\u003e';\n  })\n  .with(\n    { type: 'ok', data: { type: 'img', src: 'hi' } },\n    (src) =\u003e `\u003cimg src=${src} /\u003e`,\n  )\n  .otherwise(() =\u003e 'idk bro');\n```\n\nInto this:\n\n```typescript\nlet html;\nout: {\n  if (\n    result.type === 'error' \u0026\u0026\n    Array.isArray(result.error.foo) \u0026\u0026\n    result.error.foo.length \u003e= 2 \u0026\u0026\n    result.error.foo[0] === 1 \u0026\u0026\n    result.error.foo[1] === 2\n  ) {\n    html = '\u003cp\u003eOups! An error occured\u003c/p\u003e';\n    break out;\n  }\n  if (result.type === 'ok' \u0026\u0026 result.data.type === 'text') {\n    let data = result;\n    html = '\u003cp\u003e420\u003c/p\u003e';\n    break out;\n  }\n  if (\n    result.type === 'ok' \u0026\u0026\n    result.data.type === 'img' \u0026\u0026\n    result.data.src === 'hi'\n  ) {\n    let src = result;\n    html = `\u003cimg src=${src} /\u003e`;\n    break out;\n  }\n  html = 'idk bro';\n  break out;\n}\n```\n\n## Feature parity with ts-pattern\n\n- [x] [Literal patterns](https://github.com/gvergnaud/ts-pattern#literals)\n  - [x] string\n  - [x] number\n  - [x] booleans\n  - [x] bigint\n  - [x] undefined\n  - [x] null\n  - [x] NaN\n- [x] [Object patterns](https://github.com/gvergnaud/ts-pattern#objects)\n- [x] [Array/tuples patterns](https://github.com/gvergnaud/ts-pattern#tuples-arrays)\n- [ ] `.when()`\n- [ ] [Wildcards](https://github.com/gvergnaud/ts-pattern#wildcards) patterns\n  - [x] `P._`\n  - [x] `P.string`\n  - [x] `P.number`\n- [ ] Special matcher functions\n  - [ ] `P.not`\n  - [ ] `P.when`\n  - [x] `P.select`\n  - [ ] `P.array`\n  - [ ] `P.map`\n  - [ ] `P.set`\n\n## Notes\n\n### Fallback / compatibility with `ts-pattern`\n\nIf `pattycake` is unable to optimize a `match()` expression, it will fallback to using `ts-pattern`. This is enabled right now because we don't support the full feature set of ts-pattern.\n\n### Inlining handlers\n\nOne performance problem of `ts-pattern`'s are handler functions:\n\n```typescript\nmatch(foo)\n  .with({ foo: 'bar' }, () =\u003e /* this is a handler function */)\n  .with({ foo: 'baz' }, () =\u003e /* another one */)\n```\n\nFunction calls usually have an overhead, and a lot of the time these handlers are small little functions (e.g. `(result) =\u003e result + 1`) which can be much faster if just directly inlined in the code.\n\nAdditionally, a `match()` with many branches means creating a lot of function objects in the runtime.\n\nThe JIT-compiler and optimizer in JS engines can do inlining of functions, but in general with JIT you need to run your code several times or it to determine what to optimize.\n\nSo when possible, `pattycake` will try to inline function expression (anonymous functions / arrow functions) handlers directly into the code if it is small.\n\n### IIFEs\n\nWhen possible, `pattycake` will try to generate a block of code (like in the example above). But there are times where this is not possible without breaking the semantics of source code.\n\n## Roadmap\n\nRight now, the goal is to support the full feature set of ts-pattern, or at least a sufficient amount. After, the ideal is\nthat we compile pattern matching expressions into code that would be faster than what you would write by hand.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidenybai%2Fpattycake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faidenybai%2Fpattycake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidenybai%2Fpattycake/lists"}