Skip to content

yu2001-s/PaperDiet

PaperDiet

PaperDiet is an open source macOS app for shrinking PDFs with a native SwiftUI interface and a bundled Ghostscript backend.

Download and install

The easiest path for end users is a GitHub release build:

  1. Download the latest .zip from the repository's Releases page.
  2. Unzip it.
  3. Drag PaperDiet.app into /Applications.
  4. Open PaperDiet.app.
  5. If macOS shows a Not Opened warning, click Done, then right-click PaperDiet.app in Finder and choose Open.
  6. If macOS still blocks it, open System Settings > Privacy & Security and click Open Anyway for PaperDiet.

Release artifacts are produced by GitHub Actions and include the Ghostscript runtime plus the repo license and third-party notices. The workflow produces signed and notarized releases when the Apple Developer ID and notary secrets are configured; without those secrets, it still publishes an unsigned release archive.

PaperDiet release builds target Apple Silicon Macs only.

Current stack

PaperDiet is built with:

  • SwiftUI for the app shell and workflow
  • PDFKit for previewing imported PDFs
  • Ghostscript behind a Swift service boundary for compression

Current features

  • Native macOS Xcode project
  • Drag-and-drop PDF import
  • Multi-file queue with file size and page count analysis
  • Output-folder selection
  • Compression presets: Light, Balanced, Strong
  • Ghostscript discovery from:
    • bundled helper at Contents/Helpers/gs
    • GHOSTSCRIPT_PATH
    • common install paths
    • PATH
  • Background compression execution via Process
  • Progress parsing from Ghostscript page output
  • Before/after size reporting
  • PDF preview for original and compressed output

Build from source

PaperDiet runs as soon as it can resolve a gs executable. The easiest local setups are:

  1. Run sh Scripts/build-ghostscript-from-source.sh to produce a fully relocatable vendored runtime under Vendor/ghostscript-runtime.

  2. Or run sh Scripts/vendor-ghostscript-from-homebrew.sh to copy a local Homebrew install into Vendor/ghostscript-runtime.

  3. Build the app in Xcode, or use:

    xcodebuild -project PaperDiet.xcodeproj -scheme PaperDiet -configuration Debug -derivedDataPath /tmp/PaperDietDerivedData build CODE_SIGNING_ALLOWED=NO
  4. If you do not want a vendored runtime, install Ghostscript so gs is on your PATH.

  5. You can also launch Xcode with GHOSTSCRIPT_PATH pointing at a binary.

The Xcode target is configured for automatic Apple Development signing with team 5WM5U773A8. CI and command-line examples pass CODE_SIGNING_ALLOWED=NO when signing is not required, so contributors can still build without Apple credentials.

Release builds

  • Scripts/package-release.sh builds a Release app, bundles Ghostscript, and creates a distributable .zip in dist/.
  • Scripts/sign-app.sh optionally Developer ID-signs the app bundle and nested binaries.
  • Scripts/notarize-release.sh optionally submits the packaged archive to Apple's notary service, staples the ticket to the app, and validates stapling.
  • Scripts/prepare-github-secrets.sh base64-encodes your .p12 certificate and .p8 notary key into the exact GitHub secret values the release workflow expects.
  • Scripts/upload-github-secrets.sh uploads those five signing/notarization secrets to a GitHub repository via gh secret set.
  • .github/workflows/ci.yml validates that the app still compiles on GitHub-hosted macOS runners.
  • .github/workflows/release.yml builds tagged Apple Silicon releases, uploads release artifacts, and publishes them to GitHub Releases, with signing enabled only when Apple secrets are configured.

The current Xcode project signs local development builds with the Apple Development identity for team 5WM5U773A8. Public GitHub release signing still requires a Developer ID Application certificate plus Apple notary credentials.

To cut a release locally:

sh Scripts/package-release.sh

To cut a signed and notarized release locally, optionally provide:

  • DEVELOPER_ID_APPLICATION
  • APPLE_NOTARY_KEY_ID
  • APPLE_NOTARY_ISSUER_ID
  • either APPLE_NOTARY_API_KEY_PATH or APPLE_NOTARY_API_KEY_BASE64

To cut a release on GitHub:

  1. Push the repository to GitHub.
  2. Create and push a tag such as v0.1.0.
  3. Wait for the Release workflow to finish.
  4. Download the generated .zip assets from the GitHub release.

For signed GitHub releases, configure these GitHub Actions secrets:

  • APPLE_DEVELOPER_ID_CERT_P12_BASE64
  • APPLE_DEVELOPER_ID_CERT_PASSWORD
  • APPLE_NOTARY_API_KEY_BASE64
  • APPLE_NOTARY_KEY_ID
  • APPLE_NOTARY_ISSUER_ID

To prepare those secret values from local Apple credential files:

sh Scripts/prepare-github-secrets.sh /absolute/path/DeveloperID.p12 /absolute/path/AuthKey_<KEYID>.p8 <ISSUER-ID>

To upload them directly to GitHub:

sh Scripts/upload-github-secrets.sh <owner/repo> /absolute/path/DeveloperID.p12 /absolute/path/AuthKey_<KEYID>.p8 <ISSUER-ID> <P12-PASSWORD>

Repository structure

  • PaperDiet.xcodeproj: native macOS app project
  • PaperDiet/PaperDietApp.swift: app entry point
  • PaperDiet/ContentView.swift: main interface
  • PaperDiet/AppViewModel.swift: queue and workflow state
  • PaperDiet/Models: presets, descriptors, compression results
  • PaperDiet/Services: PDF analysis, Ghostscript discovery, process execution
  • PaperDiet/Views: PDFKit wrapper and drag/drop view

Bundling workflow

  • Scripts/build-ghostscript-from-source.sh downloads Ghostscript source, builds it into Vendor/ghostscript-runtime, and copies the Resource and iccprofiles trees needed for a relocatable app bundle.
  • Scripts/vendor-ghostscript-from-homebrew.sh copies a local Ghostscript installation into the repo-local vendor directory.
  • Scripts/stage-ghostscript-runtime.sh runs during Xcode builds and copies the Ghostscript executable into the app's Helpers folder while staging its support files into app resources.
  • At runtime, PaperDiet prefers the bundled helper and configures GS_LIB, GS_FONTPATH, DYLD_LIBRARY_PATH, GenericResourceDir, FontResourceDir, and ICCProfilesDir for that bundled layout.
  • The app bundle also carries LICENSE.txt and THIRD_PARTY_NOTICES.md in Contents/Resources.

This keeps Ghostscript as the real compression engine while keeping contributor setup simple.

Open source and licensing

PaperDiet is licensed under the GNU Affero General Public License v3.0 or later. This repository is set up to stay on Ghostscript's AGPL-compatible path. If you distribute PaperDiet with a bundled Ghostscript runtime, keep the repo license, release assets, and notices aligned with that requirement.

See:

Recommended next steps

  1. Add regression fixtures for scanned PDFs, vector PDFs, forms, bookmarks, and signed PDFs.
  2. Persist security-scoped bookmarks if you want queues to survive relaunches.
  3. Add batch export naming rules and overwrite behavior controls.
  4. Add a signed-release smoke test after the Developer ID and notary secrets are configured in CI.

About

Open source macOS app for shrinking PDFs with SwiftUI and Ghostscript.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors