{"id":13829000,"url":"https://github.com/alexandercerutti/passkit-generator","last_synced_at":"2025-04-29T18:49:29.581Z","repository":{"id":32978733,"uuid":"148533121","full_name":"alexandercerutti/passkit-generator","owner":"alexandercerutti","description":"The easiest way to generate custom Apple Wallet passes in Node.js","archived":false,"fork":false,"pushed_at":"2025-01-19T23:26:40.000Z","size":4868,"stargazers_count":1027,"open_issues_count":1,"forks_count":119,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-04-27T12:23:14.077Z","etag":null,"topics":["apple","apple-pass","apple-passkit","apple-wallet","ios","pass","passkit","wallet"],"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/alexandercerutti.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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,"publiccode":null,"codemeta":null},"funding":{"open_collective":"passkit-generator"}},"created_at":"2018-09-12T19:45:00.000Z","updated_at":"2025-04-27T07:22:22.000Z","dependencies_parsed_at":"2023-11-26T13:16:28.601Z","dependency_job_id":"9d9d5c36-7904-49e8-bdfa-d9ff77d36062","html_url":"https://github.com/alexandercerutti/passkit-generator","commit_stats":{"total_commits":929,"total_committers":20,"mean_commits":46.45,"dds":"0.038751345532830994","last_synced_commit":"bab4117cb029b00a50077262187fcc2ad9412357"},"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandercerutti%2Fpasskit-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandercerutti%2Fpasskit-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandercerutti%2Fpasskit-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandercerutti%2Fpasskit-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexandercerutti","download_url":"https://codeload.github.com/alexandercerutti/passkit-generator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251564100,"owners_count":21609844,"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":["apple","apple-pass","apple-passkit","apple-wallet","ios","pass","passkit","wallet"],"created_at":"2024-08-04T09:03:26.082Z","updated_at":"2025-04-29T18:49:29.565Z","avatar_url":"https://github.com/alexandercerutti.png","language":"TypeScript","funding_links":["https://opencollective.com/passkit-generator","https://opencollective.com/passkit-generator/contribute","https://opencollective.com/passkit-generator/organization/0/website","https://opencollective.com/passkit-generator/organization/1/website","https://opencollective.com/passkit-generator/organization/2/website","https://opencollective.com/passkit-generator/organization/3/website","https://opencollective.com/passkit-generator/organization/4/website","https://opencollective.com/passkit-generator/organization/5/website","https://opencollective.com/passkit-generator/organization/6/website","https://opencollective.com/passkit-generator/organization/7/website","https://opencollective.com/passkit-generator/organization/8/website","https://opencollective.com/passkit-generator/organization/9/website"],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\t\u003cbr\u003e\n\t\u003cbr\u003e\n\t\u003cpicture\u003e\n\t\t\u003csource media=\"(prefers-color-scheme: dark)\"\n\t\t\tsrcset=\"https://github.com/alexandercerutti/passkit-generator/raw/master/assets/logo-dark.svg?sanitize=true\"\n\t\t\twidth=\"600\"\n\t\t\u003e\n\t\t\u003cimg\n\t\t\twidth=\"600\"\n\t\t\talt=\"Passkit-generator logo for light mode\"\n\t\t\tsrc=\"https://github.com/alexandercerutti/passkit-generator/raw/master/assets/logo-light.svg?sanitize=true\"\n\t\t\u003e\n\t\u003c/picture\u003e\n\t\u003cbr\u003e\n\t\u003cbr\u003e\n\t\u003cp align=\"center\"\u003eSimple Node.js interface to generate customized \u003ca href=\"https://developer.apple.com/wallet/\"\u003eApple Wallet Passes\u003c/a\u003e for iOS and WatchOS.\u003c/p\u003e\n\n![](https://img.shields.io/npm/v/passkit-generator.svg?label=passkit-generator)\n![](https://img.shields.io/node/v/passkit-generator.svg)\n\u003cbr\u003e\n[![Financial Contributors on Open Collective](https://opencollective.com/passkit-generator/all/badge.svg?label=financial+contributors)](https://opencollective.com/passkit-generator)\n\n\u003c/div\u003e\n\u003cbr\u003e\n\n## Architecture\n\nThis library was created with a specific architecture in mind: **application** and **model** (as preprocessed entity), to split as much as possible static objects (such as logo, background, icon, etc.) from dynamic ones (translations, barcodes, serialNumber, ...), while keeping an eye on the different possible execution contexts.\n\nPass creation and population might not fully happen in runtime. This library allows to create a pass from scratch, specify a folder model (template) or specify a set of buffers. In the last two cases, both should contain all the objects needed (static medias) and structure to make a pass work.\n\nWhenever adding files, through scratch, template or buffer, these will be read and pushed as they are in the resulting .zip file, while dynamic data will be patched (`pass.json` with props) or generated in runtime (`manifest.json`, `signature` and translation files).\n\n### Installation\n\n```sh\n$ npm install passkit-generator --save\n```\n\n---\n\n### API Documentation\n\nThis package comes with an [API Documentation Reference](https://github.com/alexandercerutti/passkit-generator/wiki/API-Documentation-Reference), available in wiki, that makes available a series of methods to create and customize passes.\n\n---\n\n### Looking for the previous major version?\n\nCheck the [v2 tag](https://github.com/alexandercerutti/passkit-generator/tree/v2.0.8). That tag is kept for reference only.\n\n---\n\n### Coming from the previous major version?\n\nLook at the [Migration Guide](https://github.com/alexandercerutti/passkit-generator/wiki/Migrating-from-v2-to-v3).\n\n---\n\n### Integrating Apple Wallet Web services?\n\nGive a look at another library I made: [Passkit Webservice Toolkit](https://github.com/alexandercerutti/passkit-webservice-toolkit) and its integrations!\n\n---\n\n## Getting Started\n\n##### Model\n\nAssuming that you don't have a model yet, the first thing you'll have to do, is creating one. A model contains all the basic pass data that compose the Pass identity.\nThese data can be files (icon, thumbnails, ...), or pieces of information to be written in `pass.json` (Pass type identifier, Team Identifier, colors, ...) and whatever you know that likely won't be customized on runtime.\n\nWhen starting from zero, the best suggested solution is to use a Template (folder) to start with, as it will allow an easier access to all the files and data. Nothing will prevent you using a buffer model or creating a pass from scratch, but they are meant for an advanced usage or different contexts (e.g. running a cloud function might require a scratch model for faster startup, without storing the model in a \"data bucket\").\n\nLet's suppose you have a file `model.zip` stored somewhere: you unzip it in runtime and then get the access to its files as buffers. Those buffers should be available for the rest of your application run-time and you shouldn't be in need to read them every time you are going to create a pass.\n\n**To maintain a pass model available during the run-time, a PKPass instance can be created from whatever source, and then used as a template through `PKPass.from`**.\n\n\u003e Using the .pass extension is a best practice, showing that the directory is a pass package.\n\u003e ([Build your first pass - Apple Developer Portal](https://apple.co/2LYXWo3)).\n\nFollowing to this best practice, the package is set to **require** each folder-model to have a **_.pass_** extension.\n\nIf omitted in the configuration (as in [Usage Example](#usage_example) below), it will be forcefully added, possibly resulting in a folder reading error, if your model folder doesn't have it.\n\n---\n\nModel creation can be performed both manually or with the auxiliary of a web tool I developed, [Passkit Visual Designer](https://pkvd.app), which will let you design your model through a neat user interface.\nIt will output a .zip file that you can decompress and use as source.\n\n---\n\nYou can follow [_Create the Directory and add Files for the Pass_](https://apple.co/3zumjFI) at Apple Developer to build a correct pass model. The **icon is required** in order to make the pass work. Omitting an icon resolution, might make a pass work on a device (e.g. Mac) but not on another (e.g. iPhone). _Manifest.json_ and _signature_ will be automatically ignored from the model and generated in runtime.\n\nYou can also create `.lproj` folders (e.g. _en.lproj_ or _it.lproj_) containing localized media. To include a folder or translate texts inside the pass, please refer to [Localizing Passes](https://github.com/alexandercerutti/passkit-generator/wiki/API-Documentation-Reference#localizing-passes) in the wiki API documentation.\n\nTo include a file that belongs to an `.lproj` folder in buffers, you'll just have to name a key like `en.lproj/thumbnail.png`.\n\n##### Pass.json\n\nCreate a `pass.json` by taking example from examples folder models or the one provided by Apple for the [first tutorial](https://apple.co/2NA2nus) and fill it with the basic informations, that are `teamIdentifier`, `passTypeIdentifier` and all the other basic keys like pass type. Please refer to [Pass interface documentation on Apple Developers](https://apple.co/3DeKKYA).\n\n```json\n{\n\t\"formatVersion\": 1,\n\t\"passTypeIdentifier\": \"pass.\u003cbundle id\u003e\",\n\t\"teamIdentifier\": \"\u003cyour team identifier\u003e\",\n\t\"organizationName\": \"\u003cyour organization name\u003e\",\n\t\"description\": \"A localizable description of your pass. To do so, put here a placeholder.\",\n\t\"boardingPass\": {}\n}\n```\n\n\u003ca name=\"certificates\"\u003e\u003c/a\u003e\n\n##### Certificates\n\nThe third step is about the developer and WWDR certificates. I suggest you to create a certificate-dedicated folder inside your working directory (e.g. `./certs`) to contain everything concerning the certificates.\n\nThis is a standard procedure: you would have to do it also without using this library. We'll use OpenSSL to complete our work (or to do it entirely, if only on terminal), so be sure to have it installed.\n\n[Follow the **FULL GUIDE in wiki** to get all the files you need to proceed](https://github.com/alexandercerutti/passkit-generator/wiki/Generating-Certificates).\n\n---\n\n\u003ca name=\"usage_example\"\u003e\u003c/a\u003e\n\n## Usage Examples\n\nImporting:\n\n```typescript\n/** CommonJS **/\nconst { PKPass } = require(\"passkit-generator\");\n\n/** ESM **/\nimport { PKPass } from \"passkit-generator\";\n```\n\n### Folder Model\n\n```typescript\ntry {\n\t/** Each, but last, can be either a string or a Buffer. See API Documentation for more */\n\tconst { wwdr, signerCert, signerKey, signerKeyPassphrase } = getCertificatesContentsSomehow();\n\n\tconst pass = await PKPass.from({\n\t\t/**\n\t\t * Note: .pass extension is enforced when reading a\n\t\t * model from FS, even if not specified here below\n\t\t */\n\t\tmodel: \"./passModels/myFirstModel.pass\",\n\t\tcertificates: {\n\t\t\twwdr,\n\t\t\tsignerCert,\n\t\t\tsignerKey,\n\t\t\tsignerKeyPassphrase\n\t\t},\n\t}, {\n\t\t// keys to be added or overridden\n\t\tserialNumber: \"AAGH44625236dddaffbda\"\n\t});\n\n\t// Adding some settings to be written inside pass.json\n\tpass.localize(\"en\", { ... });\n\tpass.setBarcodes(\"36478105430\"); // Random value\n\n\t// Generate the stream .pkpass file stream\n\tconst stream = pass.getAsStream();\n\tdoSomethingWithTheStream(stream);\n\n\t// or\n\n\tconst buffer = pass.getAsBuffer();\n\tdoSomethingWithTheBuffer(buffer);\n} catch (err) {\n\tdoSomethingWithTheError(err);\n}\n```\n\n### Buffer Model\n\n```typescript\ntry {\n\t/** Each, but last, can be either a string or a Buffer. See API Documentation for more */\n\tconst { wwdr, signerCert, signerKey, signerKeyPassphrase } = getCertificatesContentsSomehow();\n\n\tconst pass = new PKPass({\n\t\t\"thumbnail.png\": Buffer.from([ ... ]),\n\t\t\"icon.png\": Buffer.from([ ... ]),\n\t\t\"pass.json\": Buffer.from([ ... ]),\n\t\t\"it.lproj/pass.strings\": Buffer.from([ ... ])\n\t},\n\t{\n\t\twwdr,\n\t\tsignerCert,\n\t\tsignerKey,\n\t\tsignerKeyPassphrase,\n\t},\n\t{\n\t\t// keys to be added or overridden\n\t\tserialNumber: \"AAGH44625236dddaffbda\",\n\t});\n\n\t// Adding some settings to be written inside pass.json\n\tpass.localize(\"en\", { ... });\n\tpass.setBarcodes(\"36478105430\"); // Random value\n\n\t// Generate the stream .pkpass file stream\n\tconst stream = pass.getAsStream();\n\tdoSomethingWithTheStream(stream);\n\n\t// or\n\n\tconst buffer = pass.getAsBuffer();\n\tdoSomethingWithTheBuffer(buffer);\n} catch (err) {\n\tdoSomethingWithTheError(err);\n}\n\n```\n\nFor more complex usage examples, please refer to [examples](https://github.com/alexandercerutti/passkit-generator/tree/master/examples) folder.\n\n---\n\n## Other\n\nIf you used this package in any of your projects, feel free to open a topic in issues to tell me and include a project description or link (for companies). 😊 You'll make me feel like my time hasn't been wasted, even if it had not anyway because I learnt and keep learning a lot of things by creating this.\n\nThe idea to develop this package, was born during the Apple Developer Academy 17/18, in Naples, Italy, driven by the need to create an iOS app component regarding passes generation for events.\n\nA big thanks to all the people and friends in the Apple Developer Academy (and not) that pushed me and helped me into realizing something like this and a big thanks to the ones that helped me to make technical choices and to all the contributors.\n\nAny contribution, is welcome.\nMade with ❤️ in Italy.\n\n---\n\n## Contributors\n\nA big thanks to all the people that contributed to improve this package. Any contribution is welcome. Do you have an idea to make this improve or something to say? Open a topic in the issues and we'll discuss together! Thank you ❤️\nAlso a big big big big thank you to all the financial contributors, which help me maintain the development of this package ❤️!\n\n### Code Contributors\n\n\u003ca href=\"https://github.com/alexandercerutti/passkit-generator/graphs/contributors\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/contributors.svg?width=890\u0026button=false\" /\u003e\u003c/a\u003e\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/passkit-generator/contribute)]\n\n#### Individuals\n\n\u003ca href=\"https://opencollective.com/passkit-generator\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/individuals.svg?width=890\"\u003e\u003c/a\u003e\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/passkit-generator/contribute)]\n\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/0/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/1/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/2/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/3/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/4/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/5/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/6/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/7/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/8/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/passkit-generator/organization/9/website\"\u003e\u003cimg src=\"https://opencollective.com/passkit-generator/organization/9/avatar.svg\"\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandercerutti%2Fpasskit-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexandercerutti%2Fpasskit-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandercerutti%2Fpasskit-generator/lists"}