{"id":26207196,"url":"https://github.com/oelin/chime","last_synced_at":"2025-10-11T12:13:20.683Z","repository":{"id":89778589,"uuid":"607187861","full_name":"oelin/chime","owner":"oelin","description":"A tiny, declarative UI library.","archived":false,"fork":false,"pushed_at":"2023-03-22T12:14:55.000Z","size":84,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-29T05:42:29.783Z","etag":null,"topics":["declarative-programming","functional-programming","ui"],"latest_commit_sha":null,"homepage":"https://npmjs.com/chime","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/oelin.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}},"created_at":"2023-02-27T13:52:15.000Z","updated_at":"2023-02-27T20:29:01.000Z","dependencies_parsed_at":"2025-03-12T05:31:19.582Z","dependency_job_id":"956c75bc-1b60-44ab-890e-f721a2813042","html_url":"https://github.com/oelin/chime","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oelin/chime","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Fchime","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Fchime/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Fchime/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Fchime/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oelin","download_url":"https://codeload.github.com/oelin/chime/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Fchime/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279007140,"owners_count":26084246,"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-10-11T02:00:06.511Z","response_time":55,"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":["declarative-programming","functional-programming","ui"],"created_at":"2025-03-12T05:31:10.068Z","updated_at":"2025-10-11T12:13:20.671Z","avatar_url":"https://github.com/oelin.png","language":"JavaScript","readme":"# Chime\n\nA tiny, declarative UI framework.\n\n**[Getting Started](#getting-started) | [Installation](#installation) | [API](#api)**\n\n```js\nfunction App() {\n    const username = ref('Alice')\n    const password = ref('')\n\n    return element('div')\n        .element('input')\n            .set('placholder', 'username')\n            .set('value', username)\n            .end()\n        .element('input')\n            .set('placeholder', 'password')\n            .set('value', password)\n            .end()\n}\n```\n\n\u003cimg src='https://github.com/oelin/chime/blob/main/images/form.png' width=100%\u003e\n\n\n## Getting Started\n\nChime is a tiny UI library which makes use of function chaining to construct UIs in a declarative style. The core library only contains a few DOM functions however it can be very easily extended via plugins using the `use()` API (for example to support two-way data binding). While Chime doesn't allow you to create views in HTML syntax, functional chaining allows you to achieve comparable succinctness while also being declarative.\n\n\n### Constructing Views\n\nChime works by implementing several chainable functions in the prototype of `HTMLElement`, allowing them to be used on any HTML element. Chime exports `Element()` (an alias of `document.createElement()`), which can be used as the root of a view. To append a child to an existing element, simply call `.Element()` on the element. For example:\n\n```js\nElement('div').Element('a') // \u003ca\u003e\u003c/a\u003e\n```\n\nThis returns the inner `\u003ca\u003e` element. To access the parent element, chain on `.end()`:\n\n```js\nElement('div')    // \u003cdiv\u003e\n    .Element('a') //     \u003ca\u003e\u003c/a\u003e\n    .end()        // \u003c/div\u003e\n```\n\nThe `.end()` method can be thought of like a closing tag for the current element. As such, it can be used to construct nested DOMs. For example:\n\n```js\nElement('div')       // \u003cdiv\u003e\n    .Element('p')    //     \u003cp\u003e\n        .text('foo') //         foo\n        .end()       //     \u003c/p\u003e\n    .Element('div')  //     \u003cdiv\u003e\n        .text('bar') //         bar\n        .end()       //     \u003c/div\u003e\n    .end()           // \u003c/div\u003e\n```\n\nTo reduce boilerplate, Chime also provides the `top()` function which returns the root element of a tree. For example, consider this set of nested `div` elements:\n\n```js\nElement('div')\n    .Element('div')\n        .Element('div')\n            .Element('div')\n                .Element('div')\n                    .end()\n                .end()\n            .end()\n        .end()\n    .end()\n```\n\nUsing `top()` we can divide the line count in half:\n\n```js\nElement('div')\n    .Element('div')\n        .Element('div')\n            .Element('div')\n                .Element('div')\n                    .top()\n```\n\n\n### Manipulating Elements\n\nApart from constructing views, Chime also allows you to easily modify the content and/or attributes of individual DOM elements. The `attribute()` function can be used to set an attribute on an element. For example:\n\n```js\nElement('div').attribute('class', 'foo') // \u003cdiv class='foo'\u003e\u003c/div\u003e\n```\n\nAnother important function is `when()` which allows you to add event listeners to elements. For example:\n\n```js\nElement('button')\n   .text('Click me!')\n   .event('click', () =\u003e console.log('Button clicked!'))\n```\n\n\n## Installation\n\n```sh\nnpm i chime\n```\n\n\n## API\n\nMost of the functions exported by the library are fairly self-explanatory.\n\n* `Element(name: String) -\u003e HTMLElement` - creates a new element (an alias of `document.createElement`).\n\nThe following functions are prototyped on `HTMLElement`:\n\n* `Element(name: String) -\u003e HTMLElement` - adds a new child element to the current element.\n\n* `attribute(name: String, value: String) -\u003e HTMLElement` - sets an attribute on the current element.\n\n* `text(value: String) -\u003e HTMLElement` - sets the `innerText` of the current element.\n\n* `when(name: String, callback: Function) -\u003e HTMLElement` - registers an event listener on the current element.\n\nFinally, the `use()` API can be used to add new functions to the prototype of `HTMLElement`. This is the easiest way to develop plugins for Chime. For example, to implement data-binding:\n\n```js\nclass Variable {\n    constructor(value) {\n        this.value = value\n        this.subscribers = []\n    }\n\n    set(value) {\n        this.value = value\n        this.subscribers.forEach(callback =\u003e callback(value))\n    }\n\n    subscribe(callback) {\n        this.subscribers.push(callback)\n        callback(this.value)\n    }\n}\n\n\nuse('binding', function(variable) {\n\n    variable.subscribe(value =\u003e this.attribute('value', value))\n    return this.event('input', () =\u003e variable.attribute(this.value))\n}\n```\n\n\u003e Note that when writing plugins, you should typically return the current element to allow for further function chaining.\n\nThis function can then be used when constructing views:\n\n```js\nfunction App() {\n    const username = new Variable('Alice')\n\n    return Element('div')\n        .Element('input').binding(username)\n        .top()\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foelin%2Fchime","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foelin%2Fchime","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foelin%2Fchime/lists"}