Skip to main content
skill CX Codex

macos-spm-app-packaging — Claude Code skill: build macOS apps without

A skill that scaffolds, builds and packages SwiftPM macOS apps without an Xcode project, from the starter layout to signing and notarization.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add Dimillian/Skills --skill macos-spm-app-packaging -a claude-code
Open on GitHub

What macos-spm-app-packaging does

The skill walks you through two steps. First you copy assets/templates/bootstrap/ into a new repo, rename MyApp in Package.swift, Sources/MyApp/ and version.env, then set APP_NAME, BUNDLE_ID and versions. Next you copy the scripts from assets/templates/ into Scripts/, build with swift build and swift test, package with Scripts/package_app.sh and run Scripts/compile_and_run.sh.

What you get is a set of templates: .app bundle assembly with resources and signing, a dev loop that kills the running app and relaunches it, .icns generation from an Icon Composer file, notarization with stapling and zip, Sparkle appcast entries, a stable dev signing identity and a plain launcher. For releases there are Scripts/sign-and-notarize.sh and Scripts/make_appcast.sh, followed by a git tag and a GitHub release.

A table of common notarization failures lists the symptom, the likely cause and the recovery: duplicate version submissions, mismatched entitlements, a missing --options runtime flag in codesign, a hung xcrun notarytool, a staple ticket that has not propagated. The scripts target macOS, and build_icon.sh needs Xcode installed. If you do not use Sparkle for updates, strip those steps from the templates — otherwise BUILD_NUMBER in version.env has to go up with every release.

What it helps with

  • scaffold a SwiftPM macOS app from scratch
  • assemble a .app bundle with a script instead of Xcode
  • sign and notarize a release build
  • generate Sparkle appcast entries for updates
  • set up a stable dev code-signing identity

Example prompts for the agent

  • Scaffold a SwiftPM macOS app and rename MyApp to HelloApp
  • Package the app with Scripts/package_app.sh and launch it
  • Sign and notarize the release build, then make the appcast

How to install macos-spm-app-packaging

1Skills CLI (Vercel)

npx skills add Dimillian/Skills --skill macos-spm-app-packaging -a claude-code

2Manually: put the files in place

~/.claude/skills/macos-spm-app-packaging/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/macos-spm-app-packaging/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about macos-spm-app-packaging

How do I install macos-spm-app-packaging in Claude?

Run npx skills add Dimillian/Skills --skill macos-spm-app-packaging -a claude-code. The skill lands in ~/.claude/skills/macos-spm-app-packaging/SKILL.md.

What does macos-spm-app-packaging do?

It takes a SwiftPM macOS app from an empty folder to a built, packaged .app, then handles signing, notarization and appcast generation, all without an Xcode project.

What do I need for it to work?

The scripts run on macOS, and Scripts/build_icon.sh requires Xcode installed. Notarization needs an App Store Connect API key.

Source text

SKILL.md · MIT
---
name: macos-spm-app-packaging
description: Scaffold, build, and package SwiftPM-based macOS apps without an Xcode project. Use when you need a from-scratch macOS app layout, SwiftPM targets/resources, a custom .app bundle assembly script, or signing/notarization/appcast steps outside Xcode.
---

# macOS SwiftPM App Packaging (No Xcode)

## Overview
Bootstrap a complete SwiftPM macOS app folder, then build, package, and run it without Xcode. Use `assets/templates/bootstrap/` for the starter layout and `references/packaging.md` + `references/release.md` for packaging and release details.

## Two-Step Workflow
1) Bootstrap the project folder
   - Copy `assets/templates/bootstrap/` into a new repo.
   - Rename `MyApp` in `Package.swift`, `Sources/MyApp/`, and `version.env`.
   - Customize `APP_NAME`, `BUNDLE_ID`, and versions.

2) Build, package, and run the bootstrapped app
   - Copy scripts from `assets/templates/` into your repo (for example, `Scripts/`).
   - Build/tests: `swift build` and `swift test`.
   - Package: `Scripts/package_app.sh`.
   - Run: `Scripts/compile_and_run.sh` (preferred) or `Scripts/launch.sh`.
   - Release (optional): `Scripts/sign-and-notarize.sh` and `Scripts/make_appcast.sh`.
   - Tag + GitHub release (optional): create a git tag, upload the zip/appcast to the GitHub release, and publish.

## Minimum End-to-End Example
Shortest path from bootstrap to a running app:
```bash
# 1. Copy and rename the skeleton
cp -R assets/templates/bootstrap/ ~/Projects/MyApp
cd ~/Projects/MyApp
sed -i '' 's/MyApp/HelloApp/g' Package.swift version.env

# 2. Copy scripts
cp assets/templates/package_app.sh Scripts/
cp assets/templates/compile_and_run.sh Scripts/
chmod +x Scripts/*.sh

# 3. Build and launch
swift build
Scripts/compile_and_run.sh
```

