A TypeScript library for scanning and retrieving information about installed macOS applications and PWAs (Progressive Web Apps), including app icons with base64 encoding support.
npm install get-installed-apps-on-macA TypeScript library for scanning and retrieving information about installed macOS applications and PWAs (Progressive Web Apps), including app icons with base64 encoding support.
- ๐ Fast Application Discovery - Uses macOS Spotlight (mdfind) for efficient app scanning
- ๐ PWA Support - Automatically detects and includes installed Progressive Web Apps
- ๐ฑ App Icon Processing - Extracts and converts app icons to base64 PNG format
- ๐ฏ Flexible Search Options - Search by bundle ID, name patterns, or custom paths
- ๐ก๏ธ Type Safety - Full TypeScript support with comprehensive type definitions
- โก Modular Architecture - Clean, well-organized codebase with separate concerns
- ๐งช Well Tested - Comprehensive test suite included
``bash`
npm install get-installed-apps-on-macor
yarn add get-installed-apps-on-macor
pnpm add get-installed-apps-on-mac
`typescript
import { scanMacOSApplications, getMacOSApplication, getAppInfoFromPath } from 'get-installed-apps-on-mac';
// Scan all applications
const apps = await scanMacOSApplications();
console.log(Found ${apps.length} applications);
// Get a specific app by bundle ID
const safari = await getMacOSApplication('com.apple.Safari');
if (safari) {
console.log(Safari: ${safari.appName} at ${safari.appPath});
}
// Extract info from a specific .app path
const appInfo = await getAppInfoFromPath('/Applications/TextEdit.app');
console.log(${appInfo.appName} (${appInfo.bundleId}));`
Scans for all installed macOS applications.
`typescript`
const apps = await scanMacOSApplications({
includeBase64Icon: false, // Include base64 encoded icons (default: false)
iconSize: 256, // Icon size in pixels (default: 256)
searchPaths: [ // Custom search paths (default: ['/Applications', '$HOME/Applications'])
'/Applications',
'/System/Applications'
],
timeout: 30000 // Command timeout in ms (default: 30000)
});
Gets a specific application by its bundle identifier.
`typescript`
const app = await getMacOSApplication('com.apple.TextEdit', {
includeBase64Icon: false
});
Extracts application information from a specific .app bundle path.
`typescript`
const app = await getAppInfoFromPath('/Applications/TextEdit.app', {
includeBase64Icon: true,
iconSize: 256
});
Parameters:
- appPath (string): Full path to the .app bundleoptions
- (object, optional):includeBase64Icon
- (boolean): Include base64 encoded icon (default: false)iconSize
- (number): Icon size in pixels (default: 256)
Main scanner class for advanced usage.
`typescript
import { MacOSAppScanner } from 'get-installed-apps-on-mac';
const scanner = new MacOSAppScanner({
includeBase64Icon: true,
iconSize: 256
});
// Scan all apps
const apps = await scanner.scanApplications();
// Find apps by name pattern
const textApps = await scanner.getApplicationsByName(/text|word/i);
// Get specific app
const finder = await scanner.getApplicationByBundleId('com.apple.finder');
`
Each application returns the following information:
`typescript`
interface AppInfo {
readonly appName: string; // Display name of the app
readonly appPath: string; // Full path to the .app bundle
readonly bundleId: string; // Bundle identifier (e.g., 'com.apple.Safari')
readonly appIconName: string | null;// Icon filename from Info.plist
readonly appIconPath: string | null;// Full path to the icon file
readonly appIconBase64: string | null; // Base64 encoded PNG icon
}
`typescript`
interface ScanOptions {
readonly includeBase64Icon?: boolean; // Include base64 icon data (default: false)
readonly iconSize?: number; // Icon size in pixels (default: 256)
readonly searchPaths?: string[]; // Paths to search (default: ['/Applications', '$HOME/Applications'])
readonly timeout?: number; // Command timeout in ms (default: 30000)
}
`typescript
import { scanMacOSApplications } from 'get-installed-apps-on-mac';
const apps = await scanMacOSApplications({ includeBase64Icon: false });
apps.forEach(app => {
console.log(${app.appName} (${app.bundleId})); Path: ${app.appPath}
console.log(); Icon: ${app.appIconPath || 'Not found'}
console.log();`
});
`typescript
import { MacOSAppScanner } from 'get-installed-apps-on-mac';
const scanner = new MacOSAppScanner({
includeBase64Icon: true,
iconSize: 128 // Smaller icons for faster processing
});
const apps = await scanner.scanApplications();
apps.forEach(app => {
if (app.appIconBase64) {
// Use the base64 icon in your app
console.log(Icon data available for ${app.appName});`
}
});
`typescript
import { MacOSAppScanner } from 'get-installed-apps-on-mac';
const scanner = new MacOSAppScanner();
// Find all Adobe apps
const adobeApps = await scanner.getApplicationsByName(/adobe/i);
// Find development tools
const devTools = await scanner.getApplicationsByName(/xcode|terminal|git/i);
`
`typescript
import { getAppInfoFromPath } from 'get-installed-apps-on-mac';
// Extract info from a known app path
const appInfo = await getAppInfoFromPath('/Users/username/Applications/MyApp.app', {
includeBase64Icon: true,
iconSize: 128
});
console.log(App: ${appInfo.appName});Bundle ID: ${appInfo.bundleId}
console.log();`
if (appInfo.appIconBase64) {
console.log('Base64 icon available');
}
- macOS 10.10+ (uses mdfind and iconutil)simple-plist
- Node.js 12+
- Dependencies: , sharp (for icon processing)
`bashInstall dependencies
pnpm install
Project Structure
`
src/
โโโ types.ts # TypeScript interfaces and error classes
โโโ icon-processor.ts # Icon extraction and conversion
โโโ plist-parser.ts # Info.plist file parsing
โโโ scanner.ts # Main MacOSAppScanner class
โโโ index.ts # Public API exports
`Error Handling
The library includes custom error classes for better error handling:
`typescript
import { AppScanError, IconProcessingError } from 'get-installed-apps-on-mac';try {
const apps = await scanMacOSApplications();
} catch (error) {
if (error instanceof AppScanError) {
console.error('App scanning failed:', error.message);
} else if (error instanceof IconProcessingError) {
console.error('Icon processing failed:', error.iconPath, error.message);
}
}
``MIT
Contributions are welcome! Please feel free to submit a Pull Request.