---
title: "d3-no-dom"
description: "📊 Fully use D3.js (Data Driven Documents) in environments without DOM. Perfect for serverless e.g. Vercel Functions"
canonical_url: "https://neg4n.dev/projects/d3-no-dom"
md_url: "https://neg4n.dev/projects/d3-no-dom.md"
---

# d3-no-dom

## Resources

- [GitHub](https://github.com/neg4n/d3-no-dom)
- [npm](https://www.npmjs.com/package/d3-no-dom)

## README

d3-no-domFully use d3.js in environments without DOM, such as Cloudflare Workers or Vercel FunctionsFeaturesSimple API with maximum extensibility.Support for asynchronous operations and API calls in render functionUtilities like sanitizing the HTML or outputting the base64 from generated svgTests covering most of the functionality ensuring robustnessInstallationnpm i d3-no-dom d3 
# or
yarn add d3-no-dom d3 
# or
pnpm add d3-no-dom d3 The d3-no-dom library does not provide any underlying DOM implementation, giving users the flexibility to choose their preferred DOM library. Some options are:linkedom: A lightweight and fast DOM implementation ideal for serverless environments such as Cloudflare Workers or Vercel Functions (recommended).npm i linkedom 
# or
yarn add linkedom 
# or
pnpm add linkedom jsdom: A more comprehensive and heavier DOM implementation, suitable for traditional backend environments like monolithic applications hosted on dedicated servers.npm i jsdom 
# or
yarn add jsdom 
# or
pnpm add jsdom [!WARNING]jsdom may not work on the Cloudflare Workers
without specifying nodejs_compat flag due to use of the Node native modulesHow to useAt first, you must supply your own d3 instance and dom provider to the d3-no-dom's prepreSvgServerSideRendererusing linkedom (recommended)import * as d3 from "d3"
import { parseHTML } from "linkedom"

// ...

class Linkedom {
  window: { document: Document };
  constructor(html: string) {
    const { document, window } = parseHTML(html);
    this.window = { document };
    Object.assign(this.window, window);
  }
}

const { render } = prepareSvgServerSideRenderer({
  domProvider: Linkedom,
  d3Instance: d3
});using jsdomimport * as d3 from "d3"
import { JSDOM } from "jsdom"

// ...

const { render } = prepareSvgServerSideRenderer({
  domProvider: JSDOM,
  d3Instance: d3
});Next, use the render function. It provides everything you need in order to fully use d3.js on the server side (the underlying mechanism is integration with Virtual DOM)//               you can make e.g. API calls here   
//           it can also be synchronous if not needed!
//              ╭────────────┤
//              │            │    
//              ↓            ↓ 
const result = await render(async ({ d3Selection, svgNode, currentDom }) => {
//      ↑                                  ↑        ↑          ↑            
//      │                d3 selected       │        │          │
//      │                object to work on ╯        │          ╰ whole DOM  
//      │                                      underlying
//      ╰ rendered svg's                 svg DOM node to work on
//   source, as HTML or base64   
})(Optionally) adjust your configuration or the render function's options directly in order to e.g. disable sanitizing
the HTML or control the return value (whether it should be HTML or base64 - where second is specifically useful with usage with satori)License & contributingThe MIT License. All contributions are welcome!
