Contents

1amageek/swift-markdown-ui

A lightweight SwiftUI library for rendering and editing Markdown content. Built on top of Apple's swift-markdown parser.

Requirements

  • Swift 6.2+
  • macOS 26+ / iOS 26+

Installation

Add the package to your Package.swift:

dependencies: [
    .package(url: "https://github.com/1amageek/swift-markdown-ui.git", from: "0.1.0"),
]

Then add MarkdownUI to your target dependencies:

.target(
    name: "YourTarget",
    dependencies: [
        .product(name: "MarkdownUI", package: "swift-markdown-ui"),
    ]
)

Usage

Rendering Markdown

import MarkdownUI

struct ContentView: View {
    var body: some View {
        MarkdownView("""
        # Hello, Markdown!

        This is a **bold** statement with some `inline code`.

        - Item 1
        - Item 2
        - [x] Completed task
        - [ ] Pending task

        ```swift
        print("Hello, World!")
        ```
        """)
    }
}

Editing Markdown

MarkdownEditor is a focused text editor for Markdown. Compose it with MarkdownView to build a split-pane layout.

struct EditorView: View {
    @State private var text = "# Hello\n\nStart writing..."

    var body: some View {
        HStack(spacing: 12) {
            MarkdownEditor(text: $text)
            Divider()
            ScrollView {
                MarkdownView(text)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(12)
            }
        }
    }
}

Swap HStack for VStack to stack the panes vertically.

Styling

MarkdownStyle provides full control over colors, fonts, and spacing for every block type.

Using the Default Style
MarkdownView("# Hello")
    .markdownStyle(.default)
Custom Style

Create a fully customized style by initializing MarkdownStyle directly:

let customStyle = MarkdownStyle(
    textColor: .primary,
    secondaryTextColor: .secondary,
    accentColor: .blue,
    codeTextColor: .green,
    codeBackground: Color.black.opacity(0.8),
    quoteBarColor: .orange,
    quoteBackground: Color.orange.opacity(0.1),
    tableBorderColor: .gray.opacity(0.3),
    tableHeaderBackground: .blue.opacity(0.1),
    tableCellBackground: .clear,
    bodyFont: .body,
    codeFont: .system(.body, design: .monospaced),
    captionFont: .caption,
    editorFont: .system(.body, design: .monospaced),
    heading1Font: .largeTitle.bold(),
    heading2Font: .title2.bold(),
    heading3Font: .title3.weight(.semibold),
    heading4Font: .headline.weight(.semibold),
    heading5Font: .subheadline.weight(.semibold),
    heading6Font: .footnote.weight(.semibold),
    tableHeaderFont: .caption.weight(.semibold),
    tableBodyFont: .body,
    blockSpacing: 12,
    lineSpacing: 4,
    listIndent: 22,
    tableColumnSpacing: 12,
    tableRowSpacing: 8
)

MarkdownView("# Custom styled")
    .markdownStyle(customStyle)
Convenience Modifiers

Override individual properties without creating a full style:

MarkdownView("| Name | Value |\n|---|---|\n| A | 1 |")
    .tableHeaderBackground(.blue.opacity(0.1))
    .tableCellBackground(.gray.opacity(0.05))
    .font(.caption, for: .code)
Font Roles

Use .font(_:for:) to override fonts for specific roles:

MarkdownView("# Title\n\nBody text with `code`")
    .font(.system(.title, design: .serif), for: .heading(1))
    .font(.system(.body, design: .serif), for: .body)
    .font(.system(.callout, design: .monospaced), for: .code)

Available font roles:

| Role | Used for | |------|----------| | .body | Paragraph text | | .code | Inline code and code blocks | | .caption | List markers, code block language labels | | .editor | Markdown editor text | | .heading(1) ... .heading(6) | Heading levels 1-6 | | .tableHeader | Table header cells | | .tableBody | Table body cells |

Style Properties Reference

Colors:

| Property | Description | |----------|-------------| | textColor | Primary text | | secondaryTextColor | List markers, captions | | accentColor | Links, tint color | | codeTextColor | Code block text | | codeBackground | Code block background | | quoteBarColor | Block quote left bar | | quoteBackground | Block quote background | | tableBorderColor | Table outer border | | tableHeaderBackground | Table header row background | | tableCellBackground | Table body cell background |

Spacing:

| Property | Default | Description | |----------|---------|-------------| | blockSpacing | 12 | Vertical space between blocks | | lineSpacing | 4 | Line spacing within text | | listIndent | 22 | Width of list marker column | | tableColumnSpacing | 12 | Horizontal space between table columns | | tableRowSpacing | 8 | Vertical space between table rows |

Environment Propagation

Styles propagate through the SwiftUI environment. Set a style on a parent view to apply it to all MarkdownView children:

VStack {
    MarkdownView("# First")
    MarkdownView("# Second")
}
.markdownStyle(customStyle)

Supported Markdown Elements

| Element | Description | |---|---| | Headings | Levels 1-6 | | Paragraphs | Inline formatting (bold, italic, links, code) | | Block Quotes | Nested block support | | Ordered Lists | Custom start index | | Unordered Lists | Bullet points | | Task Lists | Checkboxes (checked/unchecked) | | Code Blocks | Language label display | | Tables | Column alignment support | | Thematic Breaks | Horizontal rules | | HTML Blocks | Raw HTML display |

License

MIT

Package Metadata

Repository: 1amageek/swift-markdown-ui

Default branch: main

README: README.md