> ## Documentation Index
> Fetch the complete documentation index at: https://ngquct-worktree-single-window-connections.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Development Setup

> Clone, configure signing, and build TablePro in Xcode

## Prerequisites

| Software | Version         | Notes                                                                      |
| -------- | --------------- | -------------------------------------------------------------------------- |
| Xcode    | 26.0+           | Ships the macOS 26 SDK the app builds against. Every CI job pins 26.4.1.   |
| Swift    | 5 language mode | Comes with Xcode, set by `SWIFT_VERSION` in `Configs/Base.xcconfig`        |
| XcodeGen | 2.46.0          | Generates `TablePro.xcodeproj` from `project.yml`. `brew install xcodegen` |

The app references macOS 26 SDK symbols (`NSGlassEffectView` in the quick switcher), so an older Xcode cannot compile it. The deployment target stays at macOS 14.0 Sonoma, which is what the built app runs on, not what you build on.

Optional but recommended:

| Tool        | Install                    | Purpose                    |
| ----------- | -------------------------- | -------------------------- |
| SwiftLint   | `brew install swiftlint`   | Linting                    |
| SwiftFormat | `brew install swiftformat` | Code formatting            |
| GitHub CLI  | `brew install gh`          | Used by `download-libs.sh` |

## Quick Start

<Steps>
  <Step title="Clone the repository">
    ```bash theme={null}
    git clone https://github.com/TableProApp/TablePro.git && cd TablePro
    ```
  </Step>

  <Step title="Download native libraries">
    ```bash theme={null}
    scripts/download-libs.sh
    ```

    This pulls two archives from the `libs-v1` GitHub Release into `Libs/`: the macOS `.a` files (libmariadb, libpq, libduckdb, libmongoc, and others) and the iOS xcframeworks. About 257 MB downloaded, 620 MB on disk once expanded. Expect a minute or two.

    <Warning>
      Skipping this step causes linker errors. The static libraries are not checked into git.
    </Warning>
  </Step>

  <Step title="Install tools">
    ```bash theme={null}
    brew install xcodegen swiftlint swiftformat
    ```
  </Step>

  <Step title="Generate the Xcode project">
    ```bash theme={null}
    scripts/generate-project.sh
    ```

    `TablePro.xcodeproj` and `TableProMobile/TableProMobile.xcodeproj` are generated from
    `project.yml` and are not in git. Run this again after changing `project.yml` or
    `Configs/`, and after adding, moving, or deleting a source file: XcodeGen collects
    sources at generation time, so a new file is not in the project until you regenerate.
  </Step>

  <Step title="Open in Xcode">
    ```bash theme={null}
    open TablePro.xcodeproj
    ```
  </Step>

  <Step title="Configure signing">
    ```bash theme={null}
    cp Configs/Secrets.xcconfig.example Configs/Secrets.xcconfig
    ```

    Set your own team and a unique bundle identifier:

    ```
    TABLEPRO_DEVELOPMENT_TEAM = YOUR_TEAM_ID
    TABLEPRO_APP_BUNDLE_IDENTIFIER = com.yourhandle.TablePro
    ```

    A free personal team works. The Debug configuration signs with
    `TablePro.Debug.entitlements`, which drops the iCloud capability, so no paid Apple
    Developer Program membership is needed. Plugin bundles and the MCP server sign ad-hoc,
    so they need no team at all.

    `Configs/Secrets.xcconfig` is gitignored, so these settings cannot reach a commit, and
    they survive regenerating the project. Do not change signing in the Xcode UI: the
    project is generated, and the next `scripts/generate-project.sh` discards the edit.
  </Step>

  <Step title="Build and run">
    Select the **TablePro** scheme, set destination to **My Mac**, press `Cmd+R`.

    Or from the command line:

    ```bash theme={null}
    xcodebuild -project TablePro.xcodeproj -scheme TablePro -configuration Debug build -skipPackagePluginValidation
    ```

    `Cmd+R` writes the app to DerivedData
    (`~/Library/Developer/Xcode/DerivedData/TablePro-*/Build/Products/Debug`). The
    `xcodebuild` command above writes to `build/Debug/TablePro.app` inside the repo instead.
  </Step>
</Steps>

Writing a driver plugin? See [Plugin Development](/development/plugin-development) to build one and [Testing a Custom Plugin](/development/testing-plugins) to run it in your local build.

