{"id":28731539,"url":"https://github.com/kofi-q/pcsc-mini","last_synced_at":"2025-06-19T22:05:36.158Z","repository":{"id":298814309,"uuid":"1001199339","full_name":"kofi-q/pcsc-mini","owner":"kofi-q","description":"Node.js PC/SC (smart card) bindings for Linux / MacOS / Win32","archived":false,"fork":false,"pushed_at":"2025-06-18T04:04:31.000Z","size":90,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-18T21:01:45.511Z","etag":null,"topics":["addon","napi","nodejs","pcsc","pcsc-lite","pcsclite","smartcard","tokota","winscard","zig"],"latest_commit_sha":null,"homepage":"https://kofi-q.github.io/pcsc-mini/","language":"Zig","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/kofi-q.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,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-13T01:45:59.000Z","updated_at":"2025-06-18T04:01:41.000Z","dependencies_parsed_at":"2025-06-16T19:10:39.879Z","dependency_job_id":null,"html_url":"https://github.com/kofi-q/pcsc-mini","commit_stats":null,"previous_names":["kofi-q/pcsc-mini"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/kofi-q/pcsc-mini","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kofi-q%2Fpcsc-mini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kofi-q%2Fpcsc-mini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kofi-q%2Fpcsc-mini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kofi-q%2Fpcsc-mini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kofi-q","download_url":"https://codeload.github.com/kofi-q/pcsc-mini/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kofi-q%2Fpcsc-mini/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260838519,"owners_count":23070604,"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":["addon","napi","nodejs","pcsc","pcsc-lite","pcsclite","smartcard","tokota","winscard","zig"],"created_at":"2025-06-15T18:14:06.424Z","updated_at":"2025-06-19T22:05:35.073Z","avatar_url":"https://github.com/kofi-q.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pcsc-mini\n\n` › NodeJS PC/SC API bindings for smart card access on Linux / MacOS / Win32 `\n\n[Docs ↗](https://kofi-q.github.io/pcsc-mini) | | [Overview](#overview) | | [Prerequisites](#prerequisites) | | [Installation](#installation) | | [Usage](#usage)\n\n```ts\nimport * as pcsc from \"pcsc-mini\";\nconst { CardDisposition, CardMode, ReaderStatus } = pcsc;\n\nconst client = new pcsc.Client()\n  .on(\"reader\", onReader)\n  .start();\n\nfunction onReader(reader: pcsc.Reader) {\n  reader.on(\"change\", async status =\u003e {\n    if (!status.has(ReaderStatus.PRESENT)) return;\n    if (status.hasAny(ReaderStatus.MUTE, ReaderStatus.IN_USE)) return;\n\n    const card = await reader.connect(CardMode.SHARED);\n    console.log(`${await card.state()}`);\n\n    const resTx =  await card.transmit(\n      Uint8Array.of(0xca, 0xfe, 0xf0, 0x0d)\n    );\n    console.log(resTx);\n\n    const codeFeatures = pcsc.controlCode(3400);\n    const features = await card.control(codeFeatures);\n    console.log(features);\n\n    await card.disconnect(CardDisposition.RESET);\n    client.stop();\n    process.exit(0);\n  });\n}\n```\n\n## Overview\n\n`pcsc-mini` provides NodeJS bindings to native PC/SC (Personal Computer/Smart Card) APIs:\n- [`pcsc-lite`](https://pcsclite.apdu.fr/api/winscard_8h.html) on Linux and MacOS\u003csup\u003e*\u003c/sup\u003e\n- [`winscard`](https://learn.microsoft.com/en-us/windows/win32/api/winscard/) on Windows.\n\n\u003csup\u003e* MacOS has a separate implementation built on the [`CryptoTokenKit`](https://developer.apple.com/documentation/cryptotokenkit?language=objc) API.\u003c/sup\u003e\n\n### Supported Platforms\n\nPre-built binary packages are available for the following targets.\n\n These are installed as optional dependencies of the main `pcsc-mini` package (e.g. `@pcsc-mini/linux-x86_64-gnu`).\n\n| OS                           | arm64 |  x86  | x86_64 |\n|------------------------------|:-----:|:-----:|:------:|\n| `Linux ( gnu )`              |   ✅  |  ☑️   |   ✅   |\n| `Linux ( musl )`\u003csup\u003e*\u003c/sup\u003e |   ✅  |  ☑️   |   ✅   |\n| `MacOS`                      |   ✅  | `N/A` |   ☑️   |\n| `Windows`                    |   ☑️  |  ⬜️   |   ✅   |\n\n\u003csub\u003e✅ Tested \u0026 verified\u0026nbsp;\u0026nbsp;•\u0026nbsp;\u003c/sub\u003e\n\u003csub\u003e☑️ Not tested\u0026nbsp;\u0026nbsp;•\u0026nbsp;\u003c/sub\u003e\n\u003csub\u003e⬜️ Not available\u003c/sub\u003e\n\n\u003csub\u003e* During testing on Alpine, the PCSC server daemon needed to be started *after* a reader was connected for detection/monitoring to work and required a restart whenever a reader was disconnected and reconnected.\u003c/sub\u003e\n\n### JS Runtime Compatibility\n\n| Runtime                | Supported Versions                            |\n|------------------------|-----------------------------------------------|\n| **NodeJS**             | `v16.x.x, v18.x.x, v20.x.x, v22.x.x v24.x.x`  |\n| **\u003csub\u003eOTHERS:\u003c/sub\u003e** |                                               |\n| **Bun**                | `Tested with v1.2.12 (may work with earlier)` |\n| **Deno**               | `Tested with v2.3.1 (may work with earlier)`  |\n| **Electron**           | `v15.0.0+ (Tested up to v36.2.0)`             |\n\n## Prerequisites\n\n### Linux - Alpine\n\nRequired packages:\n\n- `ccid`\n- `pcsc-lite`\n- `pcsc-lite-libs`\n\n```sh\ndoas apk add ccid pcsc-lite pcsc-lite-libs\n```\nTo run the server daemon:\n```sh\ndoas rc-service pcscd start\n```\n\n### Linux - Debian/Ubuntu/etc\n\nRequired packages:\n\n- `libpcsclite1`\n- `pcscd`\n\n```sh\nsudo apt install libpcsclite1 pcscd\n```\nTo run the server daemon:\n```sh\nsudo systemctl start pcscd\n```\n\n### MacOS/Windows\n\n**`N/A` ::**  MacOS and Windows come pre-installed with smart card support. No additional installation needed.\n\n\u003cbr /\u003e\n\n## Installation\n\n**Bun**\n```sh\nbun add pcsc-mini\n```\n\n**Deno**\n```sh\ndeno add npm:pcsc-mini\n```\n\n**npm**\n```sh\nnpm i pcsc-mini\n```\n\n**pnpm**\n```sh\npnpm add pcsc-mini\n```\n\n## Usage\n\n```ts\nimport * as pcsc from \"pcsc-mini\";\nconst { CardDisposition, CardMode, ReaderStatus } = pcsc;\n\n// The `Client` emits a \"reader\" event for each detected device.\nconst client = new pcsc.Client()\n  .on(\"reader\", onReader)\n  .on(\"error\", onError)\n  .start();\n\nfunction onError(err: pcsc.Err) {\n  console.error(\"Unexpected PCSC error:\", err);\n  client.stop();\n\n  // [ Log and exit / attempt `start()` retries with backoff / etc... ]\n};\n\nfunction onReader(reader: pcsc.Reader) {\n  let card: pcsc.Card | undefined;\n\n  console.log(`Reader detected: ${reader}`);\n\n  // Each reader emits a \"change\" event on every reader state change.\n  reader.on(\"change\", async status =\u003e {\n    if (status.hasAny(ReaderStatus.MUTE, ReaderStatus.IN_USE)) return;\n\n    if (!status.has(ReaderStatus.PRESENT)) {\n      void card?.disconnect(CardDisposition.RESET);\n      card = undefined;\n      return;\n    }\n\n    try {\n      if (!card) card = await reader.connect(CardMode.SHARED);\n\n      // Transmit Uint8Array (or NodeJS Buffer) data:\n      const res = await card.transmit(\n        Uint8Array.of(0xca, 0xfe, 0xf0, 0x0d)\n      );\n\n      // Use Uint8Array response directly, or via DataView/Buffer:\n      const vw = new DataView(res.buffer, res.byteOffset, res.length);\n      const tag = vw.getUint8(0);\n      const len = vw.getUint16(2);\n      const val = new Uint8Array(res.buffer, 4, len);\n\n      // ...\n    } catch (err) {\n      console.error(\"Card error:\", err);\n    }\n  });\n\n  // \"disconnect\" is emitted when a reader is no longer detected.\n  //\n  // All event listeners will be removed from the now-invalid reader.\n  // Any reader/card-related state should be disposed of here.\n  reader.on(\"disconnect\", async () =\u003e {\n    void card?.disconnect(CardDisposition.RESET);\n    card = undefined;\n  });\n}\n```\n\n\u003e [!TIP]\n\u003e\n\u003e See the [E2E test application](./e2e/index.js) for more involved usage and error handling.\n\n## Development\n\n### Prerequisites\n\n|                          | Minimum Version | Recommended Version                |\n|--------------------------|-----------------|------------------------------------|\n| **Zig**                  | v0.14.1         | See [`.zigversion`](.zigversion)   |\n| **NodeJS**               | v24.0.0         | See [`.nvmrc`](.nvmrc)             |\n| **pnpm**                 | v10.0.0         | See [`package.json`](package.json) |\n| **\u003csub\u003eOPTIONAL:\u003c/sub\u003e** |                 |                                    |\n| **Bun**                  | v1.2.12         |                                    |\n| **Deno**                 | v2.3.1          |                                    |\n\n\n#### Linux\n\nSee [Prerequisites](#prerequisites) section above for a list of runtime prerequisites.\n\nOther relevant development libraries (e.g. `libpcsclite-dev` on Debian-based distros) are included in the [`pcsc`](https://github.com/kofi-q/pcsc-z) dependency. No additional installation needed.\n\n#### MacOS\n\n**`N/A` ::** Required MacOS Framework `.tbd`s are included in the [`pcsc`](https://github.com/kofi-q/pcsc-z) dependency. No additional installation needed.\n\n#### Windows\n\n**`N/A` ::** Required DLLs are shipped with the Zig compiler. No additional installation needed.\n\n### Building \u0026 Testing\n\n#### Building the dev addon binary:\n\nThis will output an `lib/addon.node` file to enable unit testing. Runs automatically when running the unit tests.\n\n```sh\nzig build\n```\n\n#### Running Zig and NodeJS unit tests:\n\n```sh\nzig build test\n```\n\n##### Or individually:\n\n```sh\nzig build test:node -- --watch\n```\n```sh\nzig build test:zig --watch\n```\n\n#### Running the E2E test application:\n\nThis enables testing basic operations against real devices (supporting up to 4 simultaneously connected readers) to verify functionality not testable via unit tests.\n\n```sh\nzig build e2e\n```\n\n#### Generating the NPM packages:\n\nThis will output the final NPM package directories to `./zig-out/npm_packages`.\n\n```sh\nzig build packages\n```\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkofi-q%2Fpcsc-mini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkofi-q%2Fpcsc-mini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkofi-q%2Fpcsc-mini/lists"}