Utilities to build DMG files for macOS applications, used by electron-builder.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
DMG Builder provides comprehensive utilities for building Apple Disk Images (DMG files) as part of the electron-builder ecosystem. It offers a complete DMG creation and customization framework that enables developers to generate professional macOS application installers with custom backgrounds, icons, window layouts, licensing agreements, and code signing capabilities.
npm install electron-buildernpm install dmg-builderimport { DmgTarget } from "dmg-builder";For utilities and helper functions:
import {
attachAndExecute,
detach,
customizeDmg,
getDmgTemplatePath,
getDmgVendorPath,
hdiUtil,
explainHdiutilError
} from "dmg-builder";import { DmgTarget } from "dmg-builder";
import { MacPackager } from "app-builder-lib";
import { Arch } from "builder-util";
// Create DMG target for electron-builder
const packager = new MacPackager(/* packager config */);
const dmgTarget = new DmgTarget(packager, "/path/to/output");
// Build the DMG
await dmgTarget.build("/path/to/app.app", Arch.x64);DMG Builder is built around several key components:
Main DMG creation functionality using the DmgTarget class. Handles the complete build process from app packaging to final DMG generation with customization options.
class DmgTarget extends Target {
constructor(packager: MacPackager, outDir: string);
build(appPath: string, arch: Arch): Promise<void>;
computeVolumeName(arch: Arch, custom?: string | null): string;
computeDmgOptions(appPath: string): Promise<DmgOptions>;
}Low-level DMG file operations including mounting, unmounting, and executing tasks on mounted volumes. Essential for DMG manipulation and content management.
function attachAndExecute<T>(
dmgPath: string,
readWrite: boolean,
task: (devicePath: string) => Promise<T>
): Promise<T>;
function detach(name: string): Promise<string | null>;Comprehensive DMG appearance and content customization including backgrounds, icons, window positioning, and file layouts.
interface DmgBuilderConfig {
appPath: string;
artifactPath: string;
volumeName: string;
specification: DmgOptions;
packager: MacPackager;
}
function customizeDmg(config: DmgBuilderConfig): Promise<boolean>;
function computeBackground(packager: PlatformPackager<any>): Promise<string>;
function getImageSizeUsingSips(background: string): Promise<{width: number, height: number}>;License agreement integration with support for multiple languages and customizable button layouts.
function addLicenseToDmg(
packager: PlatformPackager<any>,
dmgPath: string
): Promise<LicenseConfig | null>;
function getLicenseButtonsFile(
packager: PlatformPackager<any>
): Promise<Array<LicenseButtonsFile>>;
function getLicenseButtons(
licenseButtonFiles: Array<LicenseButtonsFile>,
langWithRegion: string,
id: number,
name: string
): Promise<string>;
function getDefaultButtons(
langWithRegion: string,
id: number,
name: string
): string;Robust error handling for hdiutil operations with detailed error explanations and retry logic for transient failures.
function hdiUtil(args: string[]): Promise<string | null>;
function explainHdiutilError(errorCode: number): string;
const hdiutilTransientExitCodes: Set<number>;interface DmgBuildConfig {
title: string;
icon?: string | null;
"badge-icon"?: string | null;
background?: string | null;
"background-color"?: string | null;
"icon-size"?: number | null;
"text-size"?: number | null;
window?: {
position?: { x?: number; y?: number };
size?: { width?: number; height?: number };
};
format?: string;
filesystem?: string;
"compression-level"?: number | null;
license?: string | null;
contents?: Array<{
path: string;
x: number;
y: number;
name?: string;
type?: "file" | "link" | "position";
hide_extension?: boolean;
hidden?: boolean;
}>;
}
interface DmgOptions {
/** Background image path or null to use backgroundColor */
background?: string | null;
/** Background color (hex) when no background image */
backgroundColor?: string | null;
/** DMG icon path */
icon?: string | null;
/** Icon size in pixels (default: platform default) */
iconSize?: number;
/** Icon text size (10-16, default: 12) */
iconTextSize?: number;
/** Window configuration for DMG appearance */
window?: {
x?: number;
y?: number;
width?: number;
height?: number;
};
/** DMG compression format (UDZO, UDRO, UDBZ) */
format?: string;
/** Enable internet-enabled DMG (deprecated) */
internetEnabled?: boolean;
/** Code sign the DMG file */
sign?: boolean;
/** Custom DMG title template */
title?: string;
/** Write update info for auto-updater */
writeUpdateInfo?: boolean;
/** Contents layout configuration */
contents?: Array<{
/** Path to file/directory or special paths like /Applications */
path?: string;
/** X position in DMG window */
x: number;
/** Y position in DMG window */
y: number;
/** Display name (optional) */
name?: string;
/** Type of content item */
type?: "file" | "link" | "dir";
}>;
}
interface LicenseButtonsFile {
file: string;
lang: string;
langWithRegion: string;
langName: string;
}
interface LicenseConfig {
$schema: string;
body: Array<{
file: string;
lang: string;
}>;
labels: Array<{
lang: string;
agree?: string;
disagree?: string;
print?: string;
save?: string;
message?: string;
}>;
}Install with Tessl CLI
npx tessl i tessl/npm-dmg-builder