Skip to content

coenttb/swift-html

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

swift-html

Swift 6.0 Platforms License Release

Type-safe HTML and CSS generation in Swift
Build websites, email templates, and server-side rendered pages with the full power of Swift's type system

Overview

swift-html is your entry point into a comprehensive ecosystem for type-safe web development in Swift. It combines the power of strongly-typed HTML elements, compile-time validated CSS properties, and an efficient rendering engine to help you build web content with confidence.

import HTML

// Type-safe HTML with SwiftUI-like syntax
let page = HTMLDocument {
    div {
        h1 { "Welcome to swift-html" }
            .color(.systemBlue)
            .fontSize(.rem(2.5))
        
        p { "Build beautiful, type-safe web pages with Swift" }
            .color(light: .gray800, dark: .gray200)
            .lineHeight(1.6)
        
        a(href: "https://github.com/coenttb/swift-html") {
            "Get Started β†’"
        }
        .padding(.rem(1))
        .backgroundColor(.systemBlue)
        .color(.white)
        .borderRadius(.px(8))
        .textDecoration(.none)
    }
    .padding(.rem(2))
    .maxWidth(.px(800))
    .margin(.auto)
} head: {
    title { "swift-html - Type-safe HTML in Swift" }
    meta(charset: .utf8)
    meta(name: .viewport, content: "width=device-width, initial-scale=1")
}

// Render to string
let bytes: ContiguousArray<UInt8> = element.render() // highly optimized
let string: String = try String(page) // render HTML as String

Why swift-html?

πŸ›‘οΈ Type Safety First

  • Compile-time validation: Catch HTML and CSS errors before runtime
  • Impossible invalid states: Can't put a href on a div or use px for color
  • IDE support: Full autocomplete, inline documentation, and refactoring

🎨 Modern CSS Support

  • Type-safe properties: Every CSS property is strongly typed
  • Dark mode built-in: First-class support for light/dark color schemes
  • Responsive helpers: Media queries and container queries with type safety

⚑ Performance

  • Zero runtime overhead: All validation happens at compile time
  • Efficient rendering: Direct byte-level rendering for server applications
  • Minimal dependencies: Lightweight and focused

🧩 Composable Architecture

  • SwiftUI-like syntax: Familiar patterns for Swift developers
  • Reusable components: Build once, use everywhere
  • Modular design: Use only what you need

Quick Start

Installation

Add swift-html to your Swift package:

dependencies: [
    .package(url: "https://github.com/coenttb/swift-html", from: "0.0.1")
]

For Xcode projects, add the package URL: https://github.com/coenttb/swift-html

Your First Page

import HTML

struct WelcomePage: HTMLDocument {
    var head: some HTML {
        title { "Welcome" }
        meta(charset: .utf8)
    }
    
    var body: some HTML {
        h1 { "Hello, World!" }
            .textAlign(.center)
            .color(.systemBlue)
    }
}

// Render it
let page = WelcomePage().render()
let html = try String(page)

SwiftUI Preview Support

Preview your HTML in Xcode while developing:

#if canImport(SwiftUI)
import SwiftUI

#Preview {
    HTMLDocument {
        div {
            h1 { "Live Preview" }
                .color(.systemBlue)
            p { "Edit and see changes instantly!" }
        }
        .padding(.rem(2))
    }
}
#endif

Core Concepts

πŸ—οΈ HTML Elements

Every HTML element is a strongly-typed Swift type:

// Type-safe elements
h1 { "Title" }
p { "Paragraph" }
a(href: "/about") { "About" }
img(src: "/logo.png", alt: "Logo")

// Impossible to write invalid HTML
// div(href: "/") { } // ❌ Compile error: 'href' is not valid for div

🎨 CSS Styling

Apply styles with type-safe modifiers:

div { "Styled content" }
    .padding(.rem(2))                    // Type-safe units
    .backgroundColor(.systemBackground)   // Semantic colors
    .borderRadius(.px(8))                // Multiple unit types
    .boxShadow(                          // Complex properties
        x: .px(0),
        y: .px(2),
        blur: .px(4),
        color: .rgba(0, 0, 0, 0.1)
    )

πŸŒ“ Dark Mode Support

First-class support for color schemes:

p { "Adaptive text" }
    .color(light: .gray900, dark: .gray100)
    .backgroundColor(light: .white, dark: .gray900)

or use the convenient Color from swift-html:

extension Color {
    static let lightBackground: Self = .init(light: .white, dark: .gray900)
}

p { "Adaptive text" }
    .backgroundColor(.lightBackground)

♻️ Reusable Components

Build components that compose:

struct Button: HTML {
    let title: String
    let action: String
    
    var body: some HTML {
        a(href: action) { title }
            .display(.inlineBlock)
            .padding(.vertical(.rem(0.5)), .horizontal(.rem(1)))
            .backgroundColor(.systemBlue)
            .color(.white)
            .borderRadius(.px(6))
            .textDecoration(.none)
            .transition(.all, duration: .ms(150))
    }
}

// Use it anywhere
Button(title: "Learn More", action: "/docs")

Real-World Examples

πŸ“± Responsive Layout

div {
    header { "Mobile First" }
    nav { "Navigation" }
    main { "Content" }
}
.display(.grid)
.gridTemplateColumns(.fr(1))
.gap(.rem(1))

πŸ“§ Email Template

struct EmailTemplate: HTMLDocument {
    let userName: String
    
    var head: some HTML {
        title { "Welcome Email" }
        style {
            """
            body { font-family: system-ui; line-height: 1.6; }
            """
        }
    }
    
    var body: some HTML {
        div {
            h1 { "Welcome, \(userName)!" }
            p { "Thanks for joining us." }
            Button(title: "Get Started", action: "https://app.example.com")
        }
        .class("container")
    }
}

πŸš€ Server-Side Rendering

import Vapor

func routes(_ app: Application) throws {
    app.get { req async throws -> Response in
        let page = HomePage(user: req.user)
        let html = try String(page)
        
        return Response(
            status: .ok,
            headers: ["Content-Type": "text/html; charset=utf-8"],
            body: .init(string: html)
        )
    }
}

Architecture

swift-html integrates four specialized packages:

swift-html (You are here!)
    β”œβ”€β”€ swift-html-types      β†’ HTML element types & attributes
    β”œβ”€β”€ swift-css-types       β†’ CSS property types & values  
    β”œβ”€β”€ pointfree-html        β†’ Rendering engine
    └── swift-html-css-pointfree β†’ Integration layer

Each package has a focused responsibility while working seamlessly together.

Testing

swift-html includes powerful testing utilities:

import Testing
import PointFreeHTMLTestSupport

@Suite("Button Tests")
struct ButtonTests {
    @Test("Button renders correctly")
    func buttonRendering() {
        let button = Button(title: "Click Me", action: "/action")
        
        assertInlineSnapshot(of: button, as: .html) {
            """
            <a href="/action" style="display: inline-block; padding: 0.5rem 1rem; background-color: #007AFF; color: white; border-radius: 6px; text-decoration: none; transition: all 150ms">Click Me</a>
            """
        }
    }
}

Documentation

Comprehensive documentation is available:

Ecosystem

Core Stack

Extensions

Examples

  • coenttb.com - Full production website built 100% with swift-html
    • Complete server-side rendered website
    • Real-world implementation patterns
    • Production-ready architecture

Requirements

  • Swift 5.10+ (Full Swift 6 support)
  • macOS 14+ / iOS 17+ / tvOS 17+ / watchOS 10+ / Linux

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Support

Acknowledgements

This project builds upon foundational work by Point-Free (Brandon Williams and Stephen Celis). This package's HTML rendering engine (pointfree-html) is a fork of their swift-html library, but updated to their current approach on pointfreeco.

License

This project is licensed under the Apache License 2.0. See LICENSE for details.


Made with ❀️ by coenttb

About

A Swift library for domain accurate and type-safe HTML & CSS

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Languages