Open Source & Free Forever

Open‑Source macOS Screen Recorder for Node.js

Native ScreenCaptureKit + AVFoundation recorder with window selection, multi‑display, overlay exclusion, granular audio, camera capture and cursor tracking. The same engine that powers Creavit Studio.

MIT License
ScreenCaptureKit + AVFoundation
Electron Compatible

Professional Screen Recording API

Quick Start - Record Everything

Install and start recording in seconds. One output path automatically creates synchronized screen, camera (temp_camera_<timestamp>.webm), audio (temp_audio_<timestamp>.webm), and cursor data (temp_cursor_<timestamp>.json) files.

// Installation
npm install node-mac-recorder

// Quick Start
const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

// Single output records screen + camera + audio + cursor
await recorder.startRecording("./output.mov");
await new Promise(r => setTimeout(r, 5000));
const result = await recorder.stopRecording();

console.log("Screen:", result.outputPath);
console.log("Camera:", result.cameraOutputPath);
console.log("Audio:", result.audioOutputPath);

Multi-Display Support

Record any display or all displays simultaneously. Perfect for multi-monitor setups with automatic coordinate mapping.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

const displays = await recorder.getDisplays();
// Record from second display
await recorder.startRecording("./display-2.mov", {
  displayId: 1,
  quality: "high"
});

Smart Window Capture

Record individual application windows with intelligent display detection. Automatically handles off-screen windows and filters system processes.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

const windows = await recorder.getWindows();
const targetWindow = windows.find(w => w.appName === "Safari");
await recorder.startRecording("./window.mov", {
  windowId: targetWindow.id
});

Custom Area Recording

Define precise rectangular regions for focused content capture. Ideal for tutorial creators and demo recordings.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

await recorder.startRecording("./area.mov", {
  captureArea: {
    x: 200, y: 100,
    width: 1200, height: 800
  },
  quality: "medium"
});

Overlay Exclusion

Floating UI elements and overlay windows are automatically excluded. Build recording tools with clean, professional output.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

// Overlay windows are automatically excluded
await recorder.startRecording("./clean.mov", {
  displayId: 0,
  quality: "high"
});
// Your floating UI won't appear in the recording

Quality & Performance

Choose frame rates (15/30/60 FPS) and quality presets. Optimized encoding with hardware acceleration for smooth recordings.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

await recorder.startRecording("./high-quality.mov", {
  quality: "high",    // low, medium, high
  frameRate: 60,      // 15, 30, 60
  captureCursor: true
});

Thumbnail Generation

Generate preview thumbnails for windows and displays. Build beautiful selection UIs for your recording application.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

const thumbnail = await recorder.getWindowThumbnail(
  windowId, 
  { maxWidth: 400, maxHeight: 300 }
);
// Returns: "data:image/png;base64,iVBORw0..."

Complete Audio & Camera Integration

Dual Audio Recording

Capture microphone and system audio independently or together. Perfect sync for tutorials, demos, and gameplay recordings with full device control.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

await recorder.startRecording("./video.mov", {
  includeMicrophone: true,
  includeSystemAudio: true
});
// Audio saved separately as temp_audio_<timestamp>.webm

Webcam Recording

Record camera footage alongside screen capture. Separate video files with shared timestamps make post-production editing effortless.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

recorder.setCameraEnabled(true);
await recorder.startRecording("./screen.mov");
// Camera saved as temp_camera_<timestamp>.webm

Cursor Tracking

Export real-time cursor positions, types, and click events as JSON. Build custom cursor animations or analytics from your recordings.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

await recorder.startCursorCapture("./cursor.json");
// Track mouse movements, clicks, cursor types
await recorder.stopCursorCapture();

Device Management

List and select specific audio inputs and cameras. Rich device metadata lets you build sophisticated recording UIs with device previews.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

const audioDevices = await recorder.getAudioDevices();
const cameras = await recorder.getCameraDevices();
recorder.setAudioDevice(audioDevices[0].id);

Permission Management

Check and request macOS permissions programmatically. Screen recording, microphone, and accessibility permissions all in one API.

const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();

const permissions = await recorder.checkPermissions();
// { screenRecording: true, microphone: true, 
//   accessibility: true }

Electron Ready

Built for Electron apps with crash protection and renderer compatibility. Seamlessly integrates with native device APIs for production applications.

// In Electron main process
const MacRecorder = require("node-mac-recorder");
const recorder = new MacRecorder();
const { ipcMain } = require("electron");
ipcMain.handle("start-recording", async () => {
  return await recorder.startRecording("./video.mov");
});

Why ScreenCaptureKit + AVFoundation?

Combines the best of both native macOS frameworks: ScreenCaptureKit for screen recording (macOS 12.3+), AVFoundation for camera capture and audio processing.

Native overlay window exclusion

Automatically excludes floating UI elements for cleaner videos

Low‑latency, low‑CPU capture

Optimized performance specifically for macOS

Multi‑display awareness

Accurate coordinate mapping across multiple displays

Rock‑solid stability

Reliable performance in Electron environments

Developer API Overview

A quick map of the most used methods. See GitHub README for full docs.

Core

  • startRecording(output, options) — begin capture
  • stopRecording() — finalize; returns paths + timestamp
  • getStatus() — current state, options and timers
  • checkPermissions() — macOS permissions snapshot

Discovery

  • getWindows() — visible/recordable windows with bounds
  • getDisplays() — available displays and positions
  • getAudioDevices() — microphones and loopbacks
  • getCameraDevices() — cameras with resolution metadata

Thumbnails

  • getWindowThumbnail(id, { maxWidth, maxHeight })
  • getDisplayThumbnail(id, { maxWidth, maxHeight })

Audio & Camera Helpers

  • setAudioDevice(deviceId), setSystemAudioEnabled(bool)
  • setSystemAudioDevice(deviceId), getAudioCaptureStatus()
  • setCameraEnabled(bool), setCameraDevice(deviceId)
  • getCameraCaptureStatus() — status + output file

Cursor Tracking

  • startCursorCapture(file) — writes events as JSON
  • stopCursorCapture() — stop and close file

Advanced Capabilities

Everything you need to build a professional macOS recorder: precise selection, synchronized audio/camera companions, and intelligent window handling.

Recording Modes

  • Full screen, window‑specific or custom area
  • Automatic display detection for windows
  • Coordinate conversion across multi‑display setups
  • Cursor show/hide, frame rate and quality controls

Audio

  • Separate toggles for microphone and system audio
  • Enumerate/select devices; prefer loopback for system‑only
  • Audio written to a synchronized companion file
  • Simple status helpers to inspect capture state

Camera

  • Video‑only WebM/QuickTime companion clip
  • Device listing with resolution metadata
  • Enable/disable on the fly; query capture status
  • Electron‑friendly device IDs for live previews

Smart Window Management

  • List visible windows with app names and bounds
  • Filter hidden/system/tiny/unnamed windows
  • Generate preview thumbnails for windows/displays
  • Native overlay exclusion for distraction‑free capture

Cursor Tracking

  • Realtime mouse positions, cursor types and click events
  • Writes structured JSON while capturing
  • Types: default, pointer, text, grab, resize, crosshair
  • Events: move, mousedown/up, rightmousedown/up

Performance & Reliability

  • ScreenCaptureKit (macOS 12.3+) for low overhead
  • Electron crash protection and robust session handling
  • H.264 video in MOV; separate AAC/WebM audio
  • Balanced presets for quality vs. size

Powered by ScreenCaptureKit

Modern, high‑performance capture with native overlay exclusion, multi‑display intelligence and low CPU usage. Record windows, displays or custom areas with cursor and audio controls.

Window / Display / Area

Full screen, window‑specific or custom region recording with automatic overlay window exclusion.

Camera Recording

Video‑only camera capture saved as a companion clip with shared session timestamp.

Granular Audio

Separate microphone/system controls and device selection. Audio is saved to a synchronized companion file.

Cursor Tracking

Track mouse position, cursor types and click events to JSON in real time.

Requirements

macOS 12.3+ (Monterey), Node.js 14+, Xcode Command Line Tools and screen/microphone permissions.

macOS
12.3+ (ScreenCaptureKit)
Node.js
v14 or newer
Xcode Tools
xcode-select --install
Permissions
Screen, mic, accessibility

Simple & Powerful API

Clean API with flexible options: window/display selection, cursor toggle, frame rate, quality, camera and audio devices.

Installation

npm install node-mac-recorder

Quick Start

const MacRecorder = require("node-mac-recorder");

const recorder = new MacRecorder();

// Simple full‑screen recording
await recorder.startRecording("./output.mov");
await new Promise((r) => setTimeout(r, 5000));
const result = await recorder.stopRecording();
console.log("Saved:", result.outputPath);
console.log("Camera clip:", result.cameraOutputPath);
console.log("Audio clip:", result.audioOutputPath);

Advanced Options

await recorder.startRecording("./recording.mov", {
  // Audio Controls
  includeMicrophone: false,
  includeSystemAudio: true,
  systemAudioDeviceId: "loopback-device-id",

  // Display & Window Selection
  displayId: 0,
  // or windowId: 12345,
  captureArea: { x: 100, y: 100, width: 1200, height: 800 },

  // Recording Options
  quality: "high",
  frameRate: 60,
  captureCursor: true,

  // Camera
  captureCamera: true,
  cameraDeviceId: "built-in-camera-id",
});

