Key Concepts Behind Palmier Pro Implementation: A Four-Layer Architecture
Palmier Pro is built as a native macOS video editor using a concentric four-layer architecture that separates SwiftUI presentation, observable state management, AVFoundation-based media rendering, and AI-driven external services, enabling professional-grade video editing with real-time AI generation capabilities.
The palmier-io/palmier-pro repository provides a comprehensive implementation of a modern macOS video editing platform written in Swift 6.2. The key concepts behind Palmier Pro implementation center on strict architectural boundaries that keep UI components, business logic, media processing, and external AI services decoupled yet efficiently communicative.
The Four-Layer Architecture
The codebase organizes functionality into four concentric layers that maintain clear separation of concerns. This structure allows the native SwiftUI interface to remain responsive while delegating heavy media operations to background systems.
Presentation Layer (SwiftUI and AppKit)
The Presentation layer handles all user interface rendering through SwiftUI with strategic AppKit fallbacks for complex interactions. All visual styling derives from Sources/PalmierPro/UI/AppTheme.swift, which defines constants for colors, spacing, fonts, and shadows through static properties like AppTheme.Background.base and AppTheme.Spacing.sm.
Due to a known limitation in macOS 26 where stacked SwiftUI .onDrop modifiers fail silently, the implementation uses native AppKit drop areas (MediaPanelDropArea) for top-level panels while reserving SwiftUI .onDrop for leaf targets only, as documented in AGENTS.md.
State and Business Logic Layer
The State layer centers on Sources/PalmierPro/Editor/ViewModel/EditorViewModel.swift, an @Observable @MainActor class that holds the single source of truth for the entire editing session. This view model owns the Timeline instance and mediates all edits including clip placement, trimming, keyframe animation, and undo/redo operations.
When timeline data changes, the view model increments timelineRenderRevision, triggering downstream observers to rebuild compositions. All mutations flow through controlled methods like placeClip(asset:trackIndex:startFrame:durationFrames:) and notifyTimelineChanged(), ensuring thread safety and consistent state propagation.
Media and Rendering Layer
The Media layer handles low-level video composition through Sources/PalmierPro/Preview/VideoEngine.swift. This engine constructs AVComposition objects by sampling per-frame data from Clip instances using pure functions like Clip.opacityAt(frame:) and Clip.transformAt(frame:) defined in Sources/PalmierPro/Models/Timeline.swift.
The VideoEngine monitors timelineRenderRevision and rebuilds the composition via CompositionBuilder, applying transforms, fades, speed adjustments, and alpha channel normalization before attaching to an AVPlayer for preview or export.
External Services and Infrastructure Layer
The External Services layer manages networking, AI generation, telemetry, and updates through injected dependencies declared in Package.swift. Key services include GenerationService for AI media creation, AgentService for ModelContextProtocol integration, Convex for backend synchronization, Sparkle for auto-updates, and Sentry for crash reporting.
These services interface with the EditorViewModel through well-defined protocols, keeping the core editor testable and independent of specific SDK implementations.
Observable State Management Patterns
The EditorViewModel class demonstrates modern Swift concurrency patterns by living on the main actor while managing mutable state:
@Observable @MainActor final class EditorViewModel {
var timeline = Timeline() {
didSet { timelineRenderRevision += 1 }
}
var mediaAssets: [MediaAsset] = []
var currentFrame: Int = 0
func placeClip(asset: MediaAsset, trackIndex: Int, startFrame: Int, durationFrames: Int) -> [String] {
// Validates track existence, creates clip, links audio if present
// Returns array of clip IDs inserted
}
}
All UI components automatically refresh when @Observable properties change, eliminating manual objectWillChange calls. The view model exposes methods like createClips, removeClipInternal, and telemetrySnapshot() to centralize business logic and anonymized analytics collection.
Pure Data Models for Timeline Composition
The Timeline struct in Sources/PalmierPro/Models/Timeline.swift represents the project as a pure data structure containing tracks, clips, and global settings like fps, width, and height. Each Track contains an array of Clip instances that store transformation data, fade parameters, and keyframe tracks.
Clip calculations remain side-effect free through methods like:
// Adjusting clip transform properties
guard let clipId = vm.timeline.tracks[0].clips.first?.id,
var clip = vm.clipFor(id: clipId) else { fatalError() }
clip.transform.width = 2.0 // double width
clip.transform.height = 2.0 // double height
clip.transform.rotation = 45.0 // degrees
vm.timeline.tracks[0].clips[0] = clip
vm.notifyTimelineChanged() // signals VideoEngine to rebuild
This functional approach enables reliable unit testing of video effects without instantiating heavyweight UI components.
AI-Driven Editing Architecture
Palmier Pro integrates AI generation through the GenerationService and AgentService classes using the ModelContextProtocol SDK. When users request AI-generated content, the view model creates a PendingPanelSeed containing the source MediaAsset and a GenerationInput with prompt parameters:
let seed = PendingPanelSeed(
asset: asset,
stored: GenerationInput(
prompt: "Create a 4-second cinematic intro matching the style of Blade Runner",
style: .cinematic,
durationSeconds: 4
)
)
vm.pendingPanelSeed = seed
vm.showGenerationPanel = true
The service communicates with Convex backends to process large-language-model prompts, returning new MediaAsset instances (such as Lottie animations or generated video) that placeClip inserts into the timeline for immediate preview.
Build-Time Metal Kernel Compilation
The Package.swift defines a custom build tool plugin located at Plugins/MetalCIKernelPlugin/MetalCIKernelPlugin.swift. This MetalCIKernelPlugin compiles Metal compute kernels during the build phase rather than runtime, minimizing the application footprint and ensuring shader code optimization before distribution.
Summary
- Four-layer architecture separates Presentation, State, Media Rendering, and External Services to maintain clean boundaries between SwiftUI and low-level AVFoundation code.
- Observable state management via
@MainActorand@ObservableinEditorViewModel.swiftensures automatic UI synchronization with thread-safe mutations. - Pure functional clip calculations in
Timeline.swiftenable testable per-frame sampling of transforms, opacity, and volume data. - Hybrid drag-and-drop uses AppKit fallbacks (
MediaPanelDropArea) to work around macOS 26 SwiftUI limitations while maintaining native SwiftUI leaf interactions. - AI-native infrastructure integrates ModelContextProtocol and Convex through
GenerationServicefor real-time media generation within the editing workflow. - Build-time optimization via
MetalCIKernelPluginpre-compiles Metal shaders to reduce runtime overhead.
Frequently Asked Questions
What makes Palmier Pro an "AI-native" video editor?
Palmier Pro embeds AI capabilities at the architectural level through the AgentService and GenerationService classes, which implement the ModelContextProtocol SDK to communicate with large language models. Unlike bolted-on features, AI generation uses the same placeClip pipeline as traditional media, allowing AI-generated assets to integrate seamlessly with the Timeline and VideoEngine for immediate preview and export.
How does Palmier Pro handle state updates across the SwiftUI interface?
The application uses Swift's @Observable macro combined with @MainActor confinement in EditorViewModel.swift. When mutable properties like timeline or currentFrame change, SwiftUI automatically schedules view updates without manual publisher management. The timelineRenderRevision counter provides a simple mechanism for non-SwiftUI observers like VideoEngine to detect changes and rebuild compositions accordingly.
Why does Palmier Pro use AppKit for drag-and-drop instead of pure SwiftUI?
On macOS 26, stacked SwiftUI .onDrop modifiers fail silently when overlays compete for drop events, as documented in AGENTS.md. The implementation solves this by using a native AppKit NSView subclass (MediaPanelDropArea) for container-level drop targets, while reserving SwiftUI .onDrop for individual media items. This hybrid approach ensures reliable drag-and-drop behavior across nested panel hierarchies.
How does the VideoEngine convert timeline data into playable video?
VideoEngine.swift monitors the timelineRenderRevision property and triggers rebuild() when changes occur. The engine uses CompositionBuilder to construct an AVComposition by iterating through tracks and clips, sampling per-frame transform and opacity values via Clip.transformAt(_:) and Clip.opacityAt(_:). The resulting composition attaches to an AVPlayer for scrubbing and playback, or exports via standard AVFoundation export sessions for final delivery.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →