{"id":30112563,"url":"https://github.com/71/capnp-swift","last_synced_at":"2025-08-10T06:47:58.037Z","repository":{"id":300499374,"uuid":"997958301","full_name":"71/capnp-swift","owner":"71","description":"(Unofficial, WIP) Cap'n Proto support for Swift; serialization only.","archived":false,"fork":false,"pushed_at":"2025-06-28T09:22:47.000Z","size":86,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-02T11:04:56.874Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/71.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-07T15:08:19.000Z","updated_at":"2025-06-28T09:22:51.000Z","dependencies_parsed_at":"2025-06-22T03:41:04.367Z","dependency_job_id":null,"html_url":"https://github.com/71/capnp-swift","commit_stats":null,"previous_names":["71/capnp-swift"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/71/capnp-swift","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/71%2Fcapnp-swift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/71%2Fcapnp-swift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/71%2Fcapnp-swift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/71%2Fcapnp-swift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/71","download_url":"https://codeload.github.com/71/capnp-swift/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/71%2Fcapnp-swift/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269688021,"owners_count":24459399,"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","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-08-10T06:47:55.767Z","updated_at":"2025-08-10T06:47:58.028Z","avatar_url":"https://github.com/71.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cap'n Proto Swift\n\n[Cap'n Proto](https://capnproto.org) runtime and code generation for Swift. Not\nan official Cap'n Proto project.\n\n## Features\n\n- Encoding and decoding of Cap'n Proto messages.\n\n- Swift-friendly APIs with `enum`s and typed errors.\n\n- Zero-copy messages which operate directly on byte buffers.\n\n- [Serialization over streams](https://capnproto.org/encoding.html#serialization-over-a-stream),\n  including zero-copy (when segments fully fit in input buffers).\n\nThe following are not supported:\n\n- RPC and interfaces.\n\n- Packing.\n\n- Generics.\n\n- Orphans.\n\n- Reflection.\n\n## Example\n\nThe `addressbook.capnp` example is available in\n[`Tests/CapnProtoTests/AddressBook.swift`](Tests/CapnProtoTests/AddressBook.swift).\n\n## Safety\n\nThe library and generated code is designed to handle malicious inputs, but it is\nnot 100% there:\n\n1. Possible decoding errors (invalid pointers, overflows) are surfaced as Swift\n   errors. However some parts of the implementation do not perform checked\n   arithmetic yet, and need to be updated to safely decode untrusted messages.\n\n1. The\n   [traversal limit which prevents amplification attacks](https://capnproto.org/encoding.html#amplification-attack)\n   is not implemented. Only the\n   [pointer depth limit which prevents stack overflows](https://capnproto.org/encoding.html#stack-overflow-dos-attack)\n   is implemented.\n\n1. There are few tests, and the code has not undergone any thorough review.\n\n## Usage\n\n### Using plugins\n\nIf `capnp` is in your `PATH`, Cap'n Proto Swift can be used as a plugin which\nwill automatically convert `.capnp` files in your source directory.\n\n```swift\n// Package.swift\n\nlet package = Package(\n  dependencies: [\n    .package(url: \"https://github.com/71/capnp-swift\", branch: \"main\"),\n  ],\n  targets: [\n    .target(\n      name: \"MyTarget\",\n      dependencies: [\n        .product(name: \"CapnProto\", package: \"capnp-swift\"),\n      ],\n      plugins: [\n        .plugin(name: \"CapnProtoPlugin\", package: \"capnp-swift\"),\n      ]\n    ),\n  ]\n)\n```\n\n### Manually\n\nIf you do not want the build to happen automatically, you can instead use\n`capnpc-swift` as a [Cap'n Proto plugin](https://capnproto.org/capnp-tool.html).\n\nFirst, add a dependency to `capnp-swift`:\n\n```swift\n// Package.swift\n\nlet package = Package(\n  dependencies: [\n    .package(url: \"https://github.com/71/capnp-swift\", branch: \"main\"),\n  ],\n  targets: [\n    .target(\n      name: \"MyTarget\",\n      dependencies: [\n        .product(name: \"CapnProto\", package: \"capnp-swift\"),\n      ]\n    ),\n  ]\n)\n```\n\nThen, use `capnp compile` to generate your code:\n\n```sh\ncapnp compile $(swift package print-capnp-compile) Sources/MyTarget/schema.capnp\n```\n\n\u003e [!NOTE]\n\u003e `swift package print-capnp-compile [output-directory]` automatically resolves\n\u003e paths needed to compile `.capnp` files and generates arguments given to\n\u003e `capnp compile`:\n\u003e\n\u003e ```sh\n\u003e $ swift package print-capnp-compile\n\u003e --output=/path/to/project/.build/arm64-apple-macosx/debug/capnpc-swift-tool --import-path=/path/to/capnp-swift/\n\u003e ```\n\u003e\n\u003e An even more manual way to do this is to build `capnpc-swift` and use its\n\u003e path:\n\u003e\n\u003e ```sh\n\u003e $ swift build --product capnpc-swift --show-bin-path\n\u003e /path/to/project/.build/arm64-apple-macosx/debug\n\u003e ```\n\n## Design\n\nUnlike the [C++](https://capnproto.org/cxx.html) and\n[Rust](https://github.com/capnproto/capnproto-rust) APIs (but like the\n[Go](https://github.com/capnproto/go-capnp) and\n[ECMAScript](https://github.com/unjs/capnp-es) APIs), there are no distinctive\ntypes for reading and writing messages. Instead, the same types are used when\nreading and writing, and writing can surface \"not written\" errors. This was\ndeemed okay as writing can _always_ fail, since the message you're working with\nin memory may not have enough space for the field you're trying to write (if the\nmessage was generated by a previous version of the code or\n[canonicalized](https://capnproto.org/encoding.html#canonicalization)).\n\n### APIs\n\n- Pointer fields are exposed as `throw`ing methods as decoding can fail, whereas\n  non-pointer fields are exposed as properties.\n\n- Enums are represented as a generated enum type wrapped in an `EnumValue\u003cE\u003e`,\n  as their value may be unknown to the program reading them. `EnumValue`\n  provides access to the underlying value as `E?` or `UInt16`.\n\n- Unions are represented as `struct`s where all union fields are `Optional`, and\n  with additional methods and types:\n\n  - `var whichDiscriminant: EnumValue\u003cWhich.Discriminant\u003e` returns the raw\n    discriminant of the union.\n\n  - `func which() -\u003e Which?` returns a Swift `enum` wrapping the union data, or\n    `nil` if the discriminant is for an unknown field. It can `throw` if one of\n    the fields is a pointer.\n\n### Multithreading\n\nSynchronizing access to messages when reading or writing would be expensive, so\nmost Cap'n Proto types are not\n[`Sendable`](https://developer.apple.com/documentation/swift/sendable) and\ninstead work on a shared `Message` instance within a single thread.\n\n`Message`s, `List`s and `Struct`s can be frozen into a `Frozen\u003cT\u003e` object which\nprevents further mutations and is `Sendable`.\n\nTracking whether a `Message` or `Struct` is mutable could be needlessly\nexpensive for those who do not care about multithreading, but the cost was\ndeemed okay for the following reasons:\n\n1. Both the `Message` and all pointer types (`List`, `Struct`) store a \"mutable\n   bit\", so determining if a `Struct` is mutable does not require dereferencing\n   its `Message`.\n\n   This mutable bit takes no space at all; it is stored in the traversal limit\n   counter.\n\n1. In order to support default values, it is necessary for parts of a message to\n   be immutable anyway.\n\nNote that freezing a type has, like Swift arrays and strings, copy-on-write\nsemantics: if no other object refers to the underlying data, the data is\ndirectly frozen. Otherwise, it is first copied.\n\n## Development\n\nAfter modifying a `.capnp` file in this repository, run:\n\n```sh\nTools/compile-proto.sh\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F71%2Fcapnp-swift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F71%2Fcapnp-swift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F71%2Fcapnp-swift/lists"}