## Validation Checkpoints
Run these after key steps to catch failures early before proceeding to the next stage.

**After packaging (`Scripts/package_app.sh`):**
```bash
# Confirm .app bundle structure is intact
ls -R build/HelloApp.app/Contents

# Check that the binary is present and executable
file build/HelloApp.app/Contents/MacOS/HelloApp
```

**After signing (`Scripts/sign-and-notarize.sh` or ad-hoc dev signing):**
```bash
# Inspect signature and entitlements
codesign -dv --verbose=4 build/HelloApp.app

# Verify the bundle passes Gatekeeper checks locally
spctl --assess --type execute --verbose build/HelloApp.app
```

**After notarization and stapling:**
```bash
# Confirm the staple ticket is attached
stapler validate build/HelloApp.app

# Re-run Gatekeeper to confirm notarization is recognised
spctl --assess --type execute --verbose build/HelloApp.app
```

## Common Notarization Failures
| Symptom | Likely Cause | Recovery |
|---|---|---|
| `The software asset has already been uploaded` | Duplicate submission for same version | Bump `BUILD_NUMBER` in `version.env` and repackage. |
| `Package Invalid: Invalid Code Signing Entitlements` | Entitlements in `.entitlements` file don't match provisioning | Audit entitlements against Apple's allowed set; remove unsupported keys. |
| `The executable does not have the hardened runtime enabled` | Missing `--options runtime` flag in `codesign` invocation | Edit `sign-and-notarize.sh` to add `--options runtime` to all `codesign` calls. |
| Notarization hangs / no status email | `xcrun notarytool` network or credential issue | Run `xcrun notarytool history` to check status; re-export App Store Connect API key if expired. |
| `stapler validate` fails after successful notarization | Ticket not yet propagated | Wait ~60 s, then re-run `xcrun stapler staple`. |

## Templates
- `assets/templates/package_app.sh`: Build binaries, create the .app bundle, copy resources, sign.
- `assets/templates/compile_and_run.sh`: Dev loop to kill running app, package, launch.
- `assets/templates/build_icon.sh`: Generate .icns from an Icon Composer file (requires Xcode install).
- `assets/templates/sign-and-notarize.sh`: Notarize, staple, and zip a release build.
- `assets/templates/make_appcast.sh`: Generate Sparkle appcast entries for updates.
- `assets/templates/setup_dev_signing.sh`: Create a stable dev code-signing identity.
- `assets/templates/launch.sh`: Simple launcher for a packaged .app.
- `assets/templates/version.env`: Example version file consumed by packaging scripts.
- `assets/templates/bootstrap/`: Minimal SwiftPM macOS app skeleton (Package.swift, Sources/, version.env).

## Notes
- Keep entitlements and signing configuration explicit; edit the template scripts instead of reimplementing.
- Remove Sparkle steps if you do not use Sparkle for updates.
- Sparkle relies on the bundle build number (`CFBundleVersion`), so `BUILD_NUMBER` in `version.env` must increase for each update.
- For menu bar apps, set `MENU_BAR_APP=1` when packaging to emit `LSUIElement` in Info.plist.

© Dimillian · MIT · Dimillian/Skills

Similar skills

Everything for Mobile →

From the same set11

swift-concurrency-expert Skill reviews and fixes concurrency issues in Swift 6.2+: adds Sendable conformance, applies @MainActor, resolves actor isolation warnings, and migrates completion handlers to async/await. CX Codex +1 2,000installs app-store-changelog Turns commits since your last tag into App Store “What's New” copy. Handy right before you ship a build to the store. CX Codex +1 1,300installs react-component-performance Identifies React render hotspots, isolates fast-changing state, and eliminates re-render churn. Useful when lists lag or components re-render too often. CX Codex +1 1,100installs github Guides coding agents to use the gh CLI for inspecting pull requests, issues, and failed CI workflows. CX Codex +1 870installs review-and-simplify-changes Reviews changed code for reuse, quality, efficiency and clarity, then optionally applies safe fixes. Useful right before you commit. CX Codex +1 794installs project-skill-audit Audits past Codex sessions, memory logs, and local skills. It identifies recurring workflows to recommend high-priority skill updates or additions. CX Codex +1 785installs review-swarm Runs a parallel read-only review of a git diff or selected files. Use it to surface regressions, security concerns, and missing test coverage before merging. CX Codex +1 756installs bug-hunt-swarm Investigates bugs with parallel sub-agents and ranks likely root causes. Use it for regressions, crashes, flaky behaviour, and failures when code edits must wait. CX Codex +1 713installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor