Prefire
π₯ A library based on Xcode Preview, for easy generation: Playbook view, Snapshot and Accessibility tests. SwiftUI and UIKit supported!
Install / Use
/learn @BarredEwe/PrefireREADME

π₯ What is Prefire?
Prefire transforms your #Preview blocks into:
- β Snapshot tests
- β Playbook views
- β Visual flows with states and user stories
- β Living documentation β fully automated
π Key Features
<img src="https://i.ibb.co/LNYBfMw/ezgif-com-gif-maker-2.gif" alt="Playbook" width="200" align="right">- π§ Smart Preview Parsing β including
#Preview,@Previewable - πΈ Snapshot Testing β automatic test generation from previews
- π Playbook View β auto-generated interactive component catalog
- π Flow-aware β build user stories from multiple preview steps
- π§© UIKit Support β support for
UIViewandUIViewController - βοΈ SPM + Xcode Plugins β works in CLI, Xcode build phases, or CI
- π§ Fast Caching β fingerprint-based AST and body caching avoids redundant work
- βοΈ Stencil Templates β customize output with your own templates
Why Prefire?
- π₯ Save Time - Generate tests and documentation automatically
- π₯ Stay Consistent - Keep previews and tests always in sync
- π₯ Improve Quality - Catch visual regressions before users do
- π₯ Boost Collaboration - Share living documentation with your team
β‘οΈ Quick Start
π¦ Example project available at: Prefire Example
1. Add Prefire to Your Project
// Package.swift
dependencies: [
.package(url: "https://github.com/BarredEwe/Prefire.git", from: "5.4.0")
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.18.0"),
],
.testTarget(
dependencies: [
.product(name: "Prefire", package: "Prefire"),
.product(name: "SnapshotTesting", package: "swift-snapshot-testing"),
],
plugins: [
.plugin(name: "PrefireTestsPlugin", package: "Prefire")
]
)
2. Write #Preview
#Preview {
Button("Submit")
}
3. Run tests
Just run the test target π β Prefire will auto-generate snapshots based on your previews.
<img src="https://i.postimg.cc/XNPVPL1G/Untitled-2.gif" width="300">π‘ If your test target is empty, Prefire will still generate files and snapshot code during build.
π¦ Installation
Supports:
- β
SPM Plugin (
Package.swift) - β Xcode Build Tool Plugin
- β
CLI (
brew install prefire) - β GitHub Actions / CI
See detailed setup in the Installation guide
π§ How It Works
π 1. Parses all source files
- Finds all
#PreviewandPreviewProviderblocks - Supports modifiers:
.prefireEnabled(),.prefireIgnored()
π 2. Caches Types and PreviewBodies
- Based on file modification date + SHA-256 of inputs
- Avoids re-parsing if nothing changed
π’ 3. Generates Snapshot Tests
- Uses
Stenciltemplates - Respects
.prefire.ymlconfiguration
π 4. Generates Playbook View
- Groups by
UserStory,State - Outputs
PreviewModels.generated.swift
π Advanced Usage
To generate tests and playbook, simply mark your preview using the PrefireProvider protocol:
struct Text_Previews: PreviewProvider, PrefireProvider {
static var previews: some View { ... }
}
If you use the #Preview macro, π₯Prefire will automatically find it!
If you don't need it, mark view - .prefireIgnored():
#Preview {
Text("")
.prefireIgnored()
}
If you want to disable the automatic get of all previews, use the setting preview_default_enabled: false. Then to include preview in the test, you need to call the .prefireEnabled():
#Preview {
Text("")
.prefireEnabled()
}
Playbook (Demo) View
To use Playbook, simply use PlaybookView
- If you want to see a list of all the Views, use
isComponent: true - If you want to sort by UserStory, use
isComponent: false
import Prefire
struct ContentView: View {
var body: some View {
PlaybookView(isComponent: true, previewModels: PreviewModels.models)
}
}
Snapshot tests
Just run generated tests π All tests will be generated in the DerivedData folder.
<img src="https://i.postimg.cc/XNPVPL1G/Untitled-2.gif" width="300">Plugin PrefireTestsPlugin will handle everything for you π οΈ
For detailed instruction, check out swift-snapshot-testing or examine an example project.
API
Prefire provide new commands for previews:
-
You can set the delay, precision and perceptualPrecision parameters for the snapshot:
.snapshot(delay: 0.3, precision: 0.95, perceptualPrecision: 0.98)static var previews: some View { TestView() .snapshot(delay: 0.3, precision: 0.95, perceptualPrecision: 0.98) } -
Function for connecting preview together in one Flow:
<img src="https://i.postimg.cc/jSh23G8W/temp-Image9a-EDKU.avif" width="350" align="right">.previewUserStory(.auth)static var previews: some View { PrefireView() .previewUserStory(.auth) } static var previews: some View { AuthView() .previewUserStory(.auth) }For example Authorization flow:
<br clear="all">LoginView,OTPViewandPincodeView -
If a preview contains more than one
<img src="https://i.postimg.cc/Z5JKNwTJ/temp-Imageh19pin.avif" width="350" align="right">View, you can markStatefor these views..previewState(.loading)
<br clear="all">static var previews: some View { TestView("Default") TestView("Loading") .previewState(.loading) }
π§° API Summary
| Feature | Modifier |
|--------|----------|
| Include in snapshot | .prefireEnabled() |
| Exclude from snapshot | .prefireIgnored() |
| Group in a flow | .previewUserStory(.auth) |
| Mark a UI state | .previewState(.error) |
| Customize snapshot | .snapshot(delay: 0.3, precision: 0.95) |
π‘ Advanced: CLI Usage
# Generate snapshot tests
prefire tests
# Generate playbook models
prefire playbook
Run prefire tests --help or prefire playbook --help for more options.
π Configuration: .prefire.yml
See detailed configuration in the Configuration guide
test_configuration:
target: MyApp
playbook_configuration:
preview_default_enabled: true
Distribution
When preparing for distribution, you may want to exclude your PreviewProvider and mock data from release builds. This can be achieved by wrapping them in #if DEBUG compiler directives. Alternatively, you can pass a compiler flag to exclude PreviewModels from release builds.
To exclude PreviewModels using Swift Package Manager, pass the PLAYBOOK_DISABLED swift setting in the package that links PrefirePlaybookPlugin:
swiftSettings: [
.define("PLAYBOOK_DISABLED", .when(configuration: .release)),
]
If you are using Xcode, you can pass the compiler flag in the Xcode build settings:
SWIFT_ACTIVE_COMPILATION_CONDITIONS = PLAYBOOK_DISABLED;
π§ Internal Architecture
PrefireCoreβ AST + preview parsing, caching, logicPrefireGeneratorβ handles stencil templating + snapshot generationPrefireCacheManagerβ unifies caching forTypesandPreviewsPrefireTestsPlugin/PrefirePlaybookPluginβ SPM/Xcode integrationsprefireβ CLI entry point, calls shared generator code
Requirements
- Swift 5.6 or higher
- Xcode 14.0 or higher
- iOS 14 or higher
Troubleshooting
NavigationView in Preview not supported for Playbook
- Consider using other views or layouts for your Playbook needs.
Running Prefire via CI
- To run Prefire via Continuous Integration (CI), you need to configure permissions:
defaults write com.apple.dt.Xcode IDESkipPackagePluginFingerprintValidatation -bool YES
Xcode is unable to generate tests in a custom path.
- To resolve this, youβll need to disable the sandbox for file generation by running the following command in your terminal:
defaults write com.apple.dt.Xcode IDEPackageSupportDisablePluginExecutionSandbox -bool YES
π€ Contributing
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch
- Submit a Pull Request
π License
Prefire is released under the Apache License 2.0. See LICENSE for details.
Related Skills
gh-issues
343.3kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
node-connect
343.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
92.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Writing Hookify Rules
92.1kThis skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
