Build web UIs with the same declarative, component-based approach as SwiftUI
Swiftlets brings the elegance of SwiftUI to web development. Define reusable components with the HTMLComponent protocol, compose them together, and build complex UIs from simple parts.
Build complex UIs from simple, reusable components
Catch errors at compile time, not runtime
If you know SwiftUI, you already know Swiftlets
Define components using the HTMLComponent protocol:
struct Greeting: HTMLComponent {
let name: String
var body: some HTMLElement {
VStack(spacing: 10) {
H2("Hello, \(name)!")
.style("color", "#007bff")
P("Welcome to Swiftlets")
.style("font-size", "1.1rem")
}
.style("text-align", "center")
.style("padding", "2rem")
.style("background", "#f8f9fa")
.style("border-radius", "0.5rem")
}
}
// Use it anywhere:
Greeting(name: "Developer").body
Welcome to Swiftlets
Here's a complete example showing a product grid with reusable components:
struct ProductGrid: HTMLComponent {
struct Product {
let name: String
let price: Double
let imageURL: String
}
let products: [Product]
var body: some HTMLElement {
VStack(spacing: 30) {
H2("Featured Products")
If(products.isEmpty) {
P("No products available")
.style("text-align", "center")
.style("color", "#6c757d")
} else: {
Grid(columns: .count(3), spacing: 20) {
ForEach(products) { product in
ProductCard(
name: product.name,
price: product.price,
imageURL: product.imageURL
).body
}
}
}
}
}
}
The syntax is intentionally similar to SwiftUI, making it easy to transition:
struct ContentView: View {
var body: some View {
VStack(spacing: 20) {
Text("Hello, SwiftUI!")
.font(.title)
.foregroundColor(.blue)
Button("Click Me") {
print("Clicked!")
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
}
}
struct ContentView: HTMLComponent {
var body: some HTMLElement {
VStack(spacing: 20) {
H1("Hello, Swiftlets!")
.style("color", "blue")
Button("Click Me")
.style("padding", "10px 20px")
.style("background", "blue")
.style("color", "white")
.style("border-radius", "8px")
.style("border", "none")
}
}
}
// Conditional rendering
If(isLoggedIn) {
UserDashboard(user: currentUser).body
} else: {
LoginForm().body
}
// Loops with ForEach
ForEach(items) { item in
ItemRow(item: item).body
}
struct Page: HTMLComponent {
var body: some HTMLElement {
VStack {
Header().body
MainContent().body
Footer().body
}
}
}