{"id":21655780,"url":"https://github.com/tayloraswift/swift-bson","last_synced_at":"2025-06-30T05:02:56.998Z","repository":{"id":263521765,"uuid":"890645874","full_name":"tayloraswift/swift-bson","owner":"tayloraswift","description":"parse, decode, and encode BSON in pure Swift","archived":false,"fork":false,"pushed_at":"2025-04-13T21:50:25.000Z","size":213,"stargazers_count":11,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-07T23:54:01.376Z","etag":null,"topics":["bson","mongdb","serialization"],"latest_commit_sha":null,"homepage":"https://swiftinit.org/docs/swift-bson/bson/examples","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tayloraswift.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"zenodo":null},"funding":{"github":["tayloraswift"]}},"created_at":"2024-11-18T23:48:17.000Z","updated_at":"2025-04-13T21:50:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"d89f851d-f9d4-42c6-b3f1-cf5affbd99f5","html_url":"https://github.com/tayloraswift/swift-bson","commit_stats":null,"previous_names":["tayloraswift/swift-bson"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/tayloraswift/swift-bson","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tayloraswift%2Fswift-bson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tayloraswift%2Fswift-bson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tayloraswift%2Fswift-bson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tayloraswift%2Fswift-bson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tayloraswift","download_url":"https://codeload.github.com/tayloraswift/swift-bson/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tayloraswift%2Fswift-bson/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262714470,"owners_count":23352462,"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":["bson","mongdb","serialization"],"created_at":"2024-11-25T08:35:57.309Z","updated_at":"2025-06-30T05:02:56.788Z","avatar_url":"https://github.com/tayloraswift.png","language":"Swift","funding_links":["https://github.com/sponsors/tayloraswift"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n***`bson`***\n\n[![Tests](https://github.com/tayloraswift/swift-bson/actions/workflows/Tests.yml/badge.svg)](https://github.com/tayloraswift/swift-bson/actions/workflows/Tests.yml)\n[![Documentation](https://github.com/tayloraswift/swift-bson/actions/workflows/Documentation.yml/badge.svg)](https://github.com/tayloraswift/swift-bson/actions/workflows/Documentation.yml)\n\n\u003c/div\u003e\n\nThe ***swift-bson*** library is a portable, Foundation-free library for working with [BSON](https://bsonspec.org/).\n\n\u003cdiv align=\"center\"\u003e\n\n[documentation](https://swiftinit.org/docs/swift-bson) ·\n[license](LICENSE)\n\n\u003c/div\u003e\n\n\n## Requirements\n\nThe swift-bson library requires Swift 6.0 or later.\n\n\n| Platform | Status |\n| -------- | ------ |\n| 🐧 Linux | [![Tests](https://github.com/tayloraswift/swift-bson/actions/workflows/Tests.yml/badge.svg)](https://github.com/tayloraswift/swift-bson/actions/workflows/Tests.yml) |\n| 🍏 Darwin | [![Tests](https://github.com/tayloraswift/swift-bson/actions/workflows/Tests.yml/badge.svg)](https://github.com/tayloraswift/swift-bson/actions/workflows/Tests.yml) |\n| 🍏 Darwin (iOS) | [![iOS](https://github.com/tayloraswift/swift-bson/actions/workflows/iOS.yml/badge.svg)](https://github.com/tayloraswift/swift-bson/actions/workflows/iOS.yml) |\n| 🍏 Darwin (tvOS) | [![tvOS](https://github.com/tayloraswift/swift-bson/actions/workflows/tvOS.yml/badge.svg)](https://github.com/tayloraswift/swift-bson/actions/workflows/tvOS.yml) |\n| 🍏 Darwin (visionOS) | [![visionOS](https://github.com/tayloraswift/swift-bson/actions/workflows/visionOS.yml/badge.svg)](https://github.com/tayloraswift/swift-bson/actions/workflows/visionOS.yml) |\n| 🍏 Darwin (watchOS) | [![watchOS](https://github.com/tayloraswift/swift-bson/actions/workflows/watchOS.yml/badge.svg)](https://github.com/tayloraswift/swift-bson/actions/workflows/watchOS.yml) |\n\n\n[Check deployment minimums](https://swiftinit.org/docs/swift-bson#ss:platform-requirements)\n\n\n## What is BSON?\n\n[BSON](https://bsonspec.org/) is a general-purpose binary serialization format that is a superset of [JSON](https://www.json.org/). Parsing BSON requires much less memory than parsing JSON, and the format is traversable, which makes it possible to extract individual fields nested deep within a BSON document without actually parsing the entire file.\n\nBSON was originally developed by [MongoDB](https://www.mongodb.com/), for which it serves as its native data format. However, the file format itself is not tied to MongoDB, and can be used in any system that requires a high-performance, low-memory serialization format.\n\n\n## Why do I need this library?\n\nIf you are using [MongoKitten](https://github.com/orlandos-nl/MongoKitten), your MongoDB driver already includes a BSON parser based on the standard library’s [`Codable`](https://swiftinit.org/docs/swift/swift/codable) system, which has the advantage of generating much of the deserialization code for you automatically. However, `Codable` has well-known performance limitations, and is not suitable for high-throughput use cases.\n\nAnother reason to use this library is that it is portable and has few dependencies. BSON parsers provided by MongoDB drivers have dependencies on networking primitives such as [`ByteBuffer`](https://swiftinit.org/docs/swift-nio/niocore/bytebuffer), which requires you to link the [SwiftNIO library](https://github.com/apple/swift-nio). For applications that simply use BSON as a storage format, this may not be desirable.\n\n\n## Is it faster than Codable?\n\nThe decoder is approximately 3 to 6 times faster than the default MongoKitten decoder. The encoder has similar throughput to `Codable`.\n\n([Benchmark source code](/Benchmarks/Benchmarks/VsMongoKittenDefault))\n\n\u003cdetails\u003e\n\n\u003csummary\u003ePerformance comparison \u003c/summary\u003e\n\n```\nHost 'vscode' with 12 'x86_64' processors with 30 GB memory, running:\n#202408030740 SMP PREEMPT_DYNAMIC Sat Aug  3 07:53:03 UTC 2024\n\n====================\nVsMongoKittenDefault\n====================\n\nDecode BSON with MongoKitten Default\n╒═════════════════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕\n│ Metric                              │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │\n╞═════════════════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡\n│ (Alloc + Retain) - Release Δ *      │    1476 │    1500 │    1506 │    1512 │    1520 │    1529 │    1536 │     376 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Object allocs *                     │    2334 │    2459 │    2493 │    2521 │    2545 │    2605 │    2634 │     376 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Releases (K) *                      │      21 │      21 │      22 │      22 │      22 │      22 │      22 │     376 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Retains (K) *                       │      17 │      18 │      18 │      18 │      18 │      18 │      18 │     376 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Throughput (# / s) (#)              │     617 │     592 │     583 │     572 │     562 │     415 │     234 │     376 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Time (wall clock) (μs) *            │    1620 │    1690 │    1714 │    1747 │    1781 │    2408 │    4276 │     376 │\n╘═════════════════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛\n\nDecode BSON with This Library\n╒═════════════════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕\n│ Metric                              │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │\n╞═════════════════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡\n│ (Alloc + Retain) - Release Δ *      │    7917 │    8035 │    8071 │    8099 │    8123 │    8167 │    8187 │    1000 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Object allocs *                     │     892 │     969 │     984 │     997 │    1011 │    1034 │    1061 │    1000 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Releases (K) *                      │      13 │      14 │      14 │      14 │      14 │      14 │      14 │    1000 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Retains *                           │    4406 │    4523 │    4555 │    4583 │    4607 │    4643 │    4697 │    1000 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Throughput (# / s) (#)              │    1915 │    1820 │    1791 │    1748 │    1669 │    1175 │    1061 │    1000 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Time (wall clock) (μs) *            │     522 │     549 │     559 │     572 │     599 │     810 │     943 │    1000 │\n╘═════════════════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛\n\nEncode BSON with MongoKitten Default\n╒═════════════════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕\n│ Metric                              │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │\n╞═════════════════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡\n│ (Alloc + Retain) - Release Δ *      │    5054 │    5247 │    5307 │    5379 │    5427 │    5519 │    5598 │     513 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Object allocs *                     │    2993 │    3113 │    3153 │    3199 │    3229 │    3279 │    3323 │     513 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Releases (K) *                      │      39 │      41 │      41 │      42 │      42 │      43 │      44 │     513 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Retains (K) *                       │      31 │      33 │      33 │      33 │      34 │      34 │      35 │     513 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Throughput (# / s) (#)              │     198 │     189 │     185 │     182 │     177 │     162 │     132 │     513 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Time (wall clock) (μs) *            │    5039 │    5300 │    5394 │    5501 │    5661 │    6181 │    7598 │     513 │\n╘═════════════════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛\n\nEncode BSON with This Library\n╒═════════════════════════════════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╤═════════╕\n│ Metric                              │      p0 │     p25 │     p50 │     p75 │     p90 │     p99 │    p100 │ Samples │\n╞═════════════════════════════════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╪═════════╡\n│ (Alloc + Retain) - Release Δ *      │    5066 │    5251 │    5311 │    5375 │    5427 │    5531 │    5614 │     514 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Object allocs *                     │    3003 │    3123 │    3153 │    3199 │    3229 │    3293 │    3353 │     514 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Releases (K) *                      │      39 │      41 │      41 │      42 │      42 │      43 │      44 │     514 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Retains (K) *                       │      31 │      33 │      33 │      33 │      34 │      34 │      35 │     514 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Throughput (# / s) (#)              │     198 │     189 │     186 │     183 │     178 │     159 │      95 │     514 │\n├─────────────────────────────────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤\n│ Time (wall clock) (μs) *            │    5061 │    5280 │    5366 │    5464 │    5612 │    6275 │   10509 │     514 │\n╘═════════════════════════════════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╧═════════╛\n```\n\n\u003c/details\u003e\n\n\n## Should I really be using BSON?\n\nBSON is not for everyone. The rationales below are *not* good reasons to adopt BSON, at least by themselves.\n\n\n### Saving disk space\n\nBSON will save memory when parsing, but in typical use cases, a BSON file will occupy a similar amount of space as an equivalent JSON file, and offer a similar compression ratio.\n\n\n### Serving to the web\n\nBSON is generally considered a server side format, and there are few compelling reasons to synthesize it for the sole purpose of serving content to browsers.\n\nThat said, [JavaScript libraries](https://www.npmjs.com/package/bson) do exist for parsing BSON, so it is possible to use it on the client side. One good reason to do this is if you are storing BSON objects as static resources accessible from a CDN, and want clients to be able to download the BSON from the CDN instead of converting it dynamically to JSON via your HTTP server.\n\n\n## Is it worth the effort?\n\nLearning this library will enable you to use a high-performance binary serialization format across a wide range of platforms. The library is small, written in pure Swift, and organized around a few key patterns that emphasize maintainability in large codebases.\n\nAlthough swift-bson cannot synthesize serialization code for you, its idioms are predictable and easily “paintable” by LLMs such as GitHub Copilot.\n\n\n## What does the code look like?\n\nIn a “realistic” codebase, a BSON model type looks like this:\n\n```swift\nstruct ExampleModel:BSONDocumentEncodable, BSONDocumentDecodable\n{\n    let id:Int64\n    let name:String?\n    let rank:Rank\n\n    /// A custom enum type.\n    enum Rank:Int32, BSONEncodable, BSONDecodable\n    {\n        case newModel\n        case risingStar\n        case aspiringModel\n        case fashionista\n        case glamourista\n        case fashionMaven\n        case runwayQueen\n        case trendSetter\n        case runwayDiva\n        case topModel\n    }\n\n    /// The schema definition.\n    enum CodingKey:String, Sendable\n    {\n        case id = \"_id\" // Chosen for compatibility with MongoDB\n        case name = \"D\"\n        case rank = \"R\"\n    }\n\n    /// The serialization logic.\n    func encode(to bson:inout BSON.DocumentEncoder\u003cCodingKey\u003e)\n    {\n        bson[.id] = self.id\n        bson[.name] = self.name\n        bson[.rank] = self.rank == .newModel ? nil : self.rank\n    }\n\n    /// The deserialization logic.\n    init(bson:BSON.DocumentDecoder\u003cCodingKey\u003e) throws\n    {\n        self.id = try bson[.id].decode()\n        self.name = try bson[.name]?.decode()\n        self.rank = try bson[.rank]?.decode() ?? .newModel\n    }\n}\n```\n\nThe code to actually round-trip this to and from raw data looks like this:\n\n```swift\nlet models:[ExampleModel] = [\n    .init(id: 0, name: \"Gigi\", rank: .topModel),\n    .init(id: 1, name: nil, rank: .newModel),\n]\n\n/// Round-trip one model\nlet document:BSON.Document = .init(encoding: models[0])\nlet _:ArraySlice\u003cUInt8\u003e = document.bytes\nlet model:ExampleModel = try .init(bson: document)\n\n/// Round-trip a list of models\nlet list:BSON.List = .init(elements: models)\nlet _:ArraySlice\u003cUInt8\u003e = list.bytes\nlet array:[ExampleModel] = try .init(bson: list)\n```\n\n\n## Tutorials\n\n- [Usage Examples](https://swiftinit.org/docs/swift-bson/bson/examples)\n- [Protocols Explained](https://swiftinit.org/docs/swift-bson/bson/walkthrough)\n- [Advanced Serialization Patterns](https://swiftinit.org/docs/swift-bson/bson/serialization-patterns)\n- [Textures and Coordinates](https://swiftinit.org/docs/swift-bson/bson/textures-and-coordinates)\n\n\n## License\n\nThe swift-bson library is Apache 2.0 licensed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftayloraswift%2Fswift-bson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftayloraswift%2Fswift-bson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftayloraswift%2Fswift-bson/lists"}