<Frame caption="Xcode project setup">
  <img className="block dark:hidden" src="https://mintcdn.com/ngquct-worktree-single-window-connections/0eSwyiRb1941j03b/images/xcode-setup.png?fit=max&auto=format&n=0eSwyiRb1941j03b&q=85&s=1e82595734beab46e4c047a9accbac2e" alt="Xcode setup" width="3024" height="1722" data-path="images/xcode-setup.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/ngquct-worktree-single-window-connections/0eSwyiRb1941j03b/images/xcode-setup-dark.png?fit=max&auto=format&n=0eSwyiRb1941j03b&q=85&s=b7f14f12bb0352ce9843eef837f5be37" alt="Xcode setup" width="3024" height="1722" data-path="images/xcode-setup-dark.png" />
</Frame>

## Project Structure

<Tree>
  <Tree.Folder name="TablePro" defaultOpen>
    <Tree.Folder name="Core">
      <Tree.File name="Database/, Plugins/, Services/, Utilities/, SSH/, Autocomplete/" />
    </Tree.Folder>

    <Tree.Folder name="Views">
      <Tree.File name="Connection/, Editor/, Main/, Results/, Settings/, Sidebar/" />
    </Tree.Folder>

    <Tree.Folder name="Models" />

    <Tree.Folder name="ViewModels" />

    <Tree.Folder name="Extensions" />

    <Tree.Folder name="Theme" />

    <Tree.Folder name="Resources" />
  </Tree.Folder>

  <Tree.Folder name="Plugins">
    <Tree.File name=".tableplugin bundles + TableProPluginKit framework" />
  </Tree.Folder>

  <Tree.Folder name="Packages">
    <Tree.File name="TableProCore: shared SwiftPM modules used by the macOS and iOS apps" />
  </Tree.Folder>

  <Tree.Folder name="LocalPackages">
    <Tree.File name="Vendored CodeEditSourceEditor, CodeEditTextView, CodeEditLanguages" />
  </Tree.Folder>

  <Tree.Folder name="Libs">
    <Tree.File name="Pre-built static libraries (downloaded, not in git)" />
  </Tree.Folder>

  <Tree.Folder name="TableProMobile">
    <Tree.File name="iOS app" />
  </Tree.Folder>

  <Tree.Folder name="TableProTests" />

  <Tree.Folder name="TableProUITests" />

  <Tree.Folder name="docs">
    <Tree.File name="Mintlify docs site" />
  </Tree.Folder>

  <Tree.Folder name="scripts">
    <Tree.File name="build-release.sh, create-dmg.sh, download-libs.sh" />
  </Tree.Folder>
</Tree>

`Packages/TableProCore/Sources/TableProPluginKit` is a symlink to `Plugins/TableProPluginKit`. Edit the files under `Plugins/` only.

## Running Tests

```bash theme={null}
xcodebuild -project TablePro.xcodeproj -scheme TablePro test -skipPackagePluginValidation
```

Or in Xcode: `Cmd+U`. To run a single class or method, pass `-only-testing:TableProTests/TestClassName` or `-only-testing:TableProTests/TestClassName/testMethodName`.

## Linting and Formatting

Before committing:

```bash theme={null}
swiftlint lint --strict
swiftformat .
```

CI rejects warnings, so plain `swiftlint lint` is not enough. Full tooling reference: [Code Style](/development/code-style).

## Troubleshooting

| Problem                             | Fix                                                                 |
| ----------------------------------- | ------------------------------------------------------------------- |
| Linker errors about missing symbols | Run `scripts/download-libs.sh`                                      |
| SPM resolution fails                | Clean build folder (`Cmd+Shift+K`), reopen Xcode                    |
| Build fails after pulling           | Delete derived data: `rm -rf ~/Library/Developer/Xcode/DerivedData` |
| `TablePro.xcodeproj` does not exist | Run `scripts/generate-project.sh`                                   |
| Code signing errors                 | Change Team in Signing & Capabilities                               |

<Note>
  Pass `-skipPackagePluginValidation` on every `xcodebuild` invocation so the build does not stop on package plugin validation. `scripts/build-release.sh`, `scripts/build-plugin.sh`, `scripts/check-pluginkit-abi.sh`, and CI all pass it.
</Note>
