{"id":13995086,"url":"https://github.com/joshdholtz/DeckUI","last_synced_at":"2025-07-22T21:32:01.169Z","repository":{"id":58887922,"uuid":"530736052","full_name":"joshdholtz/DeckUI","owner":"joshdholtz","description":"Swift DSL for writing slide decks in Xcode","archived":false,"fork":false,"pushed_at":"2023-08-20T15:02:39.000Z","size":1193,"stargazers_count":605,"open_issues_count":16,"forks_count":27,"subscribers_count":10,"default_branch":"main","last_synced_at":"2024-10-11T10:32:26.198Z","etag":null,"topics":["slides","swift","swiftui","xcode"],"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/joshdholtz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":["joshdholtz"]}},"created_at":"2022-08-30T16:18:02.000Z","updated_at":"2024-10-04T02:16:45.000Z","dependencies_parsed_at":"2024-10-25T17:17:50.301Z","dependency_job_id":"5804d123-4e32-4d12-b6ee-25847e62b642","html_url":"https://github.com/joshdholtz/DeckUI","commit_stats":{"total_commits":40,"total_committers":6,"mean_commits":6.666666666666667,"dds":"0.44999999999999996","last_synced_commit":"d7a3c319e1650197463dccfa0e98bb70ab4a6800"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshdholtz%2FDeckUI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshdholtz%2FDeckUI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshdholtz%2FDeckUI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshdholtz%2FDeckUI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joshdholtz","download_url":"https://codeload.github.com/joshdholtz/DeckUI/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227177756,"owners_count":17743158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["slides","swift","swiftui","xcode"],"created_at":"2024-08-09T14:03:14.693Z","updated_at":"2024-11-29T17:30:56.637Z","avatar_url":"https://github.com/joshdholtz.png","language":"Swift","funding_links":["https://github.com/sponsors/joshdholtz"],"categories":["Swift"],"sub_categories":[],"readme":"# ✨ DeckUI\n\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fjoshdholtz%2FDeckUI%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/joshdholtz/DeckUI)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fjoshdholtz%2FDeckUI%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/joshdholtz/DeckUI)\n![](https://img.shields.io/github/license/joshdholtz/DeckUI)\n[![](https://img.shields.io/badge/SPM-supported-DE5C43.svg?style=flat)](https://swift.org/package-manager/)\n[![](https://img.shields.io/badge/twitter-@joshdholtz-blue.svg?style=flat)]([https://twitter.com/joshdholtz](https://twitter.com/joshdholtz))\n\nDeckUI is a Swift DSL (domain specific language) for writing slide decks in Xcode. It allows for quick creation of  slides and content in a language and environment you are familiar with.\n\nBut _why_?\n\nWell, I made this because:\n- I was bored on an airplane\n- Wanted to use this as a demo for future conference talk on Swift DSLs\n- Need something more customizable than markdown for writing slide decks and more codey than Keynote\n\n👉 Watch [Introducing DeckUI - Write slide decks in Swift](https://www.youtube.com/watch?v=FraeH6OeJPY) on my YouTube channel for more explaination and full demo\n\n## ✨ Features\n\n- [x] Create slide decks in pure Swift code\n- [x] Decks are presented in SwiftUI with `Presenter`\n- [x] Build decks without knowing any SwiftUI\n  - With `Deck`, `Slide`, `Title`, `Words`, `Bullets`, `Media`, `Columns`\n- [x] Use `RawView` to drop any SwiftUI view\n  - Fully interactable and great for demos\n- [x] Display code with `Code`\n  - Use up and down arrows to highlight lines of code as your talking about them\n- [x] Support videos on `Media`\n\n### 🐌 Future Features\n\n- [ ] Support iOS and maybe tvOS\n- [ ] Fix bug with `Media` remote image loading and slide transitions\n- [ ] Animations within a slide\n- [ ] More customization on `Words`\n- [ ] Nesting of `Bullets`\n- [ ] Syntax highlighting for `Code`\n- [ ] Documentation\n- [ ] More examples\n\n## Simple Demo\n\n```swift\nimport SwiftUI\nimport DeckUI\n\nstruct ContentView: View {\n    var body: some View {\n        Presenter(deck: self.deck)\n    }\n}\n\nextension ContentView {\n    var deck: Deck {\n        Deck(title: \"SomeConf 2023\") {\n            Slide(alignment: .center) {\n                Title(\"Welcome to DeckUI\")\n            }\n\n            Slide {\n                Title(\"Quick Demo\")\n                Columns {\n                    Column {\n                        Bullets {\n                            Words(\"Bullets\")\n                            Words(\"Words\")\n                            Words(\"Images\")\n                            Words(\"Columns\")\n                        }\n                    }\n\n                    Column {\n                        Media(.remoteImage(URL(string: \"https://www.fillmurray.com/g/200/300\")!))\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\nhttps://user-images.githubusercontent.com/401294/189043329-fe75161c-17c1-4471-8632-07fb79d26d1a.mov\n\n## 💻 Installing\n\n### Swift Package Manager\n\n- File \u003e Swift Packages \u003e Add Package Dependency\n- Add `https://github.com/joshdholtz/DeckUI.git`\n- Select \"Up to Next Major\" with \"1.0.0\"\n\n## 🚀 Getting Started\n\nThere are no official \"Getting Started\" docs yet 😅 But look at...\n\n- [Demo app](https://github.com/joshdholtz/DeckUI/blob/main/Examples/Demo/Shared/ContentView.swift) for usage\n- [Sources/DeckUI/DSL](https://github.com/joshdholtz/DeckUI/tree/main/Sources/DeckUI/DSL) for how the `Deck`, `Slide`, and all slide components are built\n- [Sources/DeckUI/Views](https://github.com/joshdholtz/DeckUI/tree/main/Sources/DeckUI/Views) for how `Presenter` is built\n\n## 📖 Documentation\n\n100% not documented yet but I'll get there 🤷‍♂️\n\n## 🏎 Performance\n\nProbably bad and never production ready 😈 Please only use DeckUI for a single presentation and never at any scale.\n\n## 👨‍💻 Contributing\n\nYes please! I'm happy to discuss issues and review/merge pull requests 🙂 I will do my best to get to the but I am a dad, work at [RevenueCat](https://www.revenuecat.com/), and the lead maintainer of [fastlane](https://github.com/fastlane/fastlane) so I might not respond right away.\n\n## 📚 Examples\n\n### Slide\n\n`Slide` can be used without any parameters but can be given a custom `alignment`, `padding`, and `theme`.\n\n```swift\nSlide {\n    // Content\n}\n```\n\n```swift\nSlide(alignment: .center, padding: 80, theme: .white) {\n    // Content\n}\n```\n\n### Title\n\n`Title` can be used by itself or with an optional `subtitle`. It was real similar to `Words` but larger.\n\n```swift\nSlide(alignment: .center) {\n    Title(\"Introducing...\")\n}\n```\n\n```swift\nSlide {\n    Title(\"Introduction\", subtitle: \"What is it?\")\n    // Content\n}\n```\n\n### Words\n\n`Words` are similar to what a textbox would be in Keynote, PowerPoint, or Google Slides. There will eventually be more style configurations for words.\n\n```swift\nSlide(alignment: .center) {\n    Title(\"Center alignment\")\n    Words(\"Slides can be center aligned\")\n    Words(\"And more words\")\n}\n```\n\n### Bullets\n\n`Bullets` turns `Words` into a list. It takes an optional `style` parameter where you can choose between `.bullets` and `.dash`. `Bullets` cannot be nested yet but soon™️.\n\n```swift\nSlide {\n    Title(\"Introduction\", subtitle: \"What is it?\")\n    Bullets {\n        Words(\"A custom Swift DSL to make slide decks\")\n        Words(\"Distributed as a Swift Package\")\n        Words(\"Develop your slide deck in Xcode with Swift\")\n    }\n}\n```\n\n```swift\nSlide {\n    Title(\"Introduction\", subtitle: \"What is it?\")\n    Bullets(style: .dash) {\n        Words(\"A custom Swift DSL to make slide decks\")\n        Words(\"Distributed as a Swift Package\")\n        Words(\"Develop your slide deck in Xcode with Swift\")\n    }\n}\n```\n\n### Media\n\n`Media` provides a few ways to display images from various source types. This will eventually support videos.\n\n```swift\nSlide {\n    Media(.assetImage(\"some-asset-name\"))\n    Media(.bundleImage(\"some-file-name.jpg\"))\n    Media(.remoteImage(URL(string: \"http://placekitten.com/g/200/300\"))!)\n}\n```\n\n### Columns\n\n`Columns` allow you to use one to infinte `Column`s. Put other slide content in `Column`.\n\n```swift\nSlide {\n    Title(\"Columns\")\n    Columns {\n        Column {\n            // Content\n        }\n\n        Column {\n            // Content\n        }\n    }\n}\n```\n\n```swift\nSlide {\n    Title(\"Columns\")\n    Columns {\n        Column {\n            // Content\n        }\n\n        Column {\n            // Content\n        }\n\n        Column {\n            // Content\n        }\n\n        Column {\n            // Content\n        }\n    }\n}\n```\n\n### Code\n\n`Code` is a super specifi version `Words`. It will:\n- Display text as monospace\n- Scroll vertical if bigger than screen\n- Highlight lines of code when up and down arrows are pressed\n\n```swift\nSlide {\n    Code(\"\"\"\n    struct ContentView: View {\n        var body: some View {\n            Text(\"Hello slides\")\n        }\n    }\n    \"\"\")\n}\n```\n\n```swift\nSlide {\n    Code(\"\"\"\n    struct ContentView: View {\n        var body: some View {\n            Text(\"Hello slides\")\n        }\n    }\n    \"\"\", , enableHighlight: false)\n}\n```\n\n### RawView\n\nDrop any SwiftUI view inside of `RawView`. Could be built-in SwiftUI views like `Text` or `Button` but can also be any custom SwiftUI view.\n\n```swift\nSlide {\n    RawView {\n        CounterView()\n    }\n}\n\nstruct CounterView: View {\n    @State var count = 0\n\n    var body: some View {\n        Button {\n            self.count += 1\n        } label: {\n            Text(\"Press me - \\(self.count)\")\n                .font(.system(size: 60))\n                .padding(.horizontal, 40)\n                .padding(.vertical, 20)\n                .foregroundColor(.white)\n                .overlay(\n                    RoundedRectangle(cornerRadius: 25)\n                    .stroke(Color.white, lineWidth: 2)\n                )\n        }.buttonStyle(.plain)\n    }\n}\n```\n\n### Themes\n\nA `Theme` can be set in `Presenter` or individually on `Slide`. There are three default themes (`.dark`, `.black`, `.white`) but feel free to use your own.\n\n```swift\nstruct ContentView: View {\n    var body: some View {\n        Presenter(deck: self.deck, showCamera: true)\n    }\n}\n\nextension Theme {\n    public static let venonat: Theme = Theme(\n        background: Color(hex: \"#624a7b\"),\n        title: Foreground(\n            color: Color(hex: \"#ff5a5a\"),\n            font: Font.system(size: 80,\n                              weight: .bold,\n                              design: .default)\n        ),\n        subtitle: Foreground(\n            color: Color(hex: \"#a48bbd\"),\n            font: Font.system(size: 50,\n                              weight: .light,\n                              design: .default).italic()\n        ),\n        body: Foreground(\n            color: Color(hex: \"#FFFFFF\"),\n            font: Font.system(size: 50,\n                              weight: .regular,\n                              design: .default)\n        ),\n        code: Foreground(\n            color: Color(hex: \"#FFFFFF\"),\n            font: Font.system(size: 26,\n                              weight: .regular,\n                              design: .monospaced)\n        ),\n        codeHighlighted: (Color(hex: \"#312952\"), Foreground(\n            color: Color(hex: \"#FFFFFF\"),\n            font: Font.system(size: 26,\n                              weight: .heavy,\n                              design: .monospaced)\n        ))\n    )\n}\n```\n\n## DeckUI in the real world\n\n1. [FullQueueDeveloper](https://github.com/FullQueueDeveloper) presents \"Pushing to the App Store using Swift\" with [Swish](https://github.com/FullQueueDeveloper/Swish) \u0026 [Sh](https://github.com/FullQueueDeveloper/Sh) at GDG Omaha! [Watch the YouTube recording](https://www.youtube.com/watch?v=SxozYjWMhgU) of the presentation, and [checkout the source code on GitHub](https://github.com/FullQueueDeveloper/Deck-2022-09-13).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshdholtz%2FDeckUI","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoshdholtz%2FDeckUI","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshdholtz%2FDeckUI/lists"}