Using deno-dom with Deno

deno-dom is an implementation of DOM and HTML parser in Deno. It is implemented in Rust (via Wasm) and TypeScript. There is also a “native” implementation, leveraging the FFI interface.

deno-dom aims for specification compliance, like jsdom and unlike LinkeDOM. Currently, deno-dom is slower than LinkeDOM for things like parsing data structures, but faster at some manipulation operations. Both deno-dom and LinkeDOM are significantly faster than jsdom.

As of deno_dom v0.1.22-alpha supports running on Deno Deploy. So if you want strict standards alignment, consider using deno-dom over LinkeDOM.

Basic example

This example will take a test string and parse it as HTML and generate a DOM structure based on it. It will then query that DOM structure, picking out the first heading it encounters and print out the text content of that heading:

  1. import { DOMParser } from "https://deno.land/x/deno_dom/deno-dom-wasm.ts";
  2. import { assert } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts";
  3. const document = new DOMParser().parseFromString(
  4. `<!DOCTYPE html>
  5. <html lang="en">
  6. <head>
  7. <title>Hello from Deno</title>
  8. </head>
  9. <body>
  10. <h1>Hello from Deno</h1>
  11. <form>
  12. <input name="user">
  13. <button>
  14. Submit
  15. </button>
  16. </form>
  17. </body>
  18. </html>`,
  19. "text/html",
  20. );
  21. assert(document);
  22. const h1 = document.querySelector("h1");
  23. assert(h1);
  24. console.log(h1.textContent);

Note: the example uses an unpinned version from deno_land/x, which you likely don’t want to do, because the version can change and cause unexpected outcomes. You should use the latest version of available of deno-dom.

Faster startup

Just importing the deno-dom-wasm.ts file bootstraps the Wasm code via top level await. The problem is that top level await blocks the module loading process. Especially with big Wasm projects, it is a lot more performant to initialize the Wasm after module loading is complete.

deno-dom has the solution for that, they provide an alternative version of the library that does not automatically init the Wasm, and requires you to do it in the code:

  1. import {
  2. DOMParser,
  3. initParser,
  4. } from "https://deno.land/x/deno_dom/deno-dom-wasm-noinit.ts";
  5. (async () => {
  6. // initialize when you need it, but not at the top level
  7. await initParser();
  8. const doc = new DOMParser().parseFromString(
  9. `<h1>Lorem ipsum dolor...</h1>`,
  10. "text/html",
  11. );
  12. })();

In addition, using the deno-dom-native.ts (which requires the --allow-ffi flag) will bypass the Wasm startup penalty as well as will not require the init() startup time. This would only work with the Deno CLI and not Deploy.