Skip to main content
This guide will help you render your first markdown view using MarkdownView.

Basic usage

MarkdownView provides a single MarkdownTextView component that works on iOS, macOS, and visionOS.
1

Import the modules

import UIKit
import MarkdownParser
import MarkdownView
2

Create the view

let markdownView = MarkdownTextView()
3

Parse and render markdown

let parser = MarkdownParser()
let result = parser.parse("""
# Hello, Markdown!

This is **bold**, *italic*, and `inline code`.

- Item one
- Item two
- Item three
""")

let content = MarkdownTextView.PreprocessedContent(
    parserResult: result,
    theme: .default
)
markdownView.setMarkdown(content)

Complete UIKit example

Here’s a complete view controller that renders markdown with link and image tap handlers:
ViewController.swift
import UIKit
import MarkdownParser
import MarkdownView

class ViewController: UIViewController {

    private let markdownView = MarkdownTextView()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(markdownView)
        markdownView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            markdownView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            markdownView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
            markdownView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
        ])

        // Parse and render markdown
        let parser = MarkdownParser()
        let result = parser.parse("""
        # Hello, Markdown!

        This is **bold**, *italic*, and `inline code`.

        - Item one
        - Item two
        - Item three
        """)

        let content = MarkdownTextView.PreprocessedContent(
            parserResult: result,
            theme: .default
        )
        markdownView.setMarkdown(content)

        // Handle link taps
        markdownView.linkHandler = { payload, range, point in
            switch payload {
            case .url(let url):
                UIApplication.shared.open(url)
            case .string(let string):
                print("Tapped link: \(string)")
            }
        }

        // Handle image taps
        markdownView.imageTapHandler = { source, point in
            print("Image tapped: \(source)")
        }
    }
}

SwiftUI integration

Wrap MarkdownTextView in UIViewRepresentable to use it from SwiftUI:
import SwiftUI
import MarkdownParser
import MarkdownView

struct MarkdownTextViewRepresentable: UIViewRepresentable {
    let markdown: String
    var theme: MarkdownTheme = .default

    func makeUIView(context: Context) -> MarkdownTextView {
        let view = MarkdownTextView()
        view.backgroundColor = .clear
        view.isOpaque = false
        return view
    }

    func updateUIView(_ uiView: MarkdownTextView, context: Context) {
        uiView.theme = theme
        let parser = MarkdownParser()
        let result = parser.parse(markdown)
        let content = MarkdownTextView.PreprocessedContent(
            parserResult: result,
            theme: theme
        )
        uiView.setMarkdown(content)
    }

    func sizeThatFits(
        _ proposal: ProposedViewSize,
        uiView: MarkdownTextView,
        context: Context
    ) -> CGSize? {
        guard let width = proposal.width, width > 0 else {
            return uiView.intrinsicContentSize
        }
        let measuredSize = uiView.boundingSize(for: width)
        return CGSize(width: width, height: measuredSize.height)
    }
}

Customizing themes

MarkdownView supports comprehensive theming to match your app’s design:
var theme = MarkdownTheme()

// Customize fonts
theme.fonts.body = .preferredFont(forTextStyle: .body)
theme.fonts.code = .monospacedSystemFont(ofSize: 14, weight: .regular)

// Customize colors
theme.colors.body = .label
theme.colors.code = .secondaryLabel
theme.colors.codeBackground = .secondarySystemBackground

// Scale all fonts
theme.scaleFont(by: .large)

markdownView.theme = theme
You can create multiple themes and switch between them dynamically based on user preferences or system appearance.

Performance optimization

For better performance with dynamic content, use the raw string API to parse and render on a background queue:
// This method automatically handles parsing and preprocessing on a background queue
markdownView.setMarkdown(string: markdownString)
The setMarkdown(string:) method performs parsing, syntax highlighting, and math rendering on a background queue, then updates the UI on the main thread.

Next steps

API reference

Explore the complete MarkdownView API

Theming guide

Learn advanced theming techniques

Performance tips

Optimize rendering for large documents

Examples

Browse more code examples

Build docs developers (and LLMs) love