A screengrabbing library which uses the Windows Desktop Duplication API

Usage no npm install needed!

<script type="module">
  import windowsDesktopDuplication from '';


Windows Desktop Duplication for Node

A native addon to use the Desktop Duplication API, which is part of Windows 8 and higher.


npm install windows-desktop-duplication


const { DesktopDuplication } = require('windows-desktop-duplication');

let dd = new DesktopDuplication(0); // register for screen 0

let frame;

try {
    frame = dd.getFrame();
} catch(err) {
    console.log("An error occured:", err.message);

// work with the data in frame

More examples, including ones on how to write the data into png-files, can be found in the examples/ directory. You need to install pngjs before you can use them however (npm i pngjs).


Data format

All of the methods returning images return an object with the format:

    data: Buffer,
    width: Number,
    height: Number

The data in the buffer are the raw pixel values in RGBA order. This object format is referred to as the "default format" in the rest of this documentation.


static getMonitorCount()
Static method to get the number of available monitors.

Creates a new instance for the screen screenNum. Use the getMonitorCount() method to get the number of available screens.

Setup the required DirectX objects. Use a try/catch block to catch errors in the initialization process.

Synchronously gets a single frame in the default format. If the procedure fails, retry up to retryCount times (default: 5). If there was no image captured after all retries are used up, this method throws an error.

Like getFrame, but returning a promise instead, which resolves to image data. The capture and image processing is also run in a separate thread for better performance.

startAutoCapture(delay, ?allowSkips)
Starts a new thread, which tries to capture the screen every delay milliseconds. Image data is then emitted as an frame event. This method functions similar to setInterval(() => dd.getFrameAsync().then(frame => emit("frame", frame)), delay), but with the added bonus of all the timing stuff happening in native code and a separate thread, which improves the performance. Note: You can only have one of these threads running at any time, so subsequent calls to startAutoCapture without stopping the auto capture in between have no effect. The optional parameter allowSkips controls how the thread queues up the frame events. If the event did not have a chance to fire before the next image is captured, it can either be queued up (allowSkips = false) or just be thrown away (allowSkips = true, default).

Stops the auto capture thread. By default, no futher frame events will be emitted after this method has been called, since clearBacklog is true by default. If you want to process every captured frame however, set clearBacklog to false.


Event 'frame'
Emitted in an interval which duration is determined by the delay parameter in the startAutoCapture method. The event handler will be called with an object in the default image format.


Error: Failed to aquire next frame: The application made a call that is invalid. Either the parameters of the call or the state of some object was incorrect.

This error is thrown, if multiple simultaneous requests to capture an image are attempted simultaneously. Different from how one might expect the DesktopDuplication to work, it does not actually simply return an image of the current desktop content. Instead, the user has to request an image and Windows will only return one, if the contents have changed since the last request. The request is given a timeout, which is the maximum time it will block, in case no image is returned. This behavior does not mesh well will multithreading however. Since this library only uses a single DesktopDuplication instance for all methods as well as an one second timeout, it's very easy to request two images at the same time if getFrameAsync or startAutoCapture are used. To avoid the error, you can either only use the blocking getFrame, or make sure, that no calls to getFrame and getFrameAsync and no running auto capture thread happen at the same time.