{"id":13482064,"url":"https://github.com/b-fuze/deno-dom","last_synced_at":"2025-05-15T09:08:01.781Z","repository":{"id":39493386,"uuid":"261737486","full_name":"b-fuze/deno-dom","owner":"b-fuze","description":"Browser DOM \u0026 HTML parser in Deno","archived":false,"fork":false,"pushed_at":"2025-02-08T21:06:49.000Z","size":5760,"stargazers_count":451,"open_issues_count":44,"forks_count":45,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-05-10T01:04:18.420Z","etag":null,"topics":["browser-dom","deno","dom","html-parser","rust","typescript","wasm"],"latest_commit_sha":null,"homepage":"https://jsr.io/@b-fuze/deno-dom","language":"HTML","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/b-fuze.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":"2020-05-06T11:25:15.000Z","updated_at":"2025-05-07T11:19:45.000Z","dependencies_parsed_at":"2024-01-13T18:14:52.815Z","dependency_job_id":"92a4ab8d-97b1-4880-afd7-6ed2f6e2155c","html_url":"https://github.com/b-fuze/deno-dom","commit_stats":{"total_commits":298,"total_committers":26,"mean_commits":"11.461538461538462","dds":"0.30201342281879195","last_synced_commit":"b3dd092e213fb24fd223ecfc256bb81ca0760b37"},"previous_names":[],"tags_count":60,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b-fuze%2Fdeno-dom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b-fuze%2Fdeno-dom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b-fuze%2Fdeno-dom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b-fuze%2Fdeno-dom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/b-fuze","download_url":"https://codeload.github.com/b-fuze/deno-dom/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254310520,"owners_count":22049470,"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":["browser-dom","deno","dom","html-parser","rust","typescript","wasm"],"created_at":"2024-07-31T17:00:58.680Z","updated_at":"2025-05-15T09:07:56.773Z","avatar_url":"https://github.com/b-fuze.png","language":"HTML","funding_links":[],"categories":["HTML"],"sub_categories":[],"readme":"# Deno DOM\n\nAn implementation of the browser DOM—primarily for SSR—in Deno. Implemented with\nRust, WASM, and obviously, Deno/TypeScript.\n\n## Example\n\n```typescript\nimport { DOMParser, Element } from \"jsr:@b-fuze/deno-dom\";\n\n//   non-JSR wasm url import: https://deno.land/x/deno_dom/deno-dom-wasm.ts\n// non-JSR native url import: https://deno.land/x/deno_dom/deno-dom-native.ts\n\nconst doc = new DOMParser().parseFromString(\n  `\n    \u003ch1\u003eHello World!\u003c/h1\u003e\n    \u003cp\u003eHello from \u003ca href=\"https://deno.land/\"\u003eDeno!\u003c/a\u003e\u003c/p\u003e\n  `,\n  \"text/html\",\n);\n\nconst p = doc.querySelector(\"p\")!;\n\nconsole.log(p.textContent); // \"Hello from Deno!\"\nconsole.log(p.childNodes[1].textContent); // \"Deno!\"\n\np.innerHTML = \"DOM in \u003cb\u003eDeno\u003c/b\u003e is pretty cool\";\nconsole.log(p.children[0].outerHTML); // \"\u003cb\u003eDeno\u003c/b\u003e\"\n```\n\nDeno DOM has **two** backends, WASM and native using Deno native plugins. Both\nAPIs are **identical**, the difference being only in performance. The WASM\nbackend works with all Deno restrictions, but the native backend requires the\n`--unstable-ffi --allow-ffi --allow-env --allow-read --allow-net=deno.land`\nflags. A shorter version could be `--unstable-ffi -A`, but that allows all\npermissions so you'd have to assess your risk and requirements. You can switch\nbetween them by importing either `jsr:@b-fuze/deno-dom` for WASM or\n`jsr:@b-fuze/deno-dom/native` for the native binary.\n\nDeno DOM is still under development, but is fairly usable for basic HTML\nmanipulation needs.\n\n### WebAssembly Startup Penalty\n\nDeno suffers an initial startup penalty in Deno DOM WASM due to Top Level Await\n(TLA) preparing the WASM parser. As an alternative to running the initiation on\nstartup, you can initialize Deno DOM's parser on-demand yourself when you need\nit by importing from `jsr:@b-fuze/deno-dom/wasm-noinit`. Example:\n\n```typescript\nimport { DOMParser, initParser } from \"jsr:@b-fuze/deno-dom/wasm-noinit\";\n\n// ...and when you need Deno DOM make sure you initialize the parser...\nawait initParser();\n\n// Then you can use Deno DOM as you would normally\nconst doc = new DOMParser().parseFromString(\n  `\n    \u003ch1\u003eLorem ipsum dolor...\u003c/h1\u003e\n  `,\n  \"text/html\",\n);\n```\n\n## Documentation\n\nRefer to MDN (Mozilla Developer Network) for documentation. If there are\ninconsistencies (that aren't a result of legacy APIs) file an issue.\n\n## Goals\n\n- HTML parser in Deno\n- Fast\n- Mirror _most_ supported DOM APIs as closely as possible\n- Provide specific APIs in addition to DOM APIs to make certain operations more\n  efficient, like controlling Shadow DOM\n- Use cutting-edge JS features like private class members, optional chaining,\n  etc\n\n## Non-Goals\n\n- Headless browser implementation\n- Ability to run JS embedded in documents (`\u003cscript\u003e` tags, `onload`, etc)\n- Parse CSS or JS (they're just text, but this may be supported in the future\n  for CSSOM)\n- Support older (or even not so old) JS engines. In other words, there will be\n  no support of transpilation to ES5, no support of polyfills, etc\n- Support special functionality of obsolete HTML elements (`\u003cmarquee\u003e`, etc)\n\n## Running tests\n\nTo run tests (excluding WPT tests) use the following for WASM\n\n```sh\ndeno test --allow-read --allow-net wasm.test.ts\n```\n\nOr the following for native (native requires more permissions)\n\n```sh\ndeno test --unstable -A native.test.ts\n```\n\nTo run WPT tests update the WPT submodule\n\n```sh\ngit submodule update --progress --depth 1\n```\n\nThen append `-- --wpt` to the test command before running it, e.g. for WASM\n\n```sh\ndeno test --allow-read --allow-net wasm.test.ts -- --wpt\n```\n\nWPT tests are still a WIP, passed tests likely haven't actually passed.\n\n## Building Deno DOM Native\n\nDeno DOM native is a faster backend for Deno DOM (check [benchmarks](./bench/)),\nhowever, the WASM backend is sufficient for almost all use-cases.\n\n**Note:** If you're running an x86\\_64 system with either Windows, Linux, or\nmacOS, then you probably don't need to build the plugin. Deno DOM native\ndownloads a prebuilt binary in those cases.\n\nTo build Deno DOM's native backend,\n[install Rust](https://www.rust-lang.org/learn/get-started) if you haven't\nalready, then run\n\n```sh\ncargo build --release\n```\n\nwhich produces a binary located at `target/release/libplugin.{so,dll,dylib}`\n(extension depends on your system).\n\nTo use the new binary you need to set the **`DENO_DOM_PLUGIN`** env var to the\npath of the binary produced in the previous step. **Don't forget** to run Deno\nwith `--allow-env`.\n\n## Inconsistencies with standard APIs\n\n### Differences in `DOMTokenList`/`Element.classList`\n\nTo optimize memory usage, Deno DOM doesn't allocate `DOMTokenList`s\n(`Element.classList`) on `Element` creation, it instead creates an\n`UninitializedDOMTokenList` object. This can cause a subtle deviation from\nstandard APIs:\n\n```typescript\nconst div = doc.createElement(\"div\");\n\n// Retrieve the uninitialized DOMTokenList\nconst { classList } = div;\n\n// Initialize the DOMTokenList by adding a few classes\nclassList.add(\"foo\");\nclassList.add(\"bar\");\n\n// Inconsistency: the uninitialized classList/DOMTokenList\n// is now a different object from the initialized one\n\nclassList !== div.classList;\n\n// However, the uninitialized DOMTokenList object still\n// works as the initialized DOMTokenList object:\n\nclassList.add(\"fizz\");\ndiv.classList.contains(\"fizz\") === true;\n```\n\n# Credits\n\n- html5ever developers for the HTML parser\n- nwsapi developers for the selector parser\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb-fuze%2Fdeno-dom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fb-fuze%2Fdeno-dom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb-fuze%2Fdeno-dom/lists"}