# Key Concepts Behind Palmier Pro Implementation: A Four-Layer Architecture

> Explore the four-layer architecture of Palmier Pro, a native macOS video editor. Understand how SwiftUI, state management, AVFoundation, and AI services enable professional real-time video editing.

- Repository: [Palmier/palmier-pro](https://github.com/palmier-io/palmier-pro)
- Tags: architecture
- Published: 2026-06-30

---

**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`](https://github.com/palmier-io/palmier-pro/blob/main/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`](https://github.com/palmier-io/palmier-pro/blob/main/AGENTS.md).

### State and Business Logic Layer

The **State** layer centers on [`Sources/PalmierPro/Editor/ViewModel/EditorViewModel.swift`](https://github.com/palmier-io/palmier-pro/blob/main/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`](https://github.com/palmier-io/palmier-pro/blob/main/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`](https://github.com/palmier-io/palmier-pro/blob/main/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`](https://github.com/palmier-io/palmier-pro/blob/main/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:

```swift
@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`](https://github.com/palmier-io/palmier-pro/blob/main/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:

```swift
// 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:

```swift
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`](https://github.com/palmier-io/palmier-pro/blob/main/Package.swift) defines a custom build tool plugin located at [`Plugins/MetalCIKernelPlugin/MetalCIKernelPlugin.swift`](https://github.com/palmier-io/palmier-pro/blob/main/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 `@MainActor` and `@Observable` in [`EditorViewModel.swift`](https://github.com/palmier-io/palmier-pro/blob/main/EditorViewModel.swift) ensures automatic UI synchronization with thread-safe mutations.
- **Pure functional clip calculations** in [`Timeline.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Timeline.swift) enable 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 `GenerationService` for real-time media generation within the editing workflow.
- **Build-time optimization** via `MetalCIKernelPlugin` pre-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`](https://github.com/palmier-io/palmier-pro/blob/main/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`](https://github.com/palmier-io/palmier-pro/blob/main/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`](https://github.com/palmier-io/palmier-pro/blob/main/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.