| name | slipstream |
| description | Expert assistance for Slipstream static site generation. Use when building static websites with Slipstream, a SwiftUI-like static site generator. |
Slipstream Expert
You are an expert in the Slipstream static site generation framework. Slipstream is a SwiftUI-like declarative framework for building static HTML websites with Tailwind CSS integration.
Core Principles
- SwiftUI-like Syntax: Slipstream uses result builders and the
Viewprotocol to create HTML in a declarative, hierarchical manner - Tailwind CSS Integration: All utility modifiers map to Tailwind CSS classes
- Static Site Generation: Designed for building static HTML that can be deployed to platforms like GitHub Pages
- Type-Safe HTML: Provides Swift types for W3C HTML elements with compile-time safety
Architecture
View Protocol
The View protocol is the foundation of Slipstream:
public protocol View {
associatedtype Content: View
@ViewBuilder var body: Self.Content { get }
func render(_ container: Element) throws
}
- Implement
bodyfor custom views - Use
@ViewBuilderto enable declarative syntax - Only implement
render(_:environment:)when creating new HTML element types
Result Builders
Slipstream uses Swift result builders (@ViewBuilder) to enable hierarchical view construction. This allows:
- Multiple children in a single block
- Conditional content with
if/else - Loops with
ForEach - Optional content
Common View Types
Layout Views
VStack(alignment:spacing:)- Vertical stack (maps to flex column)HStack(alignment:spacing:)- Horizontal stack (maps to flex row)Container- Tailwind CSS container for centered, max-width contentResponsiveStack- Adapts between vertical/horizontal based on breakpoints
Text and Typography
Text("content")- Basic paragraph text (renders as<p>)H1,H2,H3,H4,H5,H6- Heading elementsParagraph- Explicit paragraph wrapperBold,Strong,Italic,Emphasis- Text stylingCode,Variable,SampleOutput- Code-related elementsMarkdownText- Render Markdown as HTML
Forms
Form- Form containerTextField(name:type:placeholder:)- Text inputTextArea(name:placeholder:)- Multi-line textButton,SubmitButton,ResetButton- ButtonsCheckbox,RadioButton- Selection inputsPickerwithOptionandOptGroup- Dropdown selectsSlider,ColorPicker,FileInput- Specialized inputsLabel,Fieldset,Legend- Form organization
Media
Image(URL)- ImagesPicturewithSource- Responsive imagesAudio,VideowithSourceandTrack- Media playbackCanvas- Canvas elementIFrame- Embedded content
Semantic HTML
Header,Footer,Navigation- Page structureArticle,Section,Aside- Content organizationDocumentMain- Main content areaFigure,FigureCaption- Figures with captionsBlockquote- QuotationsList,ListItem- ListsDescriptionList,DescriptionTerm,DefinitionDescription- Definition listsTable,TableHeader,TableBody,TableFooter,TableRow,TableCell,TableHeaderCell- TablesDetails,Summary- Collapsible contentDivider- Horizontal ruleLineBreak- Line break
SVG and MathML
SVG,SVGCircle,SVGRect,SVGPath,SVGDefs,SVGLinearGradient,SVGStop- SVG graphicsMath,MRow,MI,MO,MN,MFrac,MSqrt,MSup,MSub- Mathematical notation
Utilities
Comment("text")- HTML commentsDOMString("raw html")- Raw HTML injectionForEach(collection, id:)- Iterate over collections
Tailwind CSS Modifiers
Typography
.fontSize(.extraLarge)
.fontWeight(.bold)
.bold()
.fontStyle(.italic)
.italic()
.fontDesign(.monospaced) // .serif, .sans
.fontLeading(.loose) // line height
.textAlignment(.center)
.textColor(.blue, shade: .x500)
.textDecoration(.underline) // .lineThrough
.listStyle(.disc) // .decimal, .none
Spacing
.padding() // all edges
.padding(.horizontal, 16)
.padding(.vertical, 8)
.padding(.top, 4)
.margin(8)
.margin(.bottom, 16)
Sizing
.frame(width: 48, height: 48)
.frame(minWidth: 48, maxWidth: 96)
.frame(minHeight: 100)
Colors and Backgrounds
.textColor(.red, shade: .x500)
.backgroundColor(.blue, shade: .x100)
.background(.ultraThin) // material background
Borders and Effects
.border(1, .black)
.cornerRadius(.large)
.shadow(.large)
.outline(.solid, width: 2, color: .red)
.ring(width: 2, color: .blue)
Layout
.display(.block) // .flex, .grid, .none
.position(.absolute, edges: .top, 0)
.placement(top: 10, left: 10, zIndex: 10)
.zIndex(100)
.overflow(.scroll) // .hidden, .auto
.float(.left)
.visibility(.hidden)
Flexbox and Grid
.flexDirection(.row) // .column
.justifyContent(.spaceBetween) // .center, .start, .end
.alignItems(.center) // .start, .end, .baseline
.flexGap(16)
.gridCellColumns(2)
.gridCellRows(3)
Transforms and Transitions
.offset(x: 16, y: 32)
.opacity(0.5)
.colorInvert()
.animation(.easeIn(duration: 0.25))
.transition(.all)
Responsive and State
.fontSize(.base)
.fontSize(.large, condition: .desktop)
.textColor(.blue)
.textColor(.red, condition: .hover)
Available conditions:
- Breakpoints:
.mobile,.tablet,.desktop,.widescreen - States:
.hover,.focus,.active,.visited,.disabled
Environment System
Slipstream provides SwiftUI-like environment for passing data down the view hierarchy:
Define Custom Environment Key
struct PathKey: EnvironmentKey {
static var defaultValue: String = "/"
}
extension EnvironmentValues {
var path: String {
get { self[PathKey.self] }
set { self[PathKey.self] = newValue }
}
}
Use Environment
struct MyView: View {
@Environment(\.path) var path
var body: some View {
Text("Current path: \(path)")
}
}
// Inject environment value
MyView()
.environment(\.path, "/home")
Rendering
Render Single View
import Slipstream
struct HelloWorld: View {
var body: some View {
Text("Hello, world!")
}
}
let html = try renderHTML(HelloWorld())
print(html)
Render Sitemap
import Foundation
import Slipstream
let sitemap: Sitemap = [
"index.html": HomePage(),
"about/index.html": AboutPage(),
"blog/post-1.html": BlogPost(id: 1)
]
let outputURL = URL(filePath: #filePath)
.deletingLastPathComponent()
.deletingLastPathComponent()
.appending(path: "site")
try renderSitemap(sitemap, to: outputURL)
W3C Global Attributes
All views support W3C global attributes:
.id("unique-id")
.className("custom-class")
.title("Tooltip")
.data("key", "value")
.accessibilityLabel("Screen reader text")
.language("en")
.dir(.ltr) // .rtl
.contentEditable(.true)
.spellcheck(true)
.draggable(true)
.tabindex(1)
.disabled(true)
.hidden()
.inert(true)
.autofocus(true)
Best Practices
1. Composition
Break complex views into smaller, reusable components:
struct Navigation: View {
var body: some View {
Header {
HStack {
Link("Home", destination: "/")
Link("About", destination: "/about")
}
}
}
}
struct HomePage: View {
var body: some View {
Navigation()
DocumentMain {
H1("Welcome")
Text("Home page content")
}
}
}
2. Use Semantic HTML
Choose semantic elements over generic containers:
- Use
Header,Footer,Navigation,Articleinstead of generic divs - Use
H1-H6for headings, not styledText - Use
Strongfor semantic emphasis,Boldfor visual only
3. Responsive Design
Apply responsive modifiers for different screen sizes:
Text("Responsive")
.fontSize(.base)
.fontSize(.large, condition: .tablet)
.fontSize(.extraLarge, condition: .desktop)
.padding(4)
.padding(8, condition: .tablet)
4. Tailwind CSS Alignment
Remember that Slipstream uses Tailwind's predefined sizes, not exact pixel values. The framework finds the closest Tailwind class to requested values.
5. Environment for Shared State
Use environment for configuration that needs to flow down the hierarchy:
struct Theme {
var primaryColor: TailwindColor
var accentColor: TailwindColor
}
// Define environment key, inject at top level, read in child views
Common Patterns
Page Layout Template
struct PageTemplate<Content: View>: View {
let title: String
@ViewBuilder let content: () -> Content
var body: some View {
Container {
Header {
Navigation {
Link("Home", destination: "/")
Link("About", destination: "/about")
}
}
DocumentMain {
H1(title)
content()
}
Footer {
Text("© 2025 My Site")
}
}
}
}
// Usage
PageTemplate(title: "About") {
Text("About page content")
}
Card Component
struct Card<Content: View>: View {
@ViewBuilder let content: () -> Content
var body: some View {
VStack(alignment: .leading, spacing: 16) {
content()
}
.padding(24)
.backgroundColor(.white)
.cornerRadius(.large)
.shadow(.medium)
}
}
Hero Section
struct Hero: View {
let title: String
let subtitle: String
var body: some View {
VStack(alignment: .center, spacing: 24) {
H1(title)
.fontSize(.extraLarge5)
.fontWeight(.bold)
.textColor(.gray, shade: .x900)
Text(subtitle)
.fontSize(.extraLarge)
.textColor(.gray, shade: .x600)
}
.padding(.vertical, 96)
.textAlignment(.center)
}
}
Package Setup
Package.swift
// swift-tools-version: 5.10
import PackageDescription
let package = Package(
name: "mysite",
platforms: [
.macOS("14"),
.iOS("17"),
],
dependencies: [
.package(url: "https://github.com/jverkoey/slipstream.git", branch: "main"),
],
targets: [
.executableTarget(name: "mysite", dependencies: [
.product(name: "Slipstream", package: "slipstream"),
]),
]
)
Tailwind CSS Configuration
tailwind.config.js:
module.exports = {
content: ["./site/**/*.html"],
theme: {
extend: {},
},
plugins: [],
}
tailwind.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
Build Command
swift run && npx tailwindcss -i tailwind.css -o ./site/output.css --minify
Quick Reference
Color Palette
Available colors: .black, .white, .gray, .red, .orange, .amber, .yellow, .lime, .green, .emerald, .teal, .cyan, .sky, .blue, .indigo, .violet, .purple, .fuchsia, .pink, .rose
Shades: .x50, .x100, .x200, .x300, .x400, .x500, .x600, .x700, .x800, .x900, .x950
Font Sizes
.extraSmall, .small, .base, .large, .extraLarge, .extraLarge2, .extraLarge3, .extraLarge4, .extraLarge5, .extraLarge6, .extraLarge7, .extraLarge8, .extraLarge9
Font Weights
.thin, .extraLight, .light, .normal, .medium, .semibold, .bold, .extraBold, .black
Spacing Scale
Common values: 0, 1, 2, 4, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64, 96, 128
Shadow Sizes
.small, .medium, .large, .extraLarge, .extraLarge2, .inner, .none
Corner Radius
.none, .small, .medium, .large, .extraLarge, .extraLarge2, .extraLarge3, .full
When to Use This Skill
Use this skill when:
- Building static websites with Swift
- Converting SwiftUI-like code to HTML
- Working with Tailwind CSS utilities in Swift
- Creating reusable view components for web
- Setting up Slipstream projects
- Rendering sitemaps and multi-page sites
- Implementing responsive layouts
- Using W3C HTML elements and attributes
- Working with SVG or MathML in Slipstream
- Managing environment values
- Troubleshooting Slipstream rendering
Documentation References
The complete Slipstream documentation is available at:
- Main docs: https://slipstream.clutch.engineering/documentation/slipstream/
- GitHub: https://github.com/jverkoey/slipstream
- Site template: https://github.com/jverkoey/slipstream-site-template
Local documentation is in: Sources/Slipstream/Documentation.docc/