{"id":16691299,"url":"https://github.com/dphilipson/pure-assign","last_synced_at":"2025-10-06T22:13:04.772Z","repository":{"id":66182115,"uuid":"77811508","full_name":"dphilipson/pure-assign","owner":"dphilipson","description":"Drop-in replacement for Object.assign() for \"updating\" immutable objects.","archived":false,"fork":false,"pushed_at":"2018-12-05T18:51:14.000Z","size":113,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-07T19:01:03.761Z","etag":null,"topics":["assign","immutable","typescript","update"],"latest_commit_sha":null,"homepage":null,"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/dphilipson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2017-01-02T04:50:27.000Z","updated_at":"2020-07-18T04:04:57.000Z","dependencies_parsed_at":"2023-02-20T17:15:57.256Z","dependency_job_id":null,"html_url":"https://github.com/dphilipson/pure-assign","commit_stats":{"total_commits":26,"total_committers":2,"mean_commits":13.0,"dds":"0.42307692307692313","last_synced_commit":"7075423bb9b0dbe7b6707308b5d9f86963b1850d"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/dphilipson/pure-assign","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dphilipson%2Fpure-assign","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dphilipson%2Fpure-assign/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dphilipson%2Fpure-assign/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dphilipson%2Fpure-assign/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dphilipson","download_url":"https://codeload.github.com/dphilipson/pure-assign/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dphilipson%2Fpure-assign/sbom","scorecard":{"id":354351,"data":{"date":"2025-08-11","repo":{"name":"github.com/dphilipson/pure-assign","commit":"7075423bb9b0dbe7b6707308b5d9f86963b1850d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/26 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENCE:0","Info: FSF or OSI recognized license: MIT License: LICENCE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"66 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-q42p-pg8m-cqh6","Warn: Project is vulnerable to: GHSA-w457-6q6x-cgp9","Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f","Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p","Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv","Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8","Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65","Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-4xcv-9jjx-gfj3","Warn: Project is vulnerable to: GHSA-7wpw-2hjm-89gp","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-3f95-r44v-8mrg","Warn: Project is vulnerable to: GHSA-28xr-mwxg-3qc8","Warn: Project is vulnerable to: GHSA-9p95-fxvg-qgq2","Warn: Project is vulnerable to: GHSA-9w5j-4mwv-2wj8","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T09:10:37.917Z","repository_id":66182115,"created_at":"2025-08-18T09:10:37.917Z","updated_at":"2025-08-18T09:10:37.917Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271746777,"owners_count":24813583,"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-23T02:00:09.327Z","response_time":69,"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":["assign","immutable","typescript","update"],"created_at":"2024-10-12T16:07:46.006Z","updated_at":"2025-10-06T22:13:04.671Z","avatar_url":"https://github.com/dphilipson.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pure Assign\n\nDrop-in replacement for\n[`Object.assign()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)\nfor \"updating\" immutable objects. Unlike `Object.assign()`, `pureAssign()` will\nnot mutate the base object, nor will it create a new object if no properties\nchange.\n\n[![Build\nStatus](https://travis-ci.org/dphilipson/pure-assign.svg?branch=master)](https://travis-ci.org/dphilipson/pure-assign)\n\n## Installation\n\nWith Yarn:\n\n```\nyarn add pure-assign\n```\n\nWith NPM:\n\n```\nnpm install pure-assign\n```\n\n## Usage in Brief\n\n```ts\npureAssign(object, ...updates);\n```\n\nis equivalent to\n\n```ts\nObject.assign({}, object, ...updates);\n```\n\nexcept that it returns the original instance `object` if the result would have\nthe same values as the original.\n\n## Usage in Detail\n\n`pureAssign()` takes one or more arguments. The first argument is a base object,\nand the remaining arguments are any number of objects whose properties should be\nmerged with those of the base object to produce a new object. Unlike\n[`Object.assign()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign),\nthe first argument is not modified. For example:\n\n```ts\nimport pureAssign from \"pure-assign\";\n\nconst user = { firstName: \"Anastasia\", lastName: \"Steele\" };\nconst updatedUser = pureAssign(user, { firstName: \"Ana\" });\nconsole.log(user); // -\u003e { firstName: \"Anastasia\", lastName: \"Steele\" }\nconsole.log(updatedUser); // -\u003e { firstName: \"Ana\", lastName: \"Steele\" }\n```\n\nIf the resulting object would differ from the original, then a new object is\ncreated and returned. Otherwise, the original instance is returned. For example:\n\n```ts\nconst user = { firstName: \"Anastasia\", lastName: \"Steele\" };\nconst updatedUser = pureAssign(user, { firstName: \"Anastasia\" });\nconsole.log(user === updatedUser); // -\u003e true\n```\n\nFor TypeScript users, `pureAssign` has an additional advantage in that it\ncatches type errors of the following form, which would be uncaught if using\n`Object.assign()` or object spread:\n\n```javascript\nconst user = { firstName: \"Anastasia\", lastName: \"Steele\" };\nconst updatedUser = pureAssign(userObject, { firstNarm: \"Ana\" });\n// Type error because \"firstNarm\" is not a property of user.\n```\n\n## Motivation\n\nMany JavaScript programs treat objects as immutable data. For instance, this is\nrecommended by React and required by Redux. Such programs typically replace\nobject mutation:\n\n```javascript\nconst user = { firstName: \"Anastasia\", lastName: \"Steele\" };\nuser.firstName = \"Ana\";\n```\n\nwith calls to `Object.assign()`, creating a new object with the updated values:\n\n```javascript\nconst updatedUser = Object.assign({}, user, {\n    firstName: \"Ana\",\n});\n```\n\nor alternatively with [ES7's spread\noperator](https://github.com/sebmarkbage/ecmascript-rest-spread) and an\nappropriate transpiler:\n\n```javascript\nconst updatedUser = { ...user, firstName: \"Ana\" };\n```\n\nA drawback of this approach is that a new object is created even if the new\nproperties are identical to the old ones. This may have performance implications\nif certain updates are triggered by data \"changes.\" For example, React\ndevelopers may attempt to avoid unnecessary re-renders by using\n[`PureComponent`](https://reactjs.org/docs/react-api.html#reactpurecomponent) or\n[`React.memo()`](https://reactjs.org/docs/react-api.html#reactmemo), which only\nperforms an update if its props have \"changed\" according to a shallow-equality\ncheck. This means that if your updates create new objects with the same values,\nthey will trigger unnecessary rerenders since the old props do not have\nobject-equality with the new props, despite being functionally identical.\n\nThis is where `pureAssign()` comes in. By returning the same instance in cases\nwhere the values haven't changed, `pureAssign` avoids triggering unnecessary\nupdates which use object-equality to determine whether the state has changed.\n\nCopyright © 2017 David Philipson\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdphilipson%2Fpure-assign","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdphilipson%2Fpure-assign","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdphilipson%2Fpure-assign/lists"}