{"id":18654276,"url":"https://github.com/fatbobman/coredataevolution","last_synced_at":"2026-06-02T03:05:11.022Z","repository":{"id":257825887,"uuid":"784182260","full_name":"fatbobman/CoreDataEvolution","owner":"fatbobman","description":"SwiftData-style actor isolation, Swift-first NSManagedObject macros, and typed mapping for   modern Core Data projects.","archived":false,"fork":false,"pushed_at":"2026-05-30T00:10:14.000Z","size":726,"stargazers_count":128,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-05-30T02:10:31.790Z","etag":null,"topics":["core-data","coredata","nsmanagedobject","predicate","sqlite","swift","swift-concurrency","swift-macros","swiftdata"],"latest_commit_sha":null,"homepage":"https://fatbobman.com/en/posts/why-i-am-still-thinking-about-core-data-in-2026/","language":"Swift","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/fatbobman.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,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"fatbobman","thanks_dev":null,"custom":["https://afdian.com","https://www.paypal.com/paypalme/fatbobman"]}},"created_at":"2024-04-09T10:53:49.000Z","updated_at":"2026-05-30T00:10:12.000Z","dependencies_parsed_at":"2026-02-24T03:01:13.163Z","dependency_job_id":null,"html_url":"https://github.com/fatbobman/CoreDataEvolution","commit_stats":null,"previous_names":["fatbobman/coredataevolution"],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/fatbobman/CoreDataEvolution","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fatbobman%2FCoreDataEvolution","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fatbobman%2FCoreDataEvolution/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fatbobman%2FCoreDataEvolution/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fatbobman%2FCoreDataEvolution/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fatbobman","download_url":"https://codeload.github.com/fatbobman/CoreDataEvolution/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fatbobman%2FCoreDataEvolution/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33803767,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"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":["core-data","coredata","nsmanagedobject","predicate","sqlite","swift","swift-concurrency","swift-macros","swiftdata"],"created_at":"2024-11-07T07:14:32.545Z","updated_at":"2026-06-02T03:05:11.012Z","avatar_url":"https://github.com/fatbobman.png","language":"Swift","funding_links":["https://buymeacoffee.com/fatbobman","https://afdian.com","https://www.paypal.com/paypalme/fatbobman"],"categories":[],"sub_categories":[],"readme":"# CoreDataEvolution\n\n![Swift 6](https://img.shields.io/badge/Swift-6-orange?logo=swift) ![iOS](https://img.shields.io/badge/iOS-13.0+-green) ![macOS](https://img.shields.io/badge/macOS-10.15+-green) ![watchOS](https://img.shields.io/badge/watchOS-6.0+-green) ![visionOS](https://img.shields.io/badge/visionOS-1.0+-green) ![tvOS](https://img.shields.io/badge/tvOS-13.0+-green) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/fatbobman/CoreDataEvolution)\n\nCoreDataEvolution **does not** replace Core Data. It modernizes how Core Data is expressed, isolated, and maintained in Swift codebases.\n\nCoreDataEvolution brings four ideas together for Core Data projects:\n\n- SwiftData-style actor isolation for Core Data\n- a Swift-first source representation for `NSManagedObject` models\n- a typed mapping layer for sort and predicate code that improves naming flexibility and type\n  safety without forcing changes to the underlying model\n- tooling that keeps source declarations aligned with the real Core Data model\n\nThis document focuses on the user-facing story:\n\n- what the library is for\n- which pain points it solves\n- what the major features are\n- how the pieces fit together\n- where to go next in the detailed guides\n\n## What Problem This Library Solves\n\nCore Data is no longer the newest persistence option in Apple's ecosystem.\n\nSwiftData offers a more modern declaration style. GRDB, SQLiteData, and other approaches give many\nteams more direct database control.\n\nAnd yet Core Data is still a pragmatic choice for many production apps because it offers:\n\n- broad platform support\n- mature migration and store behavior\n- an object-graph model many teams still prefer\n- existing schemas that teams cannot easily replace\n\nSo the question this library starts from is not:\n\n- \"Should everyone still choose Core Data?\"\n\nIt is:\n\n- \"If a project is still using Core Data, how can it fit modern Swift more naturally?\"\n\nThat is where the real friction shows up today.\n\n### Pain Point 1: The model declaration layer no longer feels native to modern Swift\n\nThe problem is not that Core Data cannot model data.\n\nThe problem is that the default `NSManagedObject` source layer becomes awkward when you want\ntoday's Swift code to express intent clearly.\n\nTypical pressure points include:\n\n- better Swift-facing names than the stored schema names\n- enums instead of raw values\n- Codable payloads\n- transformable values\n- structured composition values\n- predictable generated boilerplate instead of repeated hand-written bridging\n\nWithout help, teams often end up writing a thick layer of computed properties and bridging code\njust to make the model feel natural in Swift.\n\nCoreDataEvolution adds a Swift-first declaration layer around `NSManagedObject` while keeping the\nreal Core Data runtime underneath.\n\n### Pain Point 2: The concurrency model still feels older than the rest of the codebase\n\nCore Data can absolutely be used safely with concurrency, but its default workflow still tends to\npull developers back toward `perform`, context passing, and ad hoc thread-confinement discipline.\n\nCompared with the actor-isolated style many Swift developers now expect, traditional Core Data code\noften falls back to:\n\n- manually passing contexts around\n- remembering thread confinement rules\n- reloading objects by `NSManagedObjectID`\n- building one-off background helpers\n\nCoreDataEvolution brings a SwiftData-style actor-isolated workflow to Core Data.\n\n### Pain Point 3: SwiftUI often has to stop thinking in the Core Data object graph\n\nMany Core Data apps are still shaped around relationships: projects contain tasks, notes belong to\nfolders, messages point to authors, and detail views naturally follow those chains.\n\nWith the traditional `ObservableObject` path, immediate SwiftUI refresh is usually tied to a view\nboundary that owns the observed object. That works for simple rows, but relationship-chain screens\nquickly become awkward. A view that wants to read a path such as `item.itemData.memo` often has to be\nsplit into several smaller view structs so each related object can be carried by its own observed\nwrapper.\n\nThat cost is not only boilerplate. It pushes UI structure toward observation mechanics instead of the\nshape the screen actually wants:\n\n- relationship-chain reads need extra view boundaries or forwarding glue\n- local view extraction becomes less flexible because observation ownership leaks into layout choices\n- the UI drifts away from the direct model-graph style that SwiftData encourages\n\nCoreDataEvolution's MainActor Observation support lets SwiftUI read generated Core Data accessors\ndirectly, including across relationship chains. The first goal is cognitive clarity: keep the view\nclose to the persisted object graph and make a future SwiftData migration conceptually easier.\nField-level precision helps, but it is an implementation benefit, not the primary reason for the\nfeature.\n\n### Pain Point 4: Naming flexibility, type safety, and schema stability pull against each other\n\nOnce a Core Data model ships, schema names often become hard to change safely.\n\nThat creates pressure to keep old persistent names while still wanting better Swift-facing names in\napplication code.\n\nThe usual result is some combination of:\n\n- hand-written mapping code\n- stringly-typed sort and predicate keys\n- growing drift between `.xcdatamodeld`, Swift source, and query code\n\nCoreDataEvolution adds a typed mapping layer for sort and predicate construction so you can improve\nSwift naming and type safety without being forced to rename the underlying schema.\n\n### Pain Point 5: Experience and convention are not enough anymore\n\nMany teams already know how to work around these issues.\n\nThe harder problem is that the workarounds often live as:\n\n- tribal knowledge\n- local conventions\n- discipline that must be remembered in code review\n\nThat gets less reliable as projects grow, teams change, and AI-assisted coding becomes part of the\nday-to-day workflow.\n\nCoreDataEvolution tries to turn those conventions into clearer APIs, generated structure, and an\noptional toolchain that can verify alignment over time.\n\nBackground article:\n\n- [Why I'm Still Thinking About Core Data in 2026](https://fatbobman.com/en/posts/why-i-am-still-thinking-about-core-data-in-2026/)\n\n## Mental Model\n\nThe project is built around one central idea:\n\n\u003e `@PersistentModel` is a source-level representation of a Core Data model, not a replacement for Core Data itself.\n\nThat distinction matters.\n\n### What `@PersistentModel` is\n\nIt is a Swift-facing declaration layer for:\n\n- attributes\n- relationships\n- composition values\n- generated typed path metadata\n- generated runtime schema metadata for test/debug use\n\n### What `@PersistentModel` is not\n\nIt is not:\n\n- a replacement for `.xcdatamodeld` in production\n- a migration system\n- a different persistence engine\n- a runtime reflection layer\n\nThe production source of truth is still your Core Data model.\n\nThe macro layer gives you a better, more explicit, more toolable representation of that model in Swift source.\n\nThis is the most important mental model for new users:\n\n- keep building the real schema in Xcode\n- use `@PersistentModel` to describe that schema in Swift\n- use `cde-tool` (optional) to keep the two layers aligned\n\n## The Three Main Parts of the Package\n\n### 1. Actor isolation for Core Data\n\nUse:\n\n- `@NSModelActor`\n- `@NSMainModelActor`\n\nThese macros generate the boilerplate needed to safely work with Core Data through actor isolation or main-actor isolation.\n\nGood fit:\n\n- background write handlers\n- UI-facing main-thread coordinators\n- tests that need explicit isolation boundaries\n\nGuide:\n\n- [Docs/NSModelActorGuide.md](./Docs/NSModelActorGuide.md)\n\nBackground article:\n\n- [Core Data Reform: Achieving Elegant Concurrency Operations Like SwiftData](https://fatbobman.com/en/posts/core-data-reform-achieving-elegant-concurrency-operations-like-swiftdata/)\n\n### 2. `@PersistentModel` and related macros\n\nUse:\n\n- `@PersistentModel`\n- `@Attribute`\n- `@Relationship`\n- `@Ignore`\n- `@Composition`\n- `@CompositionField`\n\nThis is the model declaration layer.\n\nIt gives you:\n\n- explicit attribute/relationship metadata\n- generated Core Data accessors\n- lightweight `relationshipNameCount` accessors for to-many relationships\n- generated to-many relationship helper APIs\n- typed key/path metadata for sort and predicate construction\n- runtime schema metadata for tests and debug workflows\n- optional MainActor Observation for generated accessors on iOS 17+ / macOS 14+\n\nGuide:\n\n- [Docs/PersistentModelGuide.md](./Docs/PersistentModelGuide.md)\n- [Docs/ObservationGuide.md](./Docs/ObservationGuide.md)\n\nObservation opt-in:\n\n```swift\n@objc(Item)\n@PersistentModel(observation: .mainActor)\nfinal class Item: NSManagedObject {\n  var title: String = \"\"\n  var summary: String = \"\"\n}\n\n@NSModelActor\nactor ItemWriter {\n  func rename(\n    id: NSManagedObjectID,\n    to title: String\n  ) async throws {\n    guard let item = self[id, as: Item.self] else { return }\n    item.title = title\n    try await saveObservedChanges()\n  }\n}\n\n@MainActor\nfinal class Store {\n  let container: NSPersistentContainer\n  let observation: CDEObservationDomain\n  let writer: ItemWriter\n\n  init(container: NSPersistentContainer) {\n    self.container = container\n    let observation = CDEObservationDomain(container: container)\n    self.observation = observation\n    writer = ItemWriter(observationDomain: observation)\n  }\n}\n```\n\nThis activates MainActor Swift Observation for CDE-generated accessors on the container's\n`viewContext`, so SwiftUI can read managed objects directly without a separate projection model.\n`ItemWriter` is a background actor; creating it with `init(observationDomain:)` registers its actor\ncontext as an Observation producer and keeps the domain setup alive. Successful\n`saveObservedChanges()` calls from that actor provide property-level Observation response for updated\nobjects. Direct `modelContext.save()` calls from the same registered context can also carry metadata,\nbut `saveObservedChanges()` is the actor-facing API that makes the property-level Observation\ncontract explicit. If save fails, CDE clears its own staged Observation metadata and rethrows without\nrolling back your context. Insert and delete operations do not need a property-level save wrapper; use\nordinary Core Data saves for those. Refresh is save-gated and can be field-precise when the save\nsource provides enough metadata. See the guide for producer routes, fallback rules, and re-merge\nbehavior.\n\n### 3. `cde-tool`\n\nUse `cde-tool` when you want a repeatable model-to-source workflow.\n\nIt is intentionally optional.\n\nThe core value of CoreDataEvolution lives in the actor-isolation macros and the macro-based model\ndeclaration layer. You can use those directly without adopting the tool at all.\n\n`cde-tool` exists as an extra layer for teams that want stronger workflow guarantees, especially\nfor CI/CD, drift detection, and existing-project migration.\n\nIt helps with:\n\n- generating `@PersistentModel` source from an existing Core Data model\n- validating drift between `.xcdatamodeld` and source declarations\n- inspecting the resolved schema view used by the toolchain\n- applying safe autofix for deterministic issues\n\nThat first point is especially useful when adopting the package in an existing Core Data project:\nthe tool can quickly turn a legacy `.xcdatamodeld` into a usable `@PersistentModel` starting point,\nsimilar in spirit to Xcode's model code generation, but aligned with CoreDataEvolution's macro\nlayer.\n\nGuide:\n\n- [Docs/CDEToolGuide.md](./Docs/CDEToolGuide.md)\n\n## Core Features\n\n### SwiftData-style actor isolation for Core Data\n\n```swift\nimport CoreDataEvolution\n\n@NSModelActor\nactor ItemStore {\n  func renameItem(id: NSManagedObjectID, to newTitle: String) throws {\n    guard let item = self[id, as: Item.self] else { return }\n    item.title = newTitle\n    try modelContext.save()\n  }\n}\n```\n\nThis lets you keep Core Data while moving to a much cleaner isolation model.\n\n### Swift-first model declarations on top of `NSManagedObject`\n\n```swift\n@objc(Item)\n@PersistentModel\nfinal class Item: NSManagedObject {\n  @Attribute(persistentName: \"name\")\n  var title: String = \"\"\n\n  @Relationship(inverse: \"items\", deleteRule: .nullify)\n  var tag: Tag?\n}\n```\n\nThis is the most important thing to understand:\n\n- the source is Swift-first\n- the runtime is still Core Data\n- the model file is still part of the system\n\nFor relationships:\n\n- to-one properties generate a getter and setter\n- to-many properties (`Set\u003cT\u003e` / `[T]`) generate a getter only\n- mutate to-many relationships through generated helpers such as `addToTags`,\n  `removeFromTags`, and `insertIntoOrderedTags(_:at:)`\n\n### Typed key/path mapping for sort and predicate code\n\nThis is one of the library's distinctive features.\n\nWhen a Swift-facing property name differs from the stored schema name, the macro-generated typed path layer still resolves sort and predicate keys to the correct persistent field path.\n\nThat means you can write:\n\n```swift\nlet sort = try NSSortDescriptor(\n  Item.self,\n  path: Item.path.title,\n  order: .asc\n)\n\nlet predicate = NSPredicate(\n  format: \"%K == %@\",\n  Item.path.title.raw,\n  \"hello\"\n)\n```\n\nwhile the store still uses the original field name.\n\nGuide:\n\n- [Docs/TypedPathGuide.md](./Docs/TypedPathGuide.md)\n\n### Explicit storage strategy selection\n\nThe source layer makes storage strategy explicit instead of burying it in hand-written bridging code.\n\nSupported source-level storage choices include:\n\n- `.default`\n- `.raw`\n- `.codable`\n- `.transformed(...)`\n- `.composition`\n\nGuide:\n\n- [Docs/StorageMethodGuide.md](./Docs/StorageMethodGuide.md)\n\n## Important Preconditions\n\nThese are the points that new users most often need clarified.\n\n### `@PersistentModel` works with Core Data models\n\nFor production use, `@PersistentModel` is not a replacement for `.xcdatamodeld`.\n\nYou still build and maintain a Core Data model.\n\nThe macro layer is the source representation that sits on top of it.\n\nThat means:\n\n- you still need a Core Data source model for production workflows\n- `cde-tool` reads that model and helps generate/validate the Swift declaration layer\n- the macro-generated runtime schema is for test/debug scenarios, not for replacing the production model system\n- unsupported runtime primitive types fail generation instead of silently downgrading schema\n\n### Relationship `inverse` uses the persistent relationship name\n\nThis is easy to miss.\n\nIn:\n\n```swift\n@Relationship(\n  persistentName: \"primary_category\",\n  inverse: \"items\",\n  deleteRule: .nullify\n)\nvar category: Category?\n```\n\n`inverse` refers to the relationship name in the Core Data model on the other side.\n\nIt does **not** refer to the other Swift property name.\n\n### `composition` requires Core Data composite attribute support\n\n`@Composition` maps to Core Data composite attributes.\n\nFor schema-backed models, this means the Xcode model must declare a real top-level `Composite`\nattribute, not a pair of flattened entity fields and not a `Transformable` fallback.\n\nThat means it requires platform support for that Core Data feature:\n\n- iOS 17+\n- macOS 14+\n- tvOS 17+\n- watchOS 10+\n- visionOS 1+\n\nIf your deployment target is below those versions, do not use `composition`.\n\n## Runtime Schema for Tests and Debugging\n\nThe package also supports a pure Swift runtime-schema path for tests and debugging.\n\nExample:\n\n```swift\nlet model = try NSManagedObjectModel.makeRuntimeModel(Item.self, Tag.self)\n\nlet container = try NSPersistentContainer.makeRuntimeTest(\n  modelTypes: Item.self, Tag.self\n)\n```\n\nThis path is intentionally limited.\n\nIt is useful when you want:\n\n- test-only model construction\n- debug-only schema checks\n- non-Xcode workflows for tests\n\nIt is not intended to replace `.xcdatamodeld` in production.\n\n## `cde-tool` Workflow\n\nTypical workflow:\n\n1. start from a Core Data source model\n2. create a config\n3. generate `@PersistentModel` source\n4. add hand-written methods and computed properties in separate extension files\n5. validate drift over time\n\nTypical first setup:\n\n```bash\ncde-tool bootstrap-config \\\n  --model-path Models/AppModel.xcdatamodeld \\\n  --output cde-tool.json\n```\n\nThen:\n\n```bash\ncde-tool generate --config cde-tool.json\ncde-tool validate --config cde-tool.json\n```\n\n### Validation modes\n\n`cde-tool validate` supports two mental models:\n\n- `conformance`\n  - checks whether source follows the rules and matches the schema logically\n- `exact`\n  - additionally requires tool-managed files to match current generated output exactly\n\n`exact` is intentionally stricter and should not be the default workflow for every team.\n\nIf you use `exact`, keep these rules in mind:\n\n- do not hand-edit tool-managed files\n- do not let format/lint rewrite tool-managed files\n- add custom methods and computed properties in separate extension files\n\n## Recommended Project Structure\n\nA practical structure looks like this:\n\n- Core Data model in `Models/`\n- generated source in a dedicated generated folder\n- hand-written extensions in separate files\n- `cde-tool.json` checked into the repository\n\nExample:\n\n- `Models/AppModel.xcdatamodeld`\n- `Sources/AppModels/Generated/`\n- `Sources/AppModels/Item+Extras.swift`\n- `cde-tool.json`\n\nThis keeps generated and hand-written code clearly separated.\n\n## Where to Read Next\n\nStart here based on what you want to do.\n\n### If you want actor-isolated Core Data code\n\n- [Docs/NSModelActorGuide.md](./Docs/NSModelActorGuide.md)\n- [Core Data Reform: Achieving Elegant Concurrency Operations Like SwiftData](https://fatbobman.com/en/posts/core-data-reform-achieving-elegant-concurrency-operations-like-swiftdata/)\n\n### If you want Swift-first Core Data model declarations\n\n- [Docs/PersistentModelGuide.md](./Docs/PersistentModelGuide.md)\n\n### If you want SwiftUI to observe generated Core Data accessors\n\n- [Docs/ObservationGuide.md](./Docs/ObservationGuide.md)\n\n### If you want remapped fields to still work in sort and predicate code\n\n- [Docs/TypedPathGuide.md](./Docs/TypedPathGuide.md)\n\n### If you want to choose the right storage strategy\n\n- [Docs/StorageMethodGuide.md](./Docs/StorageMethodGuide.md)\n\n### If you want the CLI workflow\n\n- [Docs/CDEToolGuide.md](./Docs/CDEToolGuide.md)\n\n## Summary\n\nCoreDataEvolution is not trying to replace Core Data.\n\nIt is trying to make Core Data easier to use in modern Swift codebases by adding:\n\n- better isolation patterns\n- better model source declarations\n- better MainActor Observation integration for generated model accessors\n- better schema-to-source tooling\n- better typed mapping for renamed fields\n\nIf your project still relies on Core Data, but you want a source model and workflow that feel much\ncloser to modern Swift, that is the space this library is designed for.\n\n## System Requirements\n\n- iOS 13.0+ / macOS 10.15+ / watchOS 6.0+ / visionOS 1.0+ / tvOS 13.0+\n- Swift 6.0\n\nNote: The custom executor uses a compatible `UnownedJob` serial-executor path to support the minimum deployment targets.\n\n## Contributing\n\nWe welcome contributions! Whether you want to report issues, propose new features, or contribute to the code, feel free to open issues or pull requests on the GitHub repository.\n\n## License\n\nCoreDataEvolution is available under the MIT license. See the LICENSE file for more information.\n\n## Acknowledgments\n\nSpecial thanks to the Swift community for their continuous support and contributions.\nThanks to [@rnine](https://github.com/rnine) for sharing and validating the iOS 13+ compatibility approach that inspired this adaptation.\n\n## Support the project\n\n- [🎉 Subscribe to Fatbobman's Swift Weekly](https://weekly.fatbobman.com)\n- [☕️ Buy Me A Coffee](https://buymeacoffee.com/fatbobman)\n\n## Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=fatbobman/CoreDataEvolution\u0026type=Date)](https://star-history.com/#fatbobman/CoreDataEvolution\u0026Date)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffatbobman%2Fcoredataevolution","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffatbobman%2Fcoredataevolution","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffatbobman%2Fcoredataevolution/lists"}