Swift Pieces is a library of designed SwiftUI interactions: swipe decks, glass menus, floating docks, scrubbable charts. Not primitives, and not a dependency. Each piece is a single .swift file with a #Preview, built on Apple frameworks only, that you copy into your project and own outright. Motion, haptics and states are already done.
Add any piece with the CLI:
npx swiftpieces add AssistantOrbSeveral at once:
npx swiftpieces add AssistantOrb SwipeDeck GlassActionMenuOr open the file on swiftpieces.com/components and copy it. There is nothing to install and no package to track.
67 pieces across 14 categories: text, backgrounds, Liquid Glass, buttons and controls, inputs and forms, cards, lists, navigation, sheets, feedback, motion, data and charts, AI and media.
Guides: SwiftUI animations · SwiftUI buttons · SwiftUI cards · SwiftUI haptics · Loading states · Liquid Glass
- iOS 17 baseline. Liquid Glass effects are gated behind
#available(iOS 26, *)with a Material fallback, so a piece never fails to build on an older SDK. - Apple frameworks only. No third-party dependencies, ever. A
.metalsibling ships alongside the.swiftfile where a shader is involved. - Accessible by default. Reduce Motion and Reduce Transparency are respected, colors are semantic, and Dynamic Type works.
- Documented parameters. Every init parameter carries a doc comment, which becomes the parameters table on the site.
- Type-checked in CI. Every piece is compiled against the iOS simulator SDK on every change, so an API that does not exist cannot land.
Swift Pieces is maintained by one developer and funded by its sponsors. Sponsorship pays for new free pieces, fixes for every iOS release, and the docs, CLI and MCP server.
Become a sponsor from $5 a month. Company tiers put your logo on swiftpieces.com, the docs and this README.
The free library is the pieces. Pro is the layer above them: production-ready screens, complete app templates, and the Build Kit, a set of agent skills that build the rest of your app in the same design language. One purchase, lifetime access.
Pro is closed source and lives in a private repository. This repo holds the free library and the site, and it stays that way.
git clone https://github.com/Saivion/SwiftPieces.git
cd SwiftPieces
npm install
npm run brand:build # @swiftpieces/brand -> dist (first run only)
npm run registry:build # .swift -> registry JSON, docs pages, llms.txt
npm run devUse Node 22.22 or newer: .nvmrc pins Node 22, the line CI and Cloudflare's builds use. Pieces live in registry/swift/<category>/; after changing one, or registry.json, rerun npm run registry:build to regenerate the registry output.
| Path | Purpose |
|---|---|
registry/swift/<category>/ |
Source of truth. One .swift per piece with a // swiftpieces: header; .metal siblings for shaders. |
registry/__registry__/ |
Generated registry JSON. Do not hand-edit. |
content/docs/ |
Fumadocs content. Per-piece pages are generated. |
app/ |
Next.js App Router: marketing, docs, /api/registry/[name], /api/mcp, search. |
components/previews/ |
Web recreations of the pieces, used for live previews. |
packages/cli/ |
swiftpieces on npm: init, add, list, login, whoami. |
packages/brand/ |
@swiftpieces/brand on npm: tokens, Tailwind theme, shared primitives. |
previews/ |
Xcode preview harness and recorder. |
scripts/ |
Registry build, Swift type-check, preview recorder, bundle gate, public-safety audit. |
Useful checks, all of which CI runs too:
npm run typecheck # TypeScript
npm run swift:typecheck # every piece against the iOS simulator SDK
npm run bundle:check # the Worker must stay under 8 MB compressed
npm run audit:public # nothing Pro-shaped, nothing secretDeployment and analytics (maintainers)
swiftpieces.com deploys from GitHub with Cloudflare Workers Builds. Nothing is deployed from a laptop.
| Branch | What happens |
|---|---|
main |
Builds and deploys to production (swiftpieces.com). |
| any other branch / PR | Builds a preview version with its own URL. Production is untouched. |
GitHub Actions is here for safety only, because this repo is public and takes contributions. ci.yml checks every push and PR for leaked secrets, Pro-only code, a stale registry, type errors and bundle size. swift.yml type-checks every piece against the iOS SDK, and runs only when Swift, Metal or the preview app changes. Actions never deploys and holds no Cloudflare credentials; Cloudflare does the deploying.
Workers Builds settings (Cloudflare dashboard → Workers → swiftpieces → Settings → Build):
| Setting | Value |
|---|---|
| Git repository | this repo, production branch main |
| Build command | npm run cf:build |
| Deploy command | npx opennextjs-cloudflare deploy |
| Non-production branch deploy command | npx opennextjs-cloudflare upload |
| Builds for non-production branches | on |
| Build variables | NODE_VERSION = 22, NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN and NEXT_PUBLIC_POSTHOG_HOST (optional) |
Build variables are read while building, not by the running Worker. PostHog only starts on swiftpieces.com itself, so preview URLs and local builds never count toward the numbers.
Analytics (swiftpieces.com only). The official deploy measures page views, visits and Playground usage with PostHog, and shows the all-time page views in the hero ("Explored N times"). PostHog never starts anywhere else, so forks, previews and local builds send nothing, and there is nothing to configure to run this project.
| Variable | Where | What |
|---|---|---|
NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN |
Build variable, .env.local |
The project token (phc_…). Public by design; inlined at build. |
NEXT_PUBLIC_POSTHOG_HOST |
Build variable, .env.local |
https://us.i.posthog.com, or the EU host. |
POSTHOG_PERSONAL_API_KEY |
Worker secret | A personal API key with Query: Read, for the hero's count. A real credential: never commit it. |
POSTHOG_PROJECT_ID |
Worker secret | The project's number (PostHog → Settings → Project). |
Set the two secrets with npx wrangler secret put <NAME>. The site sets no cookies, so the PostHog project needs Cookieless tracking switched on in its settings; without it, PostHog ignores the site's events. Those events carry no country: PostHog hashes the IP address before GeoIP runs.
The count is Cloudflare Web Analytics' last total, from before the switch, plus PostHog's page views on swiftpieces.com since. It is read at most every two minutes and kept in KV, so polling never reaches PostHog.
If the number stays still. Every failure logs itself, and observability is on, so one command tells you which it is:
npx wrangler tail swiftpieces --format pretty | grep "\[views\]"| Line | Meaning |
|---|---|
not configured: … |
A secret or the host variable is not reaching the Worker. Until then the hero shows the last total and holds still. |
posthog 401 … or posthog 403 … |
The personal API key is wrong, or lacks Query: Read. |
posthog 404 … |
POSTHOG_PROJECT_ID is not the key's project. |
posthog failed: … |
PostHog did not answer in time. The next read retries. |
New pieces, fixes, docs and previews are all welcome. CONTRIBUTING.md is the full walkthrough, from a .swift file to a working npx swiftpieces add command.
By taking part you agree to the Code of Conduct. Found a security issue? SECURITY.md says how to report it privately.
MIT + Commons Clause License Condition v1.0.
- You can use, copy, modify and ship the pieces in any app, website or product, personal or commercial, including client work.
- You can't sell, sublicense or redistribute the pieces themselves, whether alone, in a bundle, or as a ported version.