using-xtool

This skill should be used when building iOS apps with xtool (Xcode-free iOS development), creating xtool projects, adding app extensions, or configuring xtool.yml. Triggers on "xtool", "SwiftPM iOS", "iOS on Linux", "iOS on Windows", "Xcode-free", "app extension", "widget extension", "share extension". Covers project setup, app extensions, and deployment.

242 stars

Best use case

using-xtool is best used when you need a repeatable AI agent workflow instead of a one-off prompt. It is especially useful for teams working in multi. This skill should be used when building iOS apps with xtool (Xcode-free iOS development), creating xtool projects, adding app extensions, or configuring xtool.yml. Triggers on "xtool", "SwiftPM iOS", "iOS on Linux", "iOS on Windows", "Xcode-free", "app extension", "widget extension", "share extension". Covers project setup, app extensions, and deployment.

This skill should be used when building iOS apps with xtool (Xcode-free iOS development), creating xtool projects, adding app extensions, or configuring xtool.yml. Triggers on "xtool", "SwiftPM iOS", "iOS on Linux", "iOS on Windows", "Xcode-free", "app extension", "widget extension", "share extension". Covers project setup, app extensions, and deployment.

Users should expect a more consistent workflow output, faster repeated execution, and less time spent rewriting prompts from scratch.

Practical example

Example input

Use the "using-xtool" skill to help with this workflow task. Context: This skill should be used when building iOS apps with xtool (Xcode-free iOS development), creating xtool projects, adding app extensions, or configuring xtool.yml. Triggers on "xtool", "SwiftPM iOS", "iOS on Linux", "iOS on Windows", "Xcode-free", "app extension", "widget extension", "share extension". Covers project setup, app extensions, and deployment.

Example output

A structured workflow result with clearer steps, more consistent formatting, and an output that is easier to reuse in the next run.

When to use this skill

  • Use this skill when you want a reusable workflow rather than writing the same prompt again and again.

When not to use this skill

  • Do not use this when you only need a one-off answer and do not need a reusable workflow.
  • Do not use it if you cannot install or maintain the related files, repository context, or supporting tools.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/using-xtool/SKILL.md --create-dirs "https://raw.githubusercontent.com/aiskillstore/marketplace/main/skills/2389-research/using-xtool/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/using-xtool/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How using-xtool Compares

Feature / Agentusing-xtoolStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

This skill should be used when building iOS apps with xtool (Xcode-free iOS development), creating xtool projects, adding app extensions, or configuring xtool.yml. Triggers on "xtool", "SwiftPM iOS", "iOS on Linux", "iOS on Windows", "Xcode-free", "app extension", "widget extension", "share extension". Covers project setup, app extensions, and deployment.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Using xtool

## Overview

xtool is a **cross-platform Xcode replacement** for building iOS apps with SwiftPM on Linux, Windows, and macOS. It is NOT XcodeGen, Tuist, or Xcode project files.

## Critical: xtool is NOT XcodeGen

| xtool Uses | NOT These |
|------------|-----------|
| `xtool.yml` | `project.yml`, `Project.swift` |
| `Package.swift` (SwiftPM) | Xcode project files |
| `xtool dev` | `xtool build`, `xtool run`, `xtool generate` |
| `Sources/` directory | `Extensions/` directory |

## Project Structure

```
MyApp/
├── Package.swift          # SwiftPM package definition
├── xtool.yml              # xtool configuration
├── Sources/
│   ├── MyApp/             # Main app target
│   │   ├── MyAppApp.swift
│   │   └── ContentView.swift
│   └── MyWidget/          # Extension target (if any)
│       └── Widget.swift
├── MyApp-Info.plist       # Optional custom Info.plist
└── MyWidget-Info.plist    # Required for extensions
```

## Quick Reference: Commands

```bash
# Project lifecycle
xtool new MyApp              # Create new project
xtool new MyApp --skip-setup # Create without running setup
xtool dev                    # Build + run (same as `xtool dev run`)
xtool dev build              # Build only
xtool dev build --ipa        # Build IPA file
xtool dev run -s             # Run on iOS Simulator (--simulator)
xtool dev run -c release     # Release build (--configuration)
xtool dev run -u <udid>      # Target specific device (--udid)
xtool dev generate-xcode-project  # Generate .xcodeproj for debugging

# Device management
xtool devices                # List connected devices
xtool install app.ipa        # Install IPA to device
xtool launch                 # Launch installed app
xtool uninstall              # Uninstall app from device

# Authentication & setup
xtool setup                  # Full setup (auth + SDK)
xtool auth login             # Authenticate with Apple
xtool auth status            # Check auth status
xtool auth logout            # Log out
xtool sdk                    # Manage Darwin Swift SDK

# Developer Services
xtool ds teams               # List development teams
xtool ds certificates        # Manage certificates
xtool ds profiles            # Manage provisioning profiles
```

## xtool.yml Format

Minimal:
```yaml
version: 1
bundleID: com.example.MyApp
```

Full options:
```yaml
version: 1
bundleID: com.example.MyApp
product: MyApp                    # Which SwiftPM product is main app
infoPath: MyApp-Info.plist        # Custom Info.plist (merged)
iconPath: Resources/AppIcon.png   # App icon (1024x1024 PNG)
entitlementsPath: App.entitlements
resources:                        # Files copied to app bundle root
  - Resources/GoogleServices-Info.plist
extensions:                       # App extensions
  - product: MyWidget
    infoPath: MyWidget-Info.plist
```

## Adding App Extensions (Widgets, Share, etc.)

### Step 1: Update Package.swift

Add BOTH a product AND a target. Note: xtool uses `.library` (not `.executable`) - it bundles the library into an iOS app.

```swift
// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "MyApp",
    platforms: [.iOS(.v17)],
    products: [
        .library(name: "MyApp", targets: ["MyApp"]),
        .library(name: "MyWidget", targets: ["MyWidget"]),  // ADD
    ],
    targets: [
        .target(name: "MyApp"),
        .target(name: "MyWidget"),  // ADD
    ]
)
```

### Step 2: Update xtool.yml

```yaml
version: 1
bundleID: com.example.MyApp
product: MyApp
extensions:
  - product: MyWidget
    infoPath: MyWidget-Info.plist
```

### Step 3: Create Extension Info.plist

Minimal required (just the extension type):

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSExtension</key>
    <dict>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.widgetkit-extension</string>
    </dict>
</dict>
</plist>
```

### Step 4: Create Extension Code

`Sources/MyWidget/Widget.swift`:
```swift
import WidgetKit
import SwiftUI

@main struct MyWidgetBundle: WidgetBundle {
    var body: some Widget { MyWidget() }
}

struct MyWidget: Widget {
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: "MyWidget", provider: Provider()) { entry in
            Text(entry.date, style: .date)
                .containerBackground(.fill.tertiary, for: .widget)
        }
        .configurationDisplayName("My Widget")
    }
}

struct Entry: TimelineEntry { var date = Date() }

struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> Entry { Entry() }
    func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
        completion(Entry())
    }
    func getTimeline(in context: Context, completion: @escaping (Entry) -> Void) {
        completion(Timeline(entries: [Entry()], policy: .after(.now + 3600)))
    }
}
```

### Step 5: Build and Run

```bash
xtool dev
```

## Common Extension Types

| Extension | NSExtensionPointIdentifier |
|-----------|---------------------------|
| Widget (WidgetKit) | `com.apple.widgetkit-extension` |
| Share | `com.apple.share-services` |
| Action | `com.apple.ui-services` |
| Safari | `com.apple.Safari.web-extension` |
| Keyboard | `com.apple.keyboard-service` |
| Today (deprecated) | `com.apple.widget-extension` |

## Troubleshooting

| Error | Solution |
|-------|----------|
| "Untrusted Developer" | Settings > General > VPN & Device Management > Trust |
| Device not found | Connect USB, run `xtool devices`, enable Developer Mode |
| Auth failed | Run `xtool auth login` |
| Build fails on first run | Normal - SDK modules building. Wait for completion. |

## Resources Configuration

SwiftPM resources (in bundle subdirectory):
```swift
.target(name: "MyApp", resources: [.copy("Blob.png")])
// Access: Image("Blob", bundle: Bundle.module)
```

Top-level resources (in app bundle root):
```yaml
# xtool.yml
resources:
  - Resources/GoogleServices-Info.plist
