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.
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.
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-recorderQuick 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
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 StudioFrequently Asked Questions
Is it free and open source?
Yes, MIT licensed. Free to use in commercial projects.
Where is audio saved?
The screen recording remains silent. Audio is written to a separate companion file (e.g. temp_audio_timestamp.webm) so you can mix microphone and system sound in post.
How do I capture system audio?
Use a loopback device (e.g. BlackHole, Soundflower, Loopback) and set it via systemAudioDeviceId or rely on auto‑detection when available.
Does it work with Electron?
Yes. The native layer includes crash protections for Electron apps and supports window/display thumbnails for selection UIs.
macOS only?
Yes, built with native macOS APIs. Windows/Linux support welcome via contributions.
System requirements?
macOS 12.3+ (ScreenCaptureKit), Node.js 14+, Xcode Command Line Tools. Grant screen and microphone permissions.
Are overlay windows excluded automatically?
Yes. ScreenCaptureKit filters floating overlay windows automatically during capture — perfect for recorders with on‑screen controls.
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.
