# Database Schema for Palmier Pro: JSON-Based Persistence Model Explained

> Discover the unique JSON-based persistence model for Palmier Pro. Learn how project data is stored as Swift Codable structs, explained in this article.

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

---

**Palmier Pro uses a JSON-based persistence layer instead of a traditional relational database, storing project data as Swift structs conforming to Codable in files with `.palmier` extensions.**

The database schema for Palmier Pro is implemented entirely through Swift's `Codable` protocol rather than external database engines. In the palmier-io/palmier-pro repository, all persistent data—from project registries to timeline compositions—lives as structured JSON files on disk. This architecture provides a flat, version-friendly storage system that requires no SQL migrations or complex schema management.

## Project Registry Schema

The project registry maintains a list of recently opened projects outside of the individual `.palmier` files.

### ProjectEntry

In [`Sources/PalmierPro/Project/ProjectRegistry.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Project/ProjectRegistry.swift), the `ProjectEntry` struct represents a single entry in the recent-projects list with the following JSON fields:

- `id`: UUID
- `url`: URL
- `createdDate`: Date
- `lastOpenedDate`: Date

### ProjectRegistry

The same file defines `ProjectRegistry`, which encapsulates an array of `ProjectEntry` objects. The registry reads from and writes to a file specified by `Project.registryFilename`, storing the entire collection as a single JSON array.

## Timeline and Composition Schema

The core data model resides in [`Sources/PalmierPro/Models/Timeline.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Models/Timeline.swift), defining the structure of individual project files.

### Timeline

The root object of every `.palmier` file contains global project settings and track data:

- `fps`: Int
- `width`: Int
- `height`: Int
- `settingsConfigured`: Bool
- `tracks`: [Track]

### Track

Each track represents a layer on the timeline with these properties:

- `id`: String
- `type`: ClipType
- `muted`: Bool
- `hidden`: Bool
- `syncLocked`: Bool
- `clips`: [Clip]

### Clip

The `Clip` struct stores media references, trimming data, and animation tracks:

- `id`: String
- `mediaRef`: String
- `mediaType`: ClipType
- `sourceClipType`: ClipType
- `startFrame`: Int
- `durationFrames`: Int
- `trimStartFrame`: Int
- `trimEndFrame`: Int
- `speed`: Double
- `volume`: Double
- `fadeInFrames`: Int
- `fadeOutFrames`: Int
- `fadeInInterpolation`: Interpolation
- `fadeOutInterpolation`: Interpolation
- `opacity`: Double
- `transform`: Transform
- `crop`: Crop
- `linkGroupId`: String?
- `captionGroupId`: String?
- `textContent`: String?
- `textStyle`: TextStyle?
- `opacityTrack`: KeyframeTrack<Double>?
- `positionTrack`: KeyframeTrack<AnimPair>?
- `scaleTrack`: KeyframeTrack<AnimPair>?
- `rotationTrack`: KeyframeTrack<Double>?
- `cropTrack`: KeyframeTrack<Crop>?
- `volumeTrack`: KeyframeTrack<Double>?

### Transform and Crop

Geometric transformations are defined as separate structs:

**Transform** contains:
- `centerX`: Double
- `centerY`: Double
- `width`: Double
- `height`: Double
- `rotation`: Double
- `flipHorizontal`: Bool
- `flipVertical`: Bool

**Crop** defines normalized inset values:
- `left`: Double
- `top`: Double
- `right`: Double
- `bottom`: Double

### ClipType Enumeration

The `ClipType` enum in [`Timeline.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Timeline.swift) defines supported media types including `video`, `audio`, `image`, and `text`.

## Keyframe Animation System

In [`Sources/PalmierPro/Models/Keyframe.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Models/Keyframe.swift), the generic `KeyframeTrack<V>` struct stores animation data for clip properties. Each track contains a `keyframes` array of `Keyframe<Value>` objects, supporting animated opacity, position, scale, rotation, crop, and volume values over time.

## Media Asset Management

The optional `MediaManifest` struct in [`Sources/PalmierPro/Models/MediaManifest.swift`](https://github.com/palmier-io/palmier-pro/blob/main/Sources/PalmierPro/Models/MediaManifest.swift) tracks imported assets. It contains an `entries` array of `MediaManifestEntry` objects, each storing `id`, `url`, `type`, and `duration` to locate source files referenced by the timeline.

## Reading and Writing the Schema

All structs conform to `Codable`, enabling standard JSON encoding and decoding. The database schema is deliberately flat—no nested SQL tables—making persistence straightforward.

### Loading a Timeline

```swift
import Foundation
import PalmierPro

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 Timeline

```swift
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)
}

```

### Registering Projects

```swift
func registerProject(at url: URL) {
    ProjectRegistry.shared.register(url)
}

```

### Enumerating Timeline Contents

```swift
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 handles versioning through custom `init(from:)` implementations in `Track` and `Clip`. Adding new properties to any struct automatically introduces new keys in the JSON output, while default values ensure older project files remain readable. This approach eliminates the need for migration scripts or version stamps.

## Summary

- **Palmier Pro** uses JSON files rather than SQL databases, with Swift structs conforming to `Codable` defining the schema.
- **ProjectRegistry.swift** manages the recent-projects list as an array of `ProjectEntry` objects.
- **Timeline.swift** contains the core composition data: `Timeline`, `Track`, `Clip`, `Transform`, and `Crop`.
- **Keyframe.swift** provides generic animation tracks via `KeyframeTrack<V>`.
- **MediaManifest.swift** optionally tracks imported media assets and their metadata.
- The schema is flat, human-readable, and supports backwards compatibility through default values in custom decoders.

## Frequently Asked Questions

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

No. According to the palmier-io/palmier-pro source code, Palmier Pro does not use SQLite, Core Data, or any traditional relational database engine. Instead, it persists all data as JSON files encoded through Swift's `Codable` protocol, storing project files with the `.palmier` extension and registry data in the application's support folder.

### How are media assets referenced in the database schema?

Media assets are referenced through the `mediaRef` string field in the `Clip` struct, which points to entries in an optional `MediaManifest`. The manifest, defined in [`MediaManifest.swift`](https://github.com/palmier-io/palmier-pro/blob/main/MediaManifest.swift), maps these references to actual file URLs and metadata such as duration and type, enabling the project to locate source files without embedding binary data in the JSON schema.

### What happens when the database schema changes in a new version of Palmier Pro?

The schema handles evolution through custom `init(from:)` implementations in `Track` and `Clip` structs. When new properties are added, the JSON encoder automatically includes them in output files, while the decoder provides default values for missing keys when reading older files. This ensures backwards compatibility without requiring explicit migration code or version checks.

### Where is the project registry stored on disk?

The project registry is stored separately from individual project files in the user's application support folder. Defined in [`ProjectRegistry.swift`](https://github.com/palmier-io/palmier-pro/blob/main/ProjectRegistry.swift), the registry uses the filename specified by `Project.registryFilename` and contains a JSON array of `ProjectEntry` objects tracking paths, creation dates, and last-opened dates for recent projects.