@appkit/apple-contacts
v0.1.0
Published
TypeScript library for reading Apple Contacts via SQLite
Downloads
11
Maintainers
Readme
@appkit/apple-contacts
TypeScript library for reading Apple Contacts via direct SQLite database access.
Features
- Read-only access to macOS Contacts database
- Type-safe TypeScript API
- Comprehensive querying - Search by name, email, phone, organization, city
- Flexible filtering - Pagination, sorting, selective data loading
- Zero dependencies (except better-sqlite3 for SQLite access)
- Fast - Direct SQL queries, no IPC overhead
- Privacy-focused - 100% local, no network calls
Installation
npm install @appkit/apple-contactsRequirements
- macOS 10.15+ (Catalina or later)
- Node.js >= 20.0.0
- Terminal/app must have Full Disk Access permission
Granting Full Disk Access
- Open System Settings → Privacy & Security → Privacy
- Select Full Disk Access
- Enable access for your Terminal app or IDE
Quick Start
import { ContactsClient } from '@appkit/apple-contacts';
const client = new ContactsClient();
client.connect();
// Get all contacts
const contacts = await client.getAllContacts();
// Search by name
const results = await client.searchContacts('John');
// Get contact with full details
const contact = await client.getContact(123, { includeAll: true });
client.disconnect();API Overview
Contact Methods
// Get all contacts with options
await client.getAllContacts({
searchTerm: 'Dave',
limit: 10,
includeEmails: true,
includePhones: true,
});
// Get specific contact
await client.getContact(id, { includeAll: true });
// Search contacts
await client.searchContacts('search term');
// Find by organization
await client.getContactsByOrganization('Acme Corp');
// Get contacts with birthdays
await client.getContactsWithBirthdays();Email Methods
// Get emails for a contact
await client.getEmailsForContact(contactId);
// Search emails
await client.searchEmails({
searchTerm: '@example.com',
label: 'Work',
limit: 10,
});
// Find contacts by email
await client.findContactsByEmail('[email protected]');Phone Methods
// Get phones for a contact
await client.getPhonesForContact(contactId);
// Search phones
await client.searchPhones({
searchTerm: '555',
label: 'Mobile',
});
// Find contacts by phone
await client.findContactsByPhone('555-1234');Address Methods
// Get addresses for a contact
await client.getAddressesForContact(contactId);
// Search addresses
await client.searchAddresses({
city: 'San Francisco',
state: 'CA',
});
// Find contacts by city
await client.findContactsByCity('New York');Database Info
// Get statistics
const stats = await client.getStats();
console.log(stats.totalContacts, stats.totalEmails);
// Get database info
const info = client.getDatabaseInfo();
console.log(info.version, info.tableCount);
// List tables
const tables = client.listTables();
// Get table schema
const schema = client.getTableSchema('ZABCDRECORD');Query Options
ContactQueryOptions
{
searchTerm?: string; // Search name, email, phone, org
organization?: string; // Filter by organization
includeEmails?: boolean; // Include email addresses
includePhones?: boolean; // Include phone numbers
includeAddresses?: boolean; // Include postal addresses
includeAll?: boolean; // Include all related data
limit?: number; // Max results
offset?: number; // Pagination offset
sortBy?: 'firstName' | 'lastName' | 'organization';
sortDirection?: 'ASC' | 'DESC';
}Type Definitions
Contact
interface Contact {
id: number;
uniqueId: string;
firstName?: string;
lastName?: string;
fullName?: string;
organization?: string;
jobTitle?: string;
birthday?: string | number;
emails?: EmailAddress[];
phones?: PhoneNumber[];
addresses?: PostalAddress[];
// ... more fields
}EmailAddress
interface EmailAddress {
id: number;
ownerId: number;
address: string;
label?: string; // "_$!<Work>!$_"
labelDisplay?: string; // "Work"
}Database Structure
The library reads from ~/Library/Application Support/AddressBook/AddressBook-v22.abcddb.
Main tables:
ZABCDRECORD- Contact informationZABCDEMAILADDRESS- Email addressesZABCDPHONENUMBER- Phone numbersZABCDPOSTALADDRESS- Physical addresses
See docs/SCHEMA.md for complete schema documentation.
Read-Only by Design
This library is strictly read-only. Write operations are intentionally not supported to prevent accidental database corruption. To modify contacts, use the native Contacts.app or CNContactStore framework.
Troubleshooting
Permission Denied
Ensure your Terminal/IDE has Full Disk Access:
System Settings → Privacy & Security → Privacy → Full Disk AccessDatabase Not Found
Contacts.app must be configured with at least one account. Open Contacts.app to initialize the database.
Database Locked
If Contacts.app is actively using the database, you may encounter lock errors. Try quitting Contacts.app for batch operations.
Scripts
# Inspect database
npm run inspect
# Run test queries
npm run query
# Build TypeScript
npm run build
# Run tests
npm test
# Type check
npm run typecheckLicense
MIT
Author
Dave Weaver [email protected]
Repository
https://github.com/appkitstudio/apple-contacts