```

## Entitlements

```yaml
# xtool.yml
entitlementsPath: App.entitlements
```

```xml
<!-- App.entitlements -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.developer.homekit</key>
    <true/>
</dict>
</plist>
```

## Common Mistakes

| Mistake | Fix |
|---------|-----|
| Using `xtool build` | Use `xtool dev build` |
| Using `project.yml` | Use `xtool.yml` |
| Using `Extensions/` dir | Use `Sources/` (standard SwiftPM) |
| Forgetting Package.swift | Extensions need product + target in Package.swift |
| Complex extension Info.plist | Only NSExtension/NSExtensionPointIdentifier required |

Related Skills

using-neon

242
from aiskillstore/marketplace

Guides and best practices for working with Neon Serverless Postgres. Covers getting started, local development with Neon, choosing a connection method, Neon features, authentication (@neondatabase/auth), PostgREST-style data API (@neondatabase/neon-js), Neon CLI, and Neon's Platform API/SDKs. Use for any Neon-related questions.

when-using-flow-nexus-platform-use-flow-nexus-platform

242
from aiskillstore/marketplace

Comprehensive Flow Nexus platform management covering authentication, sandboxes, storage, databases, app deployment, payments, and monitoring. This SOP provides end-to-end platform operations.

when-using-advanced-swarm-use-swarm-advanced

242
from aiskillstore/marketplace

Advanced swarm patterns with dynamic topology switching and self-organizing behaviors for complex multi-agent coordination

using-superpowers

242
from aiskillstore/marketplace

Meta-skill enforcing skill discovery and invocation discipline through mandatory workflows. Use when starting any conversation to check for relevant skills before any response, ensuring skill-first workflow before proceeding.

using-git-worktrees

242
from aiskillstore/marketplace

Git worktree–based workspace isolation for parallel or non-disruptive development. Use when work must occur without modifying or interfering with the current working tree.

using-argc-argcfile

242
from aiskillstore/marketplace

Create and modify Argcfiles using the special syntax required. Use this when editing Argcfile.sh, @argc, or any shell script that contains `argc --argc-eval`.

using-beads-bv

242
from aiskillstore/marketplace

Use when coordinating dependency-aware task planning with beads (bd) CLI and bv graph sidecar - covers ready work selection, priority management, and robot flags for deterministic outputs

using-agent-relay

242
from aiskillstore/marketplace

Use when coordinating multiple AI agents in real-time - provides inter-agent messaging via tmux wrapper (sub-5ms latency) or file-based team inbox for async workflows

azure-quotas

242
from aiskillstore/marketplace

Check/manage Azure quotas and usage across providers. For deployment planning, capacity validation, region selection. WHEN: "check quotas", "service limits", "current usage", "request quota increase", "quota exceeded", "validate capacity", "regional availability", "provisioning limits", "vCPU limit", "how many vCPUs available in my subscription".

DevOps & Infrastructure

raindrop-io

242
from aiskillstore/marketplace

Manage Raindrop.io bookmarks with AI assistance. Save and organize bookmarks, search your collection, manage reading lists, and organize research materials. Use when working with bookmarks, web research, reading lists, or when user mentions Raindrop.io.

Data & Research

zlibrary-to-notebooklm

242
from aiskillstore/marketplace

自动从 Z-Library 下载书籍并上传到 Google NotebookLM。支持 PDF/EPUB 格式,自动转换,一键创建知识库。

discover-skills

242
from aiskillstore/marketplace

当你发现当前可用的技能都不够合适(或用户明确要求你寻找技能)时使用。本技能会基于任务目标和约束,给出一份精简的候选技能清单,帮助你选出最适配当前任务的技能。