Window Recording

const windows = await recorder.getWindows();
const safari = windows.find((w) => w.appName === "Safari");

await recorder.startRecording("./safari.mov", {
  windowId: safari.id,
  includeMicrophone: true,
  captureCursor: true,
});
await new Promise((r) => setTimeout(r, 8000));
await recorder.stopRecording();

Thumbnails for Selection UI

const windows = await recorder.getWindows();
for (const w of windows) {
  try {
    const thumb = await recorder.getWindowThumbnail(w.id, { maxWidth: 200, maxHeight: 150 });
    console.log(`Thumb ready for ${w.appName}`);
  } catch (e) {
    console.log("No preview available");
  }
}

const displays = await recorder.getDisplays();
const preview = await recorder.getDisplayThumbnail(displays[0].id, { maxWidth: 300 });

Configuration Options

includeMicrophone
Enable microphone audio (default: off)
includeSystemAudio
Capture system audio (default: on)
displayId / windowId
Select a display or a specific window
captureArea
Custom area (x, y, width, height)

One‑Liner: Record Everything

await Promise.all([
  recorder.startRecording("./recording.mov", {
    includeMicrophone: true,
    includeSystemAudio: true,
    captureCamera: true,
    quality: "high",
    frameRate: 30,
    captureCursor: false // keep cursor out of video; capture as JSON
  }),
  recorder.startCursorCapture("./cursor-data.json")
]);

await new Promise((r) => setTimeout(r, 8000));
const [result] = await Promise.all([
  recorder.stopRecording(),
  recorder.stopCursorCapture()
]);

console.log("Video:", result.outputPath);
console.log("Camera:", result.cameraOutputPath);
console.log("Audio:", result.audioOutputPath);
console.log("Session:", result.sessionTimestamp);

Camera and audio are saved as companion files; cursor data is written to JSON. All share the same sessionTimestamp.

Outputs & Session Timestamp

How files are written and matched.

Video

Main recording as .mov (H.264).

Camera

Silent camera clip as temp_camera_<timestamp>.mov (QuickTime fallback on older macOS).

Audio

Microphone/system audio in temp_audio_<timestamp>.mov companion file.

Cursor

Real‑time cursor data to your .json file (positions, types, clicks).

A shared sessionTimestamp matches video, camera, audio and cursor data to the same session.

Full Feature Breakdown

Advanced Recording

  • Full screen, window or custom area
  • Multi‑display coordinate conversion, correct display selection
  • Cursor visibility, quality and FPS control

Audio

  • Separate toggles for microphone/system audio
  • List/select devices (loopback recommended)
  • Companion file with synchronized audio

Smart Window Management

  • List visible windows with names and bounds
  • Filter system/hidden/tiny/unnamed windows
  • Window/display thumbnails for preview UIs

Camera

  • Device listing with resolution metadata
  • Video‑only companion clip (silent)
  • Device IDs compatible with Electron previews

Cursor Tracking

  • Positions, types (pointer, text, grab, etc.) and clicks
  • Writes JSON in real time

Durum & İzinler & Olaylar

  • getStatus() ile kayıt durumu ve sayaç
  • checkPermissions() ile macOS izin kontrolü
  • Olaylar: started, stopped, timeUpdate, completed

Use Cases

Perfect for Electron apps, CLI tools, and screen recording software. Build your own recording tools with native macOS performance.

Electron Apps

Build desktop screen recording applications. Integrates seamlessly with Electron's main process.

CLI Tools

Create command-line recording tools for automation, testing, and CI/CD pipelines.

Screen Recorders

Build professional recording software like Creavit Studio with all core features included.

Built for Creavit Studio

node-mac-recorder powers Creavit Studio's recording engine. We open-sourced it so other developers can build their own screen recording applications with native macOS performance.

Try Creavit Studio

Frequently Asked Questions

Troubleshooting

Common fixes for local development and CI environments.

Black or Empty Video

Grant Screen Recording permission to your terminal/app in System Settings → Privacy & Security → Screen Recording.

No System Audio

Install a loopback device (BlackHole/Soundflower/Loopback) and pass its id via systemAudioDeviceId.

Window Not Found

Ensure the window is visible and not minimized. The library filters hidden/system/tiny windows.

Coordinate Mismatch

When recording by window, coordinates are resolved automatically to the correct display.

Start Building Today

Free and open source. Built with native macOS APIs.