{"id":50745067,"url":"https://github.com/KevinVitale/SwiftSDL","last_synced_at":"2026-06-27T23:00:52.808Z","repository":{"id":70157775,"uuid":"132686334","full_name":"KevinVitale/SwiftSDL","owner":"KevinVitale","description":"SDL3 in Swift","archived":false,"fork":false,"pushed_at":"2025-12-17T02:11:52.000Z","size":43530,"stargazers_count":121,"open_issues_count":2,"forks_count":11,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-06-20T07:04:11.434Z","etag":null,"topics":["apple","audio","demo","game-development","game-loop","gamedev","graphics","ios","linux","macos","sdl","sdl2","sdl3","spm","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KevinVitale.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-05-09T01:45:33.000Z","updated_at":"2026-06-15T01:41:17.000Z","dependencies_parsed_at":"2023-05-15T11:00:46.094Z","dependency_job_id":null,"html_url":"https://github.com/KevinVitale/SwiftSDL","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/KevinVitale/SwiftSDL","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVitale%2FSwiftSDL","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVitale%2FSwiftSDL/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVitale%2FSwiftSDL/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVitale%2FSwiftSDL/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KevinVitale","download_url":"https://codeload.github.com/KevinVitale/SwiftSDL/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVitale%2FSwiftSDL/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34870654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-27T02:00:06.362Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apple","audio","demo","game-development","game-loop","gamedev","graphics","ios","linux","macos","sdl","sdl2","sdl3","spm","swift"],"created_at":"2026-06-10T20:00:38.587Z","updated_at":"2026-06-27T23:00:52.798Z","avatar_url":"https://github.com/KevinVitale.png","language":"Swift","funding_links":[],"categories":["Swift"],"sub_categories":[],"readme":"# SwiftSDL — Cross-Platform Targets with Swift \u0026 SDL3\n\n[![license](https://img.shields.io/badge/license-mit-brightgreen.svg)](LICENSE.md)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FKevinVitales%2FSwiftSDL%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/KevinVitale/SwiftSDL)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FKevinVitale%2FSwiftSDL%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/KevinVitale/SwiftSDL)\n \n **SwiftSDL** is an open-source Swift library that provides a complete interface for working with the C-based [SDL (Simple DirectMedia Layer)](https://www.libsdl.org/) library. This wrapper allows developers to leverage SDL's cross-platform multimedia and game development capabilities in Swift applications across macOS, iOS, and Linux.\n \n ## \u003cimg src=\"https://www.libsdl.org/media/SDL_logo.png\" height=\"20\" max-width=\"90%\" alt=\"SDL2\" /\u003e Simple DirectMedia Layer 3.0\n\n \u003e _\"Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL/Direct3D/Metal/Vulkan. It is used by video playback software, emulators, and popular games including Valve's award winning catalog and many Humble Bundle games.\"_ - [wiki.libsdl.org](https://wiki.libsdl.org/SDL3/FrontPage)\n\n## 🏁 Getting Started\n\n### 📋 Requirements\n\n- [Swift 6.0.2](https://www.swift.org/install/macos/), or later; and,\n- [SDL v3.1.6-preview](https://github.com/libsdl-org/SDL/releases/tag/preview-3.1.6), (required only for Linux).\n\n### 🔧 Installation\n\n```swift\n// swift-tools-version: 6.0\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"MySDLGame\",\n    platforms: [\n      .macOS(.v13)\n    ],\n    dependencies: [\n      .package(url: \"https://github.com/KevinVitale/SwiftSDL.git\", from: \"0.2.0-alpha.16\"),),\n    ],\n    targets: [\n        .executableTarget(\n            name: \"SwiftSDLTest\",\n            dependencies: [\n              \"SwiftSDL\"\n            ],\n            resources: [\n              .process(\"../Resources/BMP\"),\n            ]\n        ),\n    ]\n)\n```\n\n## 👀 Overview\n\nLike Swift itself, SwiftSDL makes SDL3 approachable for newcomers and powerful for experts.\n\n### 👾 Introduction\n\nA complete SwiftSDL game consists of the following 22-lines of code:\n\n```swift\nimport SwiftSDL\n\n@main\nfinal class MyGame: Game {\n    private enum CodingKeys: String, CodingKey {\n        case options\n    }\n\n    @OptionGroup\n    var options: GameOptions\n\n    func onReady(window: any Window) throws(SDL_Error) {\n      /* create a renderer, or acquire a gpu device. */\n      /* load assets or resources. */\n    }\n\n    func onUpdate(window: any Window) throws(SDL_Error) {\n      /* handle game logic and render frames */\n    }\n\n    func onEvent(window: any Window, _ event: SDL_Event) throws(SDL_Error) {\n      /* respond to events */\n    }\n\n    func onShutdown(window: (any Window)?) throws(SDL_Error) {\n      /* release objects and unload resources */\n    }\n}\n```\n\nThe class, `MyGame`, conforms to the `Game` protocol. A window is created automatically using reasonable defaults, although, it's possible to override the window's creation manually.\n\nUnderneath the hood, the `Game` protocol has implemented [SDL3's new main callbacks](https://wiki.libsdl.org/SDL3/README/main-functions#how-to-use-main-callbacks-in-sdl3).\n\n`GameOptions` are runtime arguments which alter the behavior or your application, such as your window's appearance.\n\n### 🧩 Tutorial\n\nLet's create an app using SwiftSDL from start-to-finish.\n\n#### Step 1: Create the project\nUsing Swift's command-line utility, we'll create the project in an empty directory\n\n```bash\n# Create an empty directory for our project\nmkdir MyGame\ncd MyGame\n\n# Create the executable package\nswift package init --type executable\n```\n \n#### Step 2: Add SwiftSDL\n\nUpdate the `Package.swift` file to include SwiftSDL as a dependency:\n\n\u003e **Note:** you may need adjust `platforms` to use `.macOS(.v13)`.\n\n```swift\n// swift-tools-version: 6.0\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"MyGame\",\n    platforms: [\n        .macOS(.v13)\n    ],\n    dependencies: [\n      .package(url: \"https://github.com/KevinVitale/SwiftSDL.git\", from: \"0.2.0-alpha.17\")\n    ],\n    targets: [\n        // Targets can depend on other targets in this package and products from dependencies.\n        .executableTarget(\n            name: \"MyGame\",\n            dependencies: [\n               \"SwiftSDL\"\n            ]\n        ),\n    ]\n)\n```\n\n#### Step 3: Create the game\n\nRename `main.swift` to `MyGame.swift`:\n\n```bash\nmv Sources/main.swift Sources/MyGame.swift\n```\n\nThen replace `MyGame.swift` with the following code:\n\n```swift\nimport SwiftSDL\n\n@main\nfinal class MyGame: Game {\n    private enum CodingKeys: String, CodingKey {\n      case options, message\n    }\n\n    @OptionGroup\n    var options: GameOptions\n\n    @Argument\n    var message: String = \"Hello, SwiftSDL!\"\n\n    private var renderer: (any Renderer)! = nil\n\n    func onReady(window: any Window) throws(SDL_Error) {\n      renderer = try window.createRenderer()\n    }\n\n    func onUpdate(window: any Window) throws(SDL_Error) {\n      try renderer\n        .clear(color: .gray)\n        .debug(text: message, position: [12, 12], scale: [2, 2])\n        .fill(rects: [24, 48, 128, 128], color: .white)\n        .fill(rects: [36, 60, 104, 104], color: .green)\n        .present()\n    }\n\n    func onEvent(window: any Window, _ event: SDL_Event) throws(SDL_Error) {\n    }\n\n    func onShutdown(window: (any Window)?) throws(SDL_Error) {\n      renderer = nil\n    }\n}\n```\n\nThen start the game:\n\n```bash\nswift run\n```\n\n\u003e **Note:** You should see a window with a gray background, a message saying _\"Hello, SwiftSDL!\"_, and two squares: one large white one, and a smaller green one.\n\nYour game has several options built-in. To see them all, use `--help`:\n\n```bash\nswift run MyGame --help\nUSAGE: my-game [\u003coptions\u003e] [\u003cmessage\u003e]\n\nARGUMENTS:\n  \u003cmessage\u003e               (default: Hello, SwiftSDL!)\n\nOPTIONS:\n  --hide-cursor           Hide the system's cursor\n  --auto-scale-content    Stretch the content to fill the window\n  --logical-size \u003clogical-size\u003e\n                          Forces the rendered content to be a certain logical size (WxH)\n  --logical-presentation \u003clogical-presentation\u003e\n                          Forces the rendered content to be a certain logical order; overrides '--auto-scale-content' (values: disabled,\n                          stretch, letterbox, overscan, integer-scale; default: disabled)\n  --vsync-rate \u003cvsync-rate\u003e\n                          Set vertical synchronization rate (values: adaptive, disabled, interger value; default: disabled)\n  --window-always-on-top  Window is always kept on top\n  --window-fullscreen     Window is set to fullscreen\n  --window-transparent    Window is uses a transparent buffer\n  --window-maximized      Create a maximized window; requires '--window-resizable'\n  --window-minimized      Create a minimized window\n  --window-max-size \u003cwindow-max-size\u003e\n                          Specify the maximum window's size (WxH)\n  --window-min-size \u003cwindow-min-size\u003e\n                          Specify the minimum window's size (WxH)\n  --window-mouse-focus    Force the window to have mouse focus\n  --window-no-frame       Create a borderless window\n  --window-resizable      Enable window resizability\n  --window-position \u003cwindow-position\u003e\n                          Specify the window's position (XxY)\n  --window-size \u003cwindow-size\u003e\n                          Specify the window's size (WxH)\n  --window-title \u003cwindow-title\u003e\n                          Specify the window's title\n  -h, --help              Show help information.\n```\n\n#### Step 4: Sample Apps\n\nSwiftSDL includes several samples to help you get started.\n\n##### Test Bench\n\nThese are reimplementations of a variety of [SDL3's tests](https://github.com/libsdl-org/SDL/tree/main/test) using SwiftSDL:\n\n| Build Command | Image Preview |\n|-|-|\n| `swift run sdl test audio-info` | \u003cimg width=\"240\" alt=\"test-controller\" src=\"https://github.com/user-attachments/assets/cd9574ca-92a2-4a4c-8bad-eeee9593bbb6\"/\u003e |\n| `swift run sdl test controller` | \u003cimg width=\"480\" alt=\"test-controller\" src=\"https://github.com/user-attachments/assets/c67d6e8b-3a25-48d6-b195-b501ae536f4f\"/\u003e |\n| `swift run sdl test camera`     | \u003cimg width=\"480\" alt=\"test-camera\" src=\"https://github.com/user-attachments/assets/e817a454-970b-4b63-ba74-3541b951f532\"/\u003e |\n| `swift run sdl test geometry`   | \u003cimg width=\"480\" alt=\"test-geometry\" src=\"https://github.com/user-attachments/assets/13a9af58-6668-48a0-9cca-70b76472a569\"/\u003e |\n| `swift run sdl test mouse-grid` | \u003cimg width=\"480\" alt=\"mouse-grid\" src=\"https://github.com/user-attachments/assets/28902a4c-6fb1-4c08-aa9c-d1047831fb41\"/\u003e |\n| `swift run sdl test sprite`     | \u003cimg width=\"480\" alt=\"test-sprite\" src=\"https://github.com/user-attachments/assets/9e1b8c5e-d4bd-471c-9d61-a3337442981f\"/\u003e |\n| `swift run sdl test gpu-examples` | \u003cimg width=\"480\" alt=\"test-sprite\" src=\"https://github.com/user-attachments/assets/082778b6-3f9e-4612-b187-930af3e7d74f\"/\u003e |\n\n##### Games\n\n| Build Command | Image Preview |\n|-|-|\n| `swift run sdl games flappy-bird` | \u003cimg width=\"480\" alt=\"game-flappy-bird\" src=\"https://github.com/user-attachments/assets/2817f22c-8557-4871-bfb8-b2bf496ffb77\"\u003e |\n| `swift run sdl games stinky-duck` | \u003cimg width=\"480\" alt=\"game-flappy-bird\" src=\"https://github.com/user-attachments/assets/afad73dd-bbd7-48f4-b6fd-144d61172968\"\u003e |\n\n##### Xcode Project: macOS, iOS, tvOS\n\nExplore: [Samples/SwiftSDL-Xcode](https://github.com/KevinVitale/SwiftSDL/tree/main/Samples/SwiftSDL-Xcode)\n\n## 💻 Platform-Specific Instructions\n\nSwiftSDL doesn't work without SDL3. Refer to the following sections to ensure SwiftSDL compiles properly.\n\n### Apple\n\nSwiftSDL works on **macOS**, **iOS**, and **tvOS** simply by adding it to your project's `Package.swift` file. A precompiled XCFramework containing the SDL3 library is provided. \n\n##### Building the XCFramework with the Makefile\n\n**You do not need to** build the XCFramework yourself. However, if you need to, the available [`Makefile`](https://github.com/KevinVitale/SwiftSDL/blob/main/Makefile) can be used:\n\n```bash\n# Clone KevinVitale/SwiftSDL\ngit clone https://github.com/KevinVitale/SwiftSDL\ncd SwiftSDL\n\n# Build XCFramework...grab some ☕️\nmake build-sdl-xcframework\n```\n![]()\n\u003cimg src=\"https://github.com/KevinVitale/SwiftSDLTest/blob/main/Resources/GitHub/osx-example.png\" width=\"320\" alt=\"macOS-example\" /\u003e \n\u003cimg src=\"https://github.com/KevinVitale/SwiftSDL/blob/main/Samples/SwiftSDL-Xcode/ios-example.gif\" width=\"320\" alt=\"iOS-example\" /\u003e\n\n### Linux\n\nYou must build and install SDL3 from source. Thankfully, it's easy and should take only a few minutes:\n\n 1. [Install whichever dependencies your need](https://wiki.libsdl.org/SDL3/README/linux) for your game; and,\n 2. [Build and install from source](https://wiki.libsdl.org/SDL3/Installation#linuxunix).\n\n\u003cimg src=\"https://github.com/KevinVitale/SwiftSDLTest/blob/main/Resources/GitHub/linux-example.png\" height=\"480\" max-width=\"50%\" alt=\"linux-example\" /\u003e\n\n### Windows\n\nSupport for Windows is currently unavailable.\n\n## 🎨 Authors\n\n - [Kevin Vitale](https://github.com/KevinVitale)\n\n## 📁 License\n\nSwiftSDL is open-sourced under the MIT license. See the `LICENSE` file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKevinVitale%2FSwiftSDL","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKevinVitale%2FSwiftSDL","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKevinVitale%2FSwiftSDL/lists"}