{"id":20025042,"url":"https://github.com/quicoto/two-way-data-binding","last_synced_at":"2026-06-05T22:31:05.867Z","repository":{"id":41653356,"uuid":"510334788","full_name":"quicoto/two-way-data-binding","owner":"quicoto","description":"Minimal two way data binding in vanilla JS","archived":false,"fork":false,"pushed_at":"2026-05-11T05:26:22.000Z","size":991,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-05-11T07:24:39.993Z","etag":null,"topics":["javascript","two-way-databinding"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/quicoto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"docs/CODE_OF_CONDUCT.md","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":null,"dco":null,"cla":null}},"created_at":"2022-07-04T11:39:29.000Z","updated_at":"2026-05-11T05:25:58.000Z","dependencies_parsed_at":"2023-02-14T05:31:56.455Z","dependency_job_id":"62801ae7-1885-4d16-a542-204a71184924","html_url":"https://github.com/quicoto/two-way-data-binding","commit_stats":{"total_commits":88,"total_committers":6,"mean_commits":"14.666666666666666","dds":"0.40909090909090906","last_synced_commit":"818d12287ea5d0cfe66e72ab0abea40a5bf37838"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/quicoto/two-way-data-binding","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicoto%2Ftwo-way-data-binding","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicoto%2Ftwo-way-data-binding/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicoto%2Ftwo-way-data-binding/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicoto%2Ftwo-way-data-binding/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quicoto","download_url":"https://codeload.github.com/quicoto/two-way-data-binding/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicoto%2Ftwo-way-data-binding/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33962959,"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-05T02:00:06.157Z","response_time":120,"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":["javascript","two-way-databinding"],"created_at":"2024-11-13T08:53:01.549Z","updated_at":"2026-06-05T22:31:05.846Z","avatar_url":"https://github.com/quicoto.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Two way data binding\n\nMinimal no-dependencies 1.2kb (756B gzipped) two way data binding in vanilla JS.\n\n[![Version](https://img.shields.io/npm/v/two-way-data-binding.svg)](https://npmjs.org/package/two-way-data-binding)\n[![Build Status](https://github.com/quicoto/two-way-data-binding/workflows/CI/badge.svg?branch=main)](https://github.com/quicoto/two-way-data-binding/actions)\n[![CodeQL Analysis](https://github.com/quicoto/two-way-data-binding/workflows/CodeQL/badge.svg?branch=main)](https://github.com/quicoto/two-way-data-binding/actions)\n[![semver: semantic-release](https://img.shields.io/badge/semver-semantic--release-blue.svg)](https://github.com/semantic-release/semantic-release)\n[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n## Install\n\n```bash\nnpm i two-way-data-binding\n```\n\n## How to use\n\nIt works with DOM elements such as:\n\n- Layout: div, span, p, headings (anything with textContent or innerHTML)\n- Form elements:\n  - Input (including checkbox, radio)\n  - Textarea\n  - Select\n\n### Basic usage\n\n```html\n\u003ch1 data-bind=\"name\"\u003eDefault value\u003c/h1\u003e\n\u003cinput type=\"text\" data-model=\"name\"/\u003e\n```\n\n```javascript\nimport TwoWayDataBinding from 'two-way-data-binding'\n\nTwoWayDataBinding({\n  dataModel: {\n    name: 'My Awesome Site'\n  },\n})\n```\n\n### Several elements with the same bind\n\n```html\n\u003cp data-bind=\"description\"\u003eDefault description\u003c/p\u003e\n\u003cinput type=\"text\" data-bind=\"description\" data-model=\"description\"/\u003e\n```\n\n```javascript\nimport TwoWayDataBinding from 'two-way-data-binding'\n\nTwoWayDataBinding()\n```\n\n### Update model via JavaScript\n\nYou can use deep objects too:\n\n```javascript\nconst proxy = TwoWayDataBinding({\n  dataModel: {\n    site: {\n      name: 'My Awesome Site'\n    }\n  },\n})\n\nproxy.site.name = `New name`;\n```\n\n## Configuration\n\n### `$context`\n\nOptional. Defines the context of the data model. Defaults to `document`\n\n### `attributeBind`\n\nOptional. Defines the attribute to bind to in your HTML. Defaults to `data-bind`\n\n### `attributeModel`\n\nOptional. Defines the attribute to bind to in your HTML. Defaults to `data-model`\n\n```javascript\n$myInput.addEventListener('twowaydatabinding:change', () =\u003e {\n  // This will be fired after the native change, after we update the state\n});\n```\n\n### `dataModel`\n\nOptional. Defines the data model. Defaults to `{}`\n\n### `events`\n\nOptional. Defines the events to bind to. Defaults to ```[`keyup`, `change`]```\n\n### `pathDelimiter`\n\nOptional. Defines the path delimiter in your `data-bind` attributes such as `header.site.name`. Defaults to `.`\n\n## Custom events handling\n\nIn order to allow consumers to perform actions **after** TwoWayDataBinding performs model update, a custom event is fired with the name `twowaydatabinding:change|keyup|eventname`. By default is dispatched in `change` and `keyup` events, but it can be extended by setting more `events` in the array of the TwoWayDataBinding configuration, meaning a `twowaydatabinding:[eventname]` will be fired after the logic is executed, and the consumer application can subscribe to them to perform any needed logic after the library has done the operations.\n\n### \u003ca id=\"setcustomvalue\"\u003e\u003c/a\u003e`twowaydatabinding:setcustomvalue`\nThis event works the other way round, from the consumer application to TwoWayDataBinding, which is listening to that event and responds by setting in the data model the value passed for a given property.\n\nThe library can prevent setting the value to the model for certain custom-value properties (see [attributeCustomValue](#attributecustomvalue)), and for those cases, a custom event `twowaydatabinding:setcustomvalue` can be fired in order to set a value into the model. A `twowaydatabinding:change` event is fired again after performing this action.\n\nTo set the new value in the data model, dispatch the event in the correspondant element passing a `detail` object populated with `path` (property path of the property to change in the data model object) and `value` properties.\n\nTo trigger it from your application:\n\n```javascript\ninput.dispatchEvent(new CustomEvent(`twowaydatabinding:setcustomvalue`, {\n  bubbles: true,\n  cancelable: true,\n  detail: {\n    path: input.getAttribute(config.attributeModel),\n    value: dataValue\n  }\n}));\n\nproxy.propName // 'newValue'\n```\n\n## Setting a custom value to a bound input instead of his value in the data model\n### \u003ca id=\"attributecustomvalue\"\u003e\u003c/a\u003e`attributeCustomValue`\n\nOptional. Defines an array of attributes to prevent the model being updated with the input value when `change` or `keyup` by default. Defaults to `['data-value']`.\n\nIf an input has `data-model` and `data-bind` attributes at the same time, when this input value is changed, the model gets updated with that input `value` property. Nevertheless, this can be prevented by adding a custom attribute which will be the host of the actual value.\n\nBy default is `['data-value']` (but can be customised and extended), and when an input has one of these attributes, the model is not updated with the value of the input and it should be manually updated by the consumer's application logic by dispatching a custom event `twowaydatabinding:setcustomvalue`. See [Custom Events handling](#setcustomvalue)\n\n## Browser support\n\nThe script does **not** include any polyfills.\n\n| Browser | Version  |\n|---------------|---|\n| Google Chrome | \u003e= 96  |\n| Edge        | \u003e= 92  |\n| Firefox       | \u003e= 91 |\n| Safari        | \u003e= 15.4  |\n| Opera        | \u003e= 76  |\n| IE        | ❌  |\n\n## How to develop\n\nYou might want to develop locally. Spawn a local server with:\n\n```bash\nnpm run develop\n```\n\nYou can change `/develop/index.html` and `/develop/index.js` to your liking.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquicoto%2Ftwo-way-data-binding","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquicoto%2Ftwo-way-data-binding","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquicoto%2Ftwo-way-data-binding/lists"}