Understanding the Database Schema for Palmier Pro: JSON-Based Persistence Architecture

Palmier Pro does not use a traditional relational database; instead, it persists all project data as JSON files encoded with Swift’s Codable protocol, using a flat schema of structs including Timeline, Track, and Clip.

The open-source video editing application Palmier Pro (palmier-io/palmier-pro) stores project state through a file-based persistence layer rather than connecting to an external SQL database. Understanding the database schema for Palmier Pro requires examining its Swift struct definitions in the source code, which directly dictate the JSON structure saved to disk.

Project Registry Structure

The application maintains a global project registry separate from individual project files. This registry tracks recently opened projects and their metadata.

ProjectEntry and Registry Storage

In Sources/PalmierPro/Project/ProjectRegistry.swift, the ProjectEntry struct defines the schema for registry items with the following JSON fields:

  • id: UUID
  • url: URL (file location)
  • createdDate: Date
  • lastOpenedDate: Date

The ProjectRegistry class holds an array of these entries and persists them to a JSON file specified by Project.registryFilename. When the application launches, it decodes this array to populate the recent projects list.

// Accessing the shared registry
ProjectRegistry.shared.register(url: newProjectURL)

// The registry file stores: [ProjectEntry]
// Fields: id, url, createdDate, lastOpenedDate

Timeline and Track Schema

The core project file (.palmier extension) contains a single Timeline object that represents the entire editing sequence.

Timeline Global Settings

Defined in Sources/PalmierPro/Models/Timeline.swift, the Timeline struct contains project-wide configuration and an array of tracks:

// Key JSON fields in Timeline
{
  "fps": 30,
  "width": 1920,
  "height": 1080,
  "settingsConfigured": true,
  "tracks": [...]
}

Track Properties

Each Track represents a layer on the timeline (video, audio, image, or text) and includes:

  • id: String (unique identifier)
  • type: ClipType enum (video, audio, image, text)
  • muted: Bool
  • hidden: Bool
  • syncLocked: Bool
  • clips: Array of Clip objects

Clip Data Model and Transformations

The Clip struct stores the majority of editing data, including media references, trimming, effects, and animation keyframes.

Core Clip Fields

In Sources/PalmierPro/Models/Timeline.swift, each clip persists:

  • mediaRef: String (reference to source media)
  • mediaType and sourceClipType: ClipType enum values
  • startFrame: Int (timeline position)
  • durationFrames: Int
  • trimStartFrame and trimEndFrame: Int
  • speed: Double (playback rate)
  • volume: Double
  • fadeInFrames and fadeOutFrames: Int
  • fadeInInterpolation and fadeOutInterpolation: Interpolation type
  • opacity: Double
  • linkGroupId: Optional String
  • captionGroupId: Optional String
  • textContent: Optional String
  • textStyle: Optional TextStyle

Geometric Transforms

The Transform struct handles spatial properties:

  • centerX and centerY: Double
  • width and height: Double
  • rotation: Double
  • flipHorizontal: Bool
  • flipVertical: Bool

Cropping Data

The Crop struct stores normalized inset values:

  • left: Double
  • top: Double
  • right: Double
  • bottom: Double

Animation and Keyframe Storage

Palmier Pro supports animation through generic keyframe tracks stored per clip.

KeyframeTrack Implementation

In Sources/PalmierPro/Models/Keyframe.swift, the KeyframeTrack<V> generic struct stores animatable properties:

  • opacityTrack: KeyframeTrack
  • positionTrack: KeyframeTrack
  • scaleTrack: KeyframeTrack
  • rotationTrack: KeyframeTrack
  • cropTrack: KeyframeTrack
  • volumeTrack: KeyframeTrack

Each track contains an array of keyframe objects with timing and value data.

Media Manifest

Optional media tracking occurs in Sources/PalmierPro/Models/MediaManifest.swift. The MediaManifest maintains an entries array of MediaManifestEntry objects containing id, url, type, and duration fields, enabling the project to locate source files even if moved.

JSON Encoding and Decoding

All schema structs conform to Codable, enabling standard Swift JSON serialization. The persistence layer uses atomic writes to prevent data corruption.

Loading a Project

import Foundation

func loadTimeline(from url: URL) throws -> Timeline {
    let data = try Data(contentsOf: url)
    let decoder = JSONDecoder()
    return try decoder.decode(Timeline.self, from: data)
}

Saving a Project

func saveTimeline(_ timeline: Timeline, to url: URL) throws {
    let encoder = JSONEncoder()
    encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
    let data = try encoder.encode(timeline)
    try data.write(to: url, options: .atomic)
}

Enumerating Timeline Contents

for track in timeline.tracks {
    for clip in track.clips {
        print("Clip \(clip.id) of type \(clip.mediaType) starts at \(clip.startFrame)")
    }
}

Schema Evolution and Backwards Compatibility

The database schema for Palmier Pro is deliberately flat and version-friendly. Because the system uses JSON rather than rigid SQL tables, adding new properties to structs automatically introduces new keys in the serialized output.

Backwards compatibility is maintained through custom init(from:) implementations in Track and Clip that provide default values for missing fields. This allows older project files to load correctly even when opened in newer versions of the application that expect additional properties.

Summary

  • Palmier Pro uses JSON files, not SQL: All data persists as encoded Swift structs using the Codable protocol.
  • Two-tier storage: The ProjectRegistry tracks recent projects separately from individual .palmier timeline files.
  • Core models defined in Timeline.swift: The schema centers on Timeline, Track, and Clip structs with nested Transform and Crop objects.
  • Animation support: Generic KeyframeTrack<V> structures in Keyframe.swift handle animated properties.
  • Atomic writes: Projects save using JSONEncoder with .atomic write options to prevent corruption.
  • Schema evolution: New properties automatically extend the JSON format while custom decoders maintain backwards compatibility.

Frequently Asked Questions

Does Palmier Pro use SQLite or Core Data for its database?

No. According to the palmier-io/palmier-pro source code, the application does not use SQLite, Core Data, or any relational database. Instead, it relies entirely on JSON file persistence using Swift's Codable protocol, with project data stored as structured text files on disk.

How are project files organized on the filesystem?

Project files use the .palmier extension and contain a single JSON-encoded Timeline object. A separate registry file (location determined by Project.registryFilename in ProjectRegistry.swift) stores the list of recent projects as a JSON array of ProjectEntry objects in the user's application support folder.

What happens if the schema changes in a future update?

The schema handles evolution through Swift's default value support and custom init(from:) implementations. When new fields are added to structs like Clip or Track, the JSON decoder provides default values for missing keys, ensuring older project files remain compatible with newer application versions.

How does Palmier Pro handle missing media files?

The optional MediaManifest struct (defined in MediaManifest.swift) maintains a catalog of imported assets with their IDs and URLs. While clips store mediaRef strings pointing to these entries, the application can use the manifest to attempt to relink media if files are moved, though the primary schema relies on persistent URL references stored in each Clip instance.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →