KaxhyapUI is an open-source SwiftUI toolkit that fills gaps in SwiftUI by providing components, extensions, and utilities that complement the standard library and make development faster and more enjoyable.
Early versions focus on practical UI components and helpers. Future releases will also introduce Liquid Glass inspired UI built for Apple's evolving design direction.
Beta: KaxhyapUI is currently in beta. APIs are not frozen and may change before v1.0.0.
Features
SwiftUI components that streamline common UI needs
Reusable, modular view building blocks
Practical API utilities and extensions
Built using modern system APIs without legacy compatibility
Distributed via Swift Package Manager
Getting Started
Who is KaxhyapUI for?
KaxhyapUI is designed for developers who embrace modern SwiftUI development.
SwiftUI Developers
Building apps for iOS 17+ and macOS 15+
Productivity Seekers
Looking to streamline common UI patterns
Teams
Want clean, reusable UI components
Modern API Lovers
Prefer SwiftUI-only APIs
Note: KaxhyapUI may not be suitable if you need support for older OS versions (pre-iOS 17, pre-macOS 15) or UIKit-based components.
Getting Started
Design Philosophy
KaxhyapUI follows a set of core principles that guide every component we build.
1
Fill the Gaps
Focus on components and utilities that complement SwiftUI's standard library, addressing common needs that aren't covered out of the box.
2
Modern System APIs
Built using modern system APIs without legacy compatibility. No support for older OS versions as of now.
3
Minimal APIs
Public APIs are kept small, focused, and purposeful. Prefer composition over configuration.
4
SwiftUI Only
Public-facing APIs are pure SwiftUI. UIKit is used internally only when required by the system.
5
Quality Over Quantity
KaxhyapUI prioritizes fewer, well-designed components instead of a large collection of shallow ones. Avoid unnecessary abstractions.
Getting Started
Platform Support
KaxhyapUI is built for modern Apple platforms.
iOS 17+
Full support for iPhone and iPad
Supported
macOS 15+
Native Mac app support
Supported
Coming Soon: tvOS, visionOS, and watchOS support will be added in a future stable release.
No support for older OS versions as of now. This is intentional to ensure we can use the latest APIs without compromise.
Getting Started
Installation
KaxhyapUI is distributed using Swift Package Manager.
Adding the Package
Follow these steps to add KaxhyapUI to your Xcode project:
1
Open your Xcode project
2
Go to File → Add Package Dependency
3
Enter the repository URL:
Repository URL
https://github.com/sachinkaxhyap/KaxhyapUI
4
Choose the version rule "Up to Next Major" starting from version 0.1.0
Importing the Library
Once added, import KaxhyapUI in your SwiftUI files:
Swift
import KaxhyapUI
Getting Started
Library Status
Beta
KaxhyapUI is currently in active development
This means:
APIs are not frozen
Breaking changes may occur between releases
Feedback and suggestions are welcome
The library is actively developed
API stability will be introduced starting with version 1.0.0.
Components
Components Overview
KaxhyapUI is built as a collection of independent, reusable SwiftUI components.
Each component:
Solves a specific UI problemCan be used independentlyHas minimal setupFollows modern SwiftUI patterns
More components are planned for future releases. Check the Roadmap for upcoming additions.
Components
AsyncStateView
New in 0.2.0
A view that displays different content based on the current async state—handling loading, success, error, and empty states in a consistent way.
AsyncStateView eliminates boilerplate code when working with asynchronous data loading patterns, providing sensible defaults while remaining fully customizable.
Platform Requirements
iOS 17.0+macOS 14.0+tvOS 17.0+watchOS 10.0+
AsyncState Enum
The component is powered by the AsyncState enum which represents the state of an asynchronous operation:
Swift
publicenumAsyncState<T> {
case idle
case loading
case success(T)
case failure(Error)
case empty
}
idle
Initial state before any action
loading
Operation in progress
success(T)
Data loaded successfully
failure(Error)
Operation failed with error
empty
No data available
Helper Properties
The AsyncState enum provides convenient computed properties:
Swift
state.isLoading// Bool - true if loading
state.data// T? - the success value if present
state.error// Error? - the error if failed
Basic Usage
Create an AsyncStateView by providing a state and a content builder for the success case:
You can place WebViewK inside any SwiftUI layout such as a VStack, NavigationStack, or TabView.
Presentation Styles
WebViewK supports two presentation styles:
Embedded Web View
Renders the web content directly inside your SwiftUI view hierarchy. Useful when the web content is part of the app's flow.
WebViewK(url: url, style: .embedded)
Safari View
Presents content using the system Safari interface. Useful for external links, authentication pages, or content that should feel separate.
WebViewK(url: url, style: .safari)
Handling Invalid URLs
If WebViewK is created without a valid URL, it automatically shows a system "content unavailable" view. This prevents crashes and provides a clear user-facing message.
Best Practices
Always validate or safely unwrap URLs before passing them
Use Safari style for external or third-party content
Use embedded web view style for internal content
Avoid overloading the component with navigation or business logic
Limitations
WebViewK focuses on simplicity and common use cases. Advanced customization such as:
JavaScript message handling
Custom navigation controls
Deep web-to-native communication
These features may be added in future versions but are intentionally out of scope for the initial beta release.
Components
Toast
New in 0.4.0
A lightweight toast notification that slides in from the bottom of the screen, with support for clear and prominent visual styles, optional action buttons, and auto-dismiss.
Toast is applied as a SwiftUI view modifier using .toast(). It automatically adapts to the platform — using glass effects on iOS 26+ and material backgrounds on earlier versions.
Platform Requirements
iOS 17.0+macOS 14.0+
Preview
Clear
Clear + Action
Prominent
Prominent + Action
ToastStyle Enum
The visual appearance of the toast is controlled by the ToastStyle enum:
Swift
publicenumToastStyle {
case clear
case prominent(Color)
}
An SF Symbol name displayed alongside the message.
image
String
—
A custom asset image name (uses the asset image overload).
style
ToastStyle
.clear
The visual style — .clear or .prominent(Color).
duration
TimeInterval
2.0
Seconds before auto-dismiss. Set to 0 to disable.
actionTitle
String?
nil
Title for an optional action button in the toast.
action
(() -> Void)?
nil
Closure executed when the action button is tapped.
Platform Adaptation
Toast automatically adapts its rendering based on the OS version:
iOS 26+ / macOS 26+
Uses the new .glassEffect() API for a native Liquid Glass appearance. Action buttons use .buttonStyle(.glass).
iOS 17 & 18 / macOS 14 & 15
Falls back to .ultraThinMaterial for the clear style and solid color backgrounds for prominent. Action buttons use .buttonStyle(.bordered).
Best Practices
Keep toast messages short and informative
Use .prominent for important or success/error notifications
Provide an action button for reversible operations (e.g., Undo)
Use a meaningful SF Symbol to reinforce the message context
Avoid using toast for critical information that requires user acknowledgment — use an alert instead
Note: The toast uses a spring animation (duration: 0.4, bounce: 0.2) for its entrance and exit transitions. It slides in from the bottom combined with an opacity fade.
Extensions
Image Compressor
New in 0.3.0
Compress images to fit within a specified maximum file size using an intelligent binary search algorithm.
The Image Compressor extension provides a simple API to compress UIImage (iOS) and NSImage (macOS) instances to a target file size in kilobytes. It automatically handles quality adjustment and progressive resizing when needed.
Platform Requirements
iOS 17.0+macOS 15.0+
Common Use Cases
Upload size limits
Email attachments
Storage optimization
API payload limits
Basic Usage
Compress an image to fit within a maximum file size:
Swift — iOS
import KaxhyapUI
let originalImage: UIImage = // ... from camera, picker, etc.// Compress to maximum 500 KBif let compressedData = originalImage.compressedTo(maxSizeKB: 500) {
// Upload compressedData to server or save locally
}
Swift — macOS
import KaxhyapUI
let originalImage: NSImage = // ... from file, pasteboard, etc.// Compress to maximum 500 KBif let compressedData = originalImage.compressedTo(maxSizeKB: 500) {
// Upload compressedData to server or save locally
}
Async Usage
For large images, use the async version to avoid blocking the main thread:
Swift
// Compress asynchronouslylet compressedData = await originalImage.compressedTo(maxSizeKB: 500)
// Or use in a TaskTask {
if let data = await image.compressedTo(maxSizeKB: 200) {
await uploadImage(data)
}
}
The async version runs the compression on a background thread with .userInitiated priority, keeping your UI responsive.
How It Works
The compressor uses a multi-step approach to achieve the target file size:
1
Dimension Check
First, the image is constrained to a maximum dimension of 4096 pixels to prevent memory issues with very large images.
2
Quality Optimization
A binary search algorithm finds the optimal JPEG compression quality (between 0.1 and 0.95) that produces an image close to but not exceeding the target size.
3
Progressive Resizing
If compression alone can't reach the target, the image is progressively resized until it fits within the size limit.
Complete Example
Here's a full example showing image compression in a photo upload flow:
Swift
import SwiftUI
import PhotosUI
import KaxhyapUI
structPhotoUploadView: View {
@Stateprivate var selectedItem: PhotosPickerItem?
@Stateprivate var isCompressing = false@Stateprivate var uploadStatus: String?
var body: someView {
VStack(spacing: 20) {
PhotosPicker(selection: $selectedItem, matching: .images) {
Label("Select Photo", systemImage: "photo")
}
if isCompressing {
ProgressView("Compressing...")
}
if let status = uploadStatus {
Text(status)
.foregroundStyle(.secondary)
}
}
.onChange(of: selectedItem) { _, newItem inTask {
await processImage(newItem)
}
}
}
private func processImage(_ item: PhotosPickerItem?) async {
guard let item,
let data = try? await item.loadTransferable(type: Data.self),
let image = UIImage(data: data) else {
return
}
isCompressing = true// Compress to max 500 KB for uploadif let compressedData = await image.compressedTo(maxSizeKB: 500) {
let originalKB = data.count / 1024let compressedKB = compressedData.count / 1024
uploadStatus = "Compressed: \(originalKB) KB → \(compressedKB) KB"// Upload compressedData...
} else {
uploadStatus = "Compression failed"
}
isCompressing = false
}
}
Parameters
Parameter
Type
Description
maxSizeKB
Int
Maximum file size in kilobytes. Must be greater than 0.
Return Value
Returns Data? containing the compressed JPEG image data, or nil if:
The maxSizeKB parameter is 0 or negative
The image cannot be converted to JPEG format
Compression fails for any other reason
Best Practices
Use the async version for images from camera or photo library
Show a progress indicator during compression
Handle the nil return case gracefully
Choose a reasonable target size (100-1000 KB for most use cases)
Avoid extremely small target sizes (under 50 KB) as quality may suffer significantly
Note: The output format is always JPEG. If you need PNG or other formats, additional processing may be required.
Resources
API Stability Policy
Before version 1.0.0
APIs may change
Renaming and refactoring may occur
New parameters or behaviors may be introduced
After version 1.0.0
Public APIs will remain stable
Breaking changes will follow semantic versioning
Deprecations will be communicated clearly
Resources
Roadmap
Planned future work for KaxhyapUI includes:
Liquid Glass components
Buttons, toolbars, and tab UI
Bottom sheet and reusable screen templates
Loading and skeleton state utilities
Async helpers
Text fields and form components
Navigation/layout helpers
Stability and API guarantees will come with v1.0.0. The roadmap may evolve based on platform changes and community feedback.
Resources
Contributing
We welcome discussions, issues, and contributions.
When contributing, please follow these guidelines:
Keep APIs small, focused, and purposeful
Focus on intentional, well-designed interfaces
Prefer composition over configuration
Build modular, composable components
Avoid unnecessary abstractions
Keep code simple and direct
Follow modern SwiftUI patterns
Use idiomatic SwiftUI and system conventions
Discussion, feedback, and suggestions are encouraged.
Resources
License
MIT License
KaxhyapUI is released under the MIT License.
This allows free use, modification, and distribution in both personal and commercial projects.
Resources
Support & Feedback
If you find KaxhyapUI useful, here's how you can help: