{"id":15693555,"url":"https://github.com/shannonmoeller/apply-html","last_synced_at":"2025-05-08T04:20:45.974Z","repository":{"id":57141557,"uuid":"117005104","full_name":"shannonmoeller/apply-html","owner":"shannonmoeller","description":"It's `.innerHTML = ''` for the 21st century.","archived":false,"fork":false,"pushed_at":"2018-08-20T15:26:19.000Z","size":189,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-12T10:15:17.762Z","etag":null,"topics":["apply","diff","dom","html","js","patch"],"latest_commit_sha":null,"homepage":"http://npm.im/apply-html","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/shannonmoeller.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}},"created_at":"2018-01-10T20:07:12.000Z","updated_at":"2022-08-24T19:35:08.000Z","dependencies_parsed_at":"2022-09-03T07:00:16.662Z","dependency_job_id":null,"html_url":"https://github.com/shannonmoeller/apply-html","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shannonmoeller%2Fapply-html","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shannonmoeller%2Fapply-html/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shannonmoeller%2Fapply-html/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shannonmoeller%2Fapply-html/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shannonmoeller","download_url":"https://codeload.github.com/shannonmoeller/apply-html/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252997380,"owners_count":21837809,"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":["apply","diff","dom","html","js","patch"],"created_at":"2024-10-03T18:45:31.287Z","updated_at":"2025-05-08T04:20:45.947Z","avatar_url":"https://github.com/shannonmoeller.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# apply-html\n\n[![NPM version][npm-img]][npm-url] [![Downloads][downloads-img]][npm-url] [![Build Status][travis-img]][travis-url] [![Coverage Status][coveralls-img]][coveralls-url]\n\nIt's `.innerHTML = ''` for the 21st century!\n\nYet another library to diff and patch an existing DOM tree by efficiently comparing it to a string. Why? This library is a little bit different than [others](#acknowledgements). It makes use of an [HTML `\u003ctemplate\u003e`'s](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template) unique ability to create an inert [document fragment](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment), featuring:\n\n- A real DOM tree\n- Multiple root nodes\n- Will not trigger resource loading prematurely\n- Will not apply embedded stylesheets prematurely\n- Will not trigger custom element constructors or lifecycle events prematurely\n\nThe live DOM is then patched with the inert fragment using a hyper-fast [diffing algorithm](http://npm.im/nanomorph) for real DOM nodes. This ensures that things only start happening if and when they're supposed to, organically.\n\nPlay with it on [CodePen](https://codepen.io/shannonmoeller/pen/XZXBpE?editors=1111).\n\n## Install\n\n```command\n$ npm install --save apply-html\n```\n\nor\n\n```html\n\u003cscript src=\"https://wzrd.in/standalone/apply-html\"\u003e\u003c/script\u003e\n```\n\nor\n\n```html\n\u003cscript type=\"module\"\u003e\n    import { apply, html } from 'https://unpkg.com/apply-html?module';\n\u003c/script\u003e\n```\n\n## Usage\n\n### Patching\n\n```js\nconst { apply } = require('apply-html');\n\napply(document.body, '\u003ch1 class=\"day\"\u003eHello World\u003c/h1\u003e');\n\nconsole.log(document.body.innerHTML);\n// -\u003e \u003ch1 class=\"day\"\u003eHello World\u003c/h1\u003e\n\napply(document.body, '\u003ch1 class=\"night\"\u003eGoodnight Moon\u003c/h1\u003e');\n\nconsole.log(document.body.innerHTML);\n// -\u003e \u003ch1 class=\"night\"\u003eGoodnight Moon\u003c/h1\u003e\n```\n\n### Interpolation and Escaping\n\n```js\nconst { apply, html, raw } = require('apply-html');\n\nconst foo = '\u003cem\u003efoo\u003c/em\u003e';\nconst bar = raw('\u003cem\u003ebar\u003c/em\u003e');\nconst baz = html`\u003cstrong\u003ebaz\u003c/strong\u003e`;\n\napply(document.body, html`\n    ${foo}\n    ${bar}\n    ${baz}\n`);\n\nconsole.log(document.body.innerHTML);\n// -\u003e \u0026lt;em\u0026gt;foo\u0026lt;/em\u0026gt;\n// -\u003e \u003cem\u003ebar\u003c/em\u003e\n// -\u003e \u003cstrong\u003ebaz\u003c/strong\u003e\n```\n\n### Server-side Rendering\n\nThe `html` and `raw` functions never touch the DOM so they're completely safe to use server-side.\n\n```js\nconst http = require('http');\nconst { html } = require('apply-html');\n\nconst content = html`\n    \u003ch1\u003eHello \u003cem\u003eWorld\u003c/em\u003e\u003c/h1\u003e\n    \u003cp\u003eHow are you today?\u003c/p\u003e\n`;\n\nmodule.exports = http\n    .createServer((req, res) =\u003e res.end(content.toString()))\n    .listen(3000);\n```\n\n## API\n\n### `apply(element, string): Element`\n\n- `element` `{Element}` DOM element with children to be patched.\n- `string` `{String|SafeString}` String or [SafeString](#safestring) containing safe HTML to render.\n\nUpdates the content of the given element, making the fewest possible changes required to match the given string of HTML. The string is converted into an HTML `\u003ctemplate\u003e` and the resulting DOM trees are compared. Returns the updated element.\n\n### `` html`string`: SafeString ``\n\nA template tag that creates a new [SafeString](#safestring) containing a string of HTML. Interpolated values are serialized based on type:\n\n- `Array` - Items are serialized then joined with an empty string (`''`).\n- `Boolean|null|undefined` - Converted to an empty string (`''`).\n- `Function` - Throws a `TypeError`.\n- `Number` - Inserted as-is.\n- `Object` - Converted to an HTML-encoded JSON blob.\n- `SafeString` - Inserted as-is.\n- `String` - HTML-encoded to safeguard against [XSS](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)). To opt out of escaping, use [`raw()`](#rawstring-safestring).\n\n### `raw(string): SafeString`\n\n- `string` `{String}` String of safe HTML.\n\nWraps a string in a [SafeString](#safestring) to indicate that it's safe to be inserted into the document. Only use on trusted strings to safeguard against [XSS](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)).\n\n## SafeString\n\n### `.raw` `{String}`\n\nThe wrapped string.\n\n### `.length` `{Number}`\n\nLength of the wrapped string. Read only.\n\n### `.toJSON(): String`\n\nReturns the raw string.\n\n### `.toString(): String`\n\nReturns the raw string.\n\n## Acknowledgements\n\nStanding on the shoulders of these giants:\n\n- [bel](http://npm.im/bel)\n- [diff-dom](http://npm.im/diff-dom)\n- [domdiff](http://npm.im/domdiff)\n- [hyperhtml](http://npm.im/hyperhtml)\n- [lit-html](http://npm.im/lit-html)\n- [morphdom](http://npm.im/morphdom)\n- [nanomorph](http://npm.im/nanomorph)\n- [preact](http://nipm.im/preact)\n- [snabbdom](http://npm.im/snabbdom)\n- [react](http://nipm.im/react)\n- [vue.js](http://npm.im/vue)\n- and [more...](https://rawgit.com/krausest/js-framework-benchmark/master/webdriver-ts-results/table.html)\n\n----\n\nMIT © [Shannon Moeller](http://shannonmoeller.com)\n\n[coveralls-img]: http://img.shields.io/coveralls/shannonmoeller/apply-html/master.svg?style=flat-square\n[coveralls-url]: https://coveralls.io/r/shannonmoeller/apply-html\n[downloads-img]: http://img.shields.io/npm/dm/apply-html.svg?style=flat-square\n[npm-img]:       http://img.shields.io/npm/v/apply-html.svg?style=flat-square\n[npm-url]:       https://npmjs.org/package/apply-html\n[travis-img]:    http://img.shields.io/travis/shannonmoeller/apply-html.svg?style=flat-square\n[travis-url]:    https://travis-ci.org/shannonmoeller/apply-html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshannonmoeller%2Fapply-html","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshannonmoeller%2Fapply-html","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshannonmoeller%2Fapply-html/lists"}