Skip to content

Technology Stack

Last Updated: 2026-02-03 | Reading Time: 15 minutes

Comprehensive overview of technologies powering PasteShelf.



PasteShelf is built as a native macOS application using Apple’s latest technologies, prioritizing performance, privacy, and seamless system integration.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PasteShelf Tech Stack β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ LANGUAGE Swift 5.9+ β”‚
β”‚ UI FRAMEWORK SwiftUI + AppKit β”‚
β”‚ DATA PERSISTENCE CoreData + CloudKit β”‚
β”‚ CONCURRENCY Swift Concurrency (async/await) β”‚
β”‚ SECURITY Keychain + CryptoKit β”‚
β”‚ PLATFORM macOS 14.0+ (Sonoma) β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Role: Primary programming language

Why Swift?

  • Type safety and modern syntax
  • Excellent macOS integration
  • Strong concurrency model
  • Active development by Apple

Key Features Used:

// Swift Concurrency
func fetchItems() async throws -> [ClipboardItem] {
try await withThrowingTaskGroup(of: ClipboardItem.self) { group in
// Parallel processing
}
}
// Property Wrappers
@MainActor
class ViewModel: ObservableObject {
@Published var items: [ClipboardItem] = []
}
// Result Builders (SwiftUI)
var body: some View {
VStack {
ForEach(items) { item in
ItemRow(item: item)
}
}
}
// Macros (Swift 5.9+)
@Observable
class AppState {
var clipboardItems: [ClipboardItem] = []
}

Role: Primary UI framework

Why SwiftUI?

  • Declarative, reactive UI
  • Native macOS look and feel
  • Automatic dark mode support
  • Built-in accessibility

Architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SwiftUI Architecture β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ View ViewModel Model β”‚
β”‚ ──── ───────── ───── β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ SwiftUI │────▢│ ObservableObj │────▢│ CoreData β”‚ β”‚
β”‚ β”‚ View β”‚ β”‚ @Published β”‚ β”‚ Entity β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ @StateObject β”‚ @FetchRequest β”‚
β”‚ β”‚ @EnvironmentObjβ”‚ β”‚
β”‚ β–Ό β–Ό β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Combine Publishers β”‚ β”‚
β”‚ β”‚ (Reactive data flow) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Components:

ComponentUsage
@StateLocal view state
@BindingTwo-way data binding
@StateObjectViewModel ownership
@EnvironmentObjectShared state
@FetchRequestCoreData integration
@AppStorageUserDefaults binding

Role: Local data persistence

Why CoreData?

  • Native Apple framework
  • CloudKit integration built-in
  • Efficient for large datasets
  • Automatic migration support

Configuration:

// NSPersistentCloudKitContainer for sync support
let container = NSPersistentCloudKitContainer(name: "PasteShelf")
// Multiple store configuration
let localStoreDescription = NSPersistentStoreDescription(url: localURL)
localStoreDescription.configuration = "Local"
let cloudStoreDescription = NSPersistentStoreDescription(url: cloudURL)
cloudStoreDescription.configuration = "Cloud"
cloudStoreDescription.cloudKitContainerOptions = CKContainerOptions(
containerIdentifier: "iCloud.com.pasteshelf.PasteShelf"
)

See Database Schema for data model details.

Role: Cross-device synchronization

Why CloudKit?

  • Native Apple integration
  • End-to-end encryption
  • No server maintenance
  • Generous free tier

Architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ CloudKit Architecture β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Private Database β”‚ β”‚
β”‚ β”‚ (User's iCloud Account) β”‚ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ Custom Zone β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ "com.pasteshelf.clipboardHistory" β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ Record Types: β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β€’ ClipboardItem β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β€’ ClipboardContent (asset) β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ β€’ UserPreferences β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”‚ Sync Features: β”‚
β”‚ β€’ Automatic background sync β”‚
β”‚ β€’ Conflict resolution (last-write-wins) β”‚
β”‚ β€’ Incremental changes via CKFetchRecordZoneChangesOperationβ”‚
β”‚ β€’ Push notifications for real-time updates β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

FrameworkPurposeTier
AppKitMenu bar, floating panelπŸ†“
FoundationCore utilitiesπŸ†“
CombineReactive programmingπŸ†“
OSLogUnified loggingπŸ†“
MetricKitPerformance metricsπŸ†“
LocalAuthenticationBiometric authπŸ†“
CryptoKitEncryptionπŸ†“
NaturalLanguageText analysis⭐
CreateMLOn-device ML⭐
VisionOCR for images⭐

Core clipboard monitoring:

import AppKit
class ClipboardMonitor {
private var changeCount: Int = 0
private var timer: Timer?
func startMonitoring() {
changeCount = NSPasteboard.general.changeCount
timer = Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { [weak self] _ in
self?.checkForChanges()
}
}
private func checkForChanges() {
let currentCount = NSPasteboard.general.changeCount
if currentCount != changeCount {
changeCount = currentCount
captureCurrentContent()
}
}
private func captureCurrentContent() {
let pasteboard = NSPasteboard.general
// Supported types
let types: [NSPasteboard.PasteboardType] = [
.string,
.rtf,
.html,
.png,
.tiff,
.fileURL
]
for type in types {
if let data = pasteboard.data(forType: type) {
// Process content
}
}
}
}

Keychain integration:

import Security
class KeychainManager {
func save(key: String, data: Data) throws {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: "com.pasteshelf.PasteShelf",
kSecAttrAccount as String: key,
kSecValueData as String: data,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
let status = SecItemAdd(query as CFDictionary, nil)
guard status == errSecSuccess else {
throw KeychainError.saveFailed(status)
}
}
}

End-to-end encryption:

import CryptoKit
class EncryptionManager {
private let key: SymmetricKey
init() {
// Generate or retrieve from Keychain
key = SymmetricKey(size: .bits256)
}
func encrypt(_ data: Data) throws -> Data {
let sealedBox = try AES.GCM.seal(data, using: key)
return sealedBox.combined!
}
func decrypt(_ data: Data) throws -> Data {
let sealedBox = try AES.GCM.SealedBox(combined: data)
return try AES.GCM.open(sealedBox, using: key)
}
}

Biometric authentication:

import LocalAuthentication
class BiometricAuth {
func authenticate() async throws -> Bool {
let context = LAContext()
var error: NSError?
guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
throw BiometricError.notAvailable
}
return try await context.evaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "Unlock PasteShelf"
)
}
}

OCR for image search:

import Vision
class OCREngine {
func extractText(from image: CGImage) async throws -> String {
let request = VNRecognizeTextRequest()
request.recognitionLevel = .accurate
request.usesLanguageCorrection = true
let handler = VNImageRequestHandler(cgImage: image, options: [:])
try handler.perform([request])
guard let observations = request.results else {
return ""
}
return observations
.compactMap { $0.topCandidates(1).first?.string }
.joined(separator: "\n")
}
}

Semantic search:

import NaturalLanguage
class SemanticSearch {
private let embedding = NLEmbedding.wordEmbedding(for: .english)
func findSimilar(to query: String, in items: [ClipboardItem]) -> [ClipboardItem] {
guard let queryVector = embedding?.vector(for: query) else {
return []
}
return items
.map { item in
let similarity = cosineSimilarity(queryVector, item.embedding)
return (item, similarity)
}
.sorted { $0.1 > $1.1 }
.map { $0.0 }
}
}

PasteShelf minimizes third-party dependencies to:

  • Reduce attack surface
  • Avoid licensing complications
  • Ensure long-term maintainability
  • Keep app size small
DependencyPurposeLicense
NonePure Apple frameworksN/A
DependencyPurposeConsideration
SQLite.swiftDirect SQLite accessIf CoreData limitations hit
KeychainAccessSimplified KeychainIf Security API too complex
SparkleAuto-updates (non-App Store)Direct distribution only

ToolVersionPurpose
Xcode15.0+IDE and build system
Swift5.9+Compiler
Git2.30+Version control
SwiftLintLatestCode linting
SwiftFormatLatestCode formatting
ToolPurpose
GitHub ActionsCI/CD automation
FastlaneBuild and release automation
xcprettyPrettier Xcode output
ToolPurpose
XCTestUnit and UI testing
XCUITestUI automation
InstrumentsPerformance profiling
ToolPurpose
DocCAPI documentation
MarkdownGeneral documentation

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Distribution Architecture β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ App Store β”‚ β”‚ Direct Distribution β”‚ β”‚
β”‚ β”‚ (Primary) β”‚ β”‚ (Secondary) β”‚ β”‚
β”‚ β”‚ ───────── β”‚ β”‚ ────────────── β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β€’ Sandboxed β”‚ β”‚ β€’ DMG download β”‚ β”‚
β”‚ β”‚ β€’ Review β”‚ β”‚ β€’ Sparkle updates β”‚ β”‚
β”‚ β”‚ β€’ Auto-update β”‚ β”‚ β€’ Notarized β”‚ β”‚
β”‚ β”‚ β€’ Payment β”‚ β”‚ β€’ Direct licensing β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

For Enterprise features:

ServiceProviderPurpose
Sync ServerSelf-hosted optionAir-gapped sync
AnalyticsPrivacy-respectingUsage metrics

Context: Choose primary UI framework.

Decision: SwiftUI with AppKit interop.

Rationale:

  • SwiftUI for main views (modern, declarative)
  • AppKit for menu bar and floating panel (better control)
  • Future-proof as SwiftUI matures

Context: Choose persistence layer.

Decision: CoreData with NSPersistentCloudKitContainer.

Rationale:

  • Built-in CloudKit sync
  • Automatic migration
  • Apple’s strategic direction
  • Good enough performance for clipboard data

Context: Choose sync infrastructure.

Decision: CloudKit for Pro, self-hosted option for Enterprise.

Rationale:

  • CloudKit: Zero infrastructure, E2E encryption, Apple integration
  • Self-hosted: Enterprise compliance requirements

Context: Choose AI/ML strategy for semantic search.

Decision: On-device ML using CreateML/CoreML.

Rationale:

  • Privacy: No data leaves device
  • Performance: Low latency
  • Offline: Works without internet
  • Cost: No API fees

ComponentVersionRelease Date
macOS14.0 (Sonoma)Sep 2023
Swift5.9Sep 2023
Xcode15.0Sep 2023
ComponentVersionNotes
macOS14.0 - 15.xSonoma and later
Swift5.9+Latest stable
Xcode15.0+Latest stable
VersionDeprecation DateEOL Date
macOS 13N/A (never supported)N/A

DocumentDescription
ArchitectureSystem architecture
Database SchemaData models
Build SystemBuild configuration
PerformanceOptimization

Last updated: 2026-02-03