{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/steipete-me/2025-06-01-introducing-demark-html-in-md-out-blink-fast/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "![](https://steipete.me/assets/img/2025/demark/banner.png)\n\nI recently found myself needing a component that converts messy, potentially malformed HTML to clean Markdown in Swift. After searching around, I couldn’t find anything that really fit my needs, so I decided to write my own. The result is [Demark](https://github.com/steipete/Demark) – my first Swift package that’s now available on the [Swift Package Index](https://swiftpackageindex.com/steipete/Demark).\n\n## The Problem\n\nHTML to Markdown conversion sounds straightforward, but it’s surprisingly complex when you need to handle:\n\n- Malformed or messy HTML\n- JavaScript-rendered content\n- Complex nested structures\n- Various HTML edge cases\n\nI needed something reliable that could handle real-world HTML, not just clean, well-formed markup.\n\n## The Solution: Standing on the Shoulders of Giants\n\nInstead of writing a full-blown HTML parser from scratch, I took a different approach. Why reinvent the wheel when there are already excellent JavaScript libraries that solve this problem really well?\n\nDemark leverages two proven JavaScript libraries:\n\n- **[Turndown.js](https://github.com/mixmark-io/turndown)** for the most accurate conversions\n- **[html-to-md](https://github.com/stonehank/html-to-md)** for faster, lightweight processing\n\nThe magic happens by running these libraries inside a WKWebView, giving me access to a full browser environment with proper DOM parsing capabilities.\n\n## Two Conversion Engines\n\nDemark offers flexibility with two different engines:\n\n**[Turndown.js](https://github.com/mixmark-io/turndown) (Default)** - When you need accuracy:\n\n- Full DOM-based parsing\n- Handles complex HTML and JavaScript-rendered content\n- Comprehensive configuration options\n- \\~100ms for first conversion (then much faster)\n\n**[html-to-md](https://github.com/stonehank/html-to-md)** - When you need speed:\n\n- Lightweight JavaScript-based conversion\n- Much faster performance (~5-10ms per conversion)\n- Perfect for batch processing simple HTML\n\n## Vibe Coding with AI\n\nHere’s the thing – I probably would never have released this without AI assistance. But with AI, the whole process became so much easier. What would have taken me days of tedious work – setting up the package structure, writing documentation, handling edge cases, making it Swift Package Index ready – took me just a few hours.\n\nAI helped me:\n\n- Structure the Swift package properly\n- Write comprehensive documentation\n- Handle all the WebKit integration details\n- Create a clean, modern Swift API with async/await\n- Set up proper error handling\n\n## Simple to Use\n\nDespite the complexity under the hood, Demark is dead simple to use. The Swift package that turns down HTML and turns up Markdown – it’s a markup markdown!\n\n```swift\nimport Demark\n\n@MainActor \nfunc convertHTML() async throws {\n    let demark = Demark()\n    let html = \"<h1>Hello World</h1><p>This is <strong>bold</strong> text.</p>\"\n    let markdown = try await demark.convertToMarkdown(html)\n    print(markdown)\n    // Output: # Hello World\n    //\n    // This is **bold** text.\n}\n```\n\n## My First Swift Package\n\nDemark works across all Apple platforms: iOS, macOS, watchOS, tvOS, and visionOS.\n\nI’m quite happy about this milestone. After years of iOS development, publishing my first Swift package feels like a natural next step in my open source journey. The fact that it’s now in the [Swift Package Index](https://swiftpackageindex.com/steipete/Demark) makes it easily discoverable and installable for other developers.\n\nThe experience taught me that sometimes the best solution isn’t writing everything from scratch – it’s about cleverly combining existing, battle-tested solutions in a new way.\n\n## Try It Out\n\nIf you need HTML to Markdown conversion in your Swift projects, give [Demark](https://github.com/steipete/Demark) a try. You can add it to your project via Swift Package Manager:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/steipete/Demark.git\", from: \"1.0.0\")\n]\n```\n\nThe repository includes an example app with a dual-pane interface where you can test conversions in real-time. Perfect for seeing exactly how your HTML will be transformed.\n\nHere’s to many more Swift packages! 🚀\n",
  "authors": [],
  "captured_at": "2026-09-27T19:29:15.293681927+00:00",
  "category": "programming",
  "content_html": "<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://steipete.me/assets/img/2025/demark/banner.png\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>I recently found myself needing a component that converts messy, potentially malformed HTML to clean Markdown in Swift. After searching around, I couldn’t find anything that really fit my needs, so I decided to write my own. The result is <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/steipete/Demark\">Demark</a> – my first Swift package that’s now available on the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://swiftpackageindex.com/steipete/Demark\">Swift Package Index</a>.</p>\n<h2>The Problem</h2>\n<p>HTML to Markdown conversion sounds straightforward, but it’s surprisingly complex when you need to handle:</p>\n<ul>\n<li>Malformed or messy HTML</li>\n<li>JavaScript-rendered content</li>\n<li>Complex nested structures</li>\n<li>Various HTML edge cases</li>\n</ul>\n<p>I needed something reliable that could handle real-world HTML, not just clean, well-formed markup.</p>\n<h2>The Solution: Standing on the Shoulders of Giants</h2>\n<p>Instead of writing a full-blown HTML parser from scratch, I took a different approach. Why reinvent the wheel when there are already excellent JavaScript libraries that solve this problem really well?</p>\n<p>Demark leverages two proven JavaScript libraries:</p>\n<ul>\n<li><strong><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/mixmark-io/turndown\">Turndown.js</a></strong> for the most accurate conversions</li>\n<li><strong><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/stonehank/html-to-md\">html-to-md</a></strong> for faster, lightweight processing</li>\n</ul>\n<p>The magic happens by running these libraries inside a WKWebView, giving me access to a full browser environment with proper DOM parsing capabilities.</p>\n<h2>Two Conversion Engines</h2>\n<p>Demark offers flexibility with two different engines:</p>\n<p><strong><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/mixmark-io/turndown\">Turndown.js</a> (Default)</strong> - When you need accuracy:</p>\n<ul>\n<li>Full DOM-based parsing</li>\n<li>Handles complex HTML and JavaScript-rendered content</li>\n<li>Comprehensive configuration options</li>\n<li>~100ms for first conversion (then much faster)</li>\n</ul>\n<p><strong><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/stonehank/html-to-md\">html-to-md</a></strong> - When you need speed:</p>\n<ul>\n<li>Lightweight JavaScript-based conversion</li>\n<li>Much faster performance (~5-10ms per conversion)</li>\n<li>Perfect for batch processing simple HTML</li>\n</ul>\n<h2>Vibe Coding with AI</h2>\n<p>Here’s the thing – I probably would never have released this without AI assistance. But with AI, the whole process became so much easier. What would have taken me days of tedious work – setting up the package structure, writing documentation, handling edge cases, making it Swift Package Index ready – took me just a few hours.</p>\n<p>AI helped me:</p>\n<ul>\n<li>Structure the Swift package properly</li>\n<li>Write comprehensive documentation</li>\n<li>Handle all the WebKit integration details</li>\n<li>Create a clean, modern Swift API with async/await</li>\n<li>Set up proper error handling</li>\n</ul>\n<h2>Simple to Use</h2>\n<p>Despite the complexity under the hood, Demark is dead simple to use. The Swift package that turns down HTML and turns up Markdown – it’s a markup markdown!</p>\n<pre><code class=\"language-swift\"><span class=\"code-snippet\" data-language=\"Swift\">import Demark\n\n@MainActor \nfunc convertHTML() async throws {\n    let demark = Demark()\n    let html = &quot;&lt;h1&gt;Hello World&lt;/h1&gt;&lt;p&gt;This is &lt;strong&gt;bold&lt;/strong&gt; text.&lt;/p&gt;&quot;\n    let markdown = try await demark.convertToMarkdown(html)\n    print(markdown)\n    // Output: # Hello World\n    //\n    // This is **bold** text.\n}\n</span></code></pre>\n<h2>My First Swift Package</h2>\n<p>Demark works across all Apple platforms: iOS, macOS, watchOS, tvOS, and visionOS.</p>\n<p>I’m quite happy about this milestone. After years of iOS development, publishing my first Swift package feels like a natural next step in my open source journey. The fact that it’s now in the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://swiftpackageindex.com/steipete/Demark\">Swift Package Index</a> makes it easily discoverable and installable for other developers.</p>\n<p>The experience taught me that sometimes the best solution isn’t writing everything from scratch – it’s about cleverly combining existing, battle-tested solutions in a new way.</p>\n<h2>Try It Out</h2>\n<p>If you need HTML to Markdown conversion in your Swift projects, give <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/steipete/Demark\">Demark</a> a try. You can add it to your project via Swift Package Manager:</p>\n<pre><code class=\"language-swift\"><span class=\"code-snippet\" data-language=\"Swift\">dependencies: [\n    .package(url: &quot;https://github.com/steipete/Demark.git&quot;, from: &quot;1.0.0&quot;)\n]\n</span></code></pre>\n<p>The repository includes an example app with a dual-pane interface where you can test conversions in real-time. Perfect for seeing exactly how your HTML will be transformed.</p>\n<p>Here’s to many more Swift packages! 🚀</p>\n",
  "content_markdown": "![](https://steipete.me/assets/img/2025/demark/banner.png)\n\nI recently found myself needing a component that converts messy, potentially malformed HTML to clean Markdown in Swift. After searching around, I couldn’t find anything that really fit my needs, so I decided to write my own. The result is [Demark](https://github.com/steipete/Demark) – my first Swift package that’s now available on the [Swift Package Index](https://swiftpackageindex.com/steipete/Demark).\n\n## The Problem\n\nHTML to Markdown conversion sounds straightforward, but it’s surprisingly complex when you need to handle:\n\n- Malformed or messy HTML\n- JavaScript-rendered content\n- Complex nested structures\n- Various HTML edge cases\n\nI needed something reliable that could handle real-world HTML, not just clean, well-formed markup.\n\n## The Solution: Standing on the Shoulders of Giants\n\nInstead of writing a full-blown HTML parser from scratch, I took a different approach. Why reinvent the wheel when there are already excellent JavaScript libraries that solve this problem really well?\n\nDemark leverages two proven JavaScript libraries:\n\n- **[Turndown.js](https://github.com/mixmark-io/turndown)** for the most accurate conversions\n- **[html-to-md](https://github.com/stonehank/html-to-md)** for faster, lightweight processing\n\nThe magic happens by running these libraries inside a WKWebView, giving me access to a full browser environment with proper DOM parsing capabilities.\n\n## Two Conversion Engines\n\nDemark offers flexibility with two different engines:\n\n**[Turndown.js](https://github.com/mixmark-io/turndown) (Default)** - When you need accuracy:\n\n- Full DOM-based parsing\n- Handles complex HTML and JavaScript-rendered content\n- Comprehensive configuration options\n- \\~100ms for first conversion (then much faster)\n\n**[html-to-md](https://github.com/stonehank/html-to-md)** - When you need speed:\n\n- Lightweight JavaScript-based conversion\n- Much faster performance (~5-10ms per conversion)\n- Perfect for batch processing simple HTML\n\n## Vibe Coding with AI\n\nHere’s the thing – I probably would never have released this without AI assistance. But with AI, the whole process became so much easier. What would have taken me days of tedious work – setting up the package structure, writing documentation, handling edge cases, making it Swift Package Index ready – took me just a few hours.\n\nAI helped me:\n\n- Structure the Swift package properly\n- Write comprehensive documentation\n- Handle all the WebKit integration details\n- Create a clean, modern Swift API with async/await\n- Set up proper error handling\n\n## Simple to Use\n\nDespite the complexity under the hood, Demark is dead simple to use. The Swift package that turns down HTML and turns up Markdown – it’s a markup markdown!\n\n```swift\nimport Demark\n\n@MainActor \nfunc convertHTML() async throws {\n    let demark = Demark()\n    let html = \"<h1>Hello World</h1><p>This is <strong>bold</strong> text.</p>\"\n    let markdown = try await demark.convertToMarkdown(html)\n    print(markdown)\n    // Output: # Hello World\n    //\n    // This is **bold** text.\n}\n```\n\n## My First Swift Package\n\nDemark works across all Apple platforms: iOS, macOS, watchOS, tvOS, and visionOS.\n\nI’m quite happy about this milestone. After years of iOS development, publishing my first Swift package feels like a natural next step in my open source journey. The fact that it’s now in the [Swift Package Index](https://swiftpackageindex.com/steipete/Demark) makes it easily discoverable and installable for other developers.\n\nThe experience taught me that sometimes the best solution isn’t writing everything from scratch – it’s about cleverly combining existing, battle-tested solutions in a new way.\n\n## Try It Out\n\nIf you need HTML to Markdown conversion in your Swift projects, give [Demark](https://github.com/steipete/Demark) a try. You can add it to your project via Swift Package Manager:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/steipete/Demark.git\", from: \"1.0.0\")\n]\n```\n\nThe repository includes an example app with a dual-pane interface where you can test conversions in real-time. Perfect for seeing exactly how your HTML will be transformed.\n\nHere’s to many more Swift packages! 🚀\n",
  "dateCreated": "2026-09-27T19:29:15.293681927+00:00",
  "date_created": "2025-06-01T18:45:00+00:00",
  "date_modified": "2025-06-01T18:45:00+00:00",
  "date_published": "2025-06-01T18:45:00+00:00",
  "description": "How I vibe coded my first Swift package using existing JavaScript libraries and AI assistance to solve HTML to Markdown conversion in Swift.",
  "external_url": "https://steipete.me/posts/2025/introducing-demark-html-to-markdown-in-swift/",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/steipete-me/2025/06/2025-06-01-introducing-demark-html-in-md-out-blink-fast.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/steipete-me/2025/06/2025-06-01-introducing-demark-html-in-md-out-blink-fast.md"
  },
  "id": "urn:aggr:item:4df43bafc8c067509c92fb7178b6ac21414b5f73",
  "isBasedOn": {
    "@id": "https://steipete.me/posts/2025/introducing-demark-html-to-markdown-in-swift/"
  },
  "mainEntity": {
    "@id": "https://steipete.me/posts/2025/introducing-demark-html-to-markdown-in-swift/",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/steipete-me/2025-06-01-introducing-demark-html-in-md-out-blink-fast/#webpage"
    },
    "dateModified": "2025-06-01T18:45:00+00:00",
    "datePublished": "2025-06-01T18:45:00+00:00",
    "headline": "Introducing Demark: HTML in. MD out. Blink-fast.",
    "timeRequired": "PT3M",
    "url": "https://steipete.me/posts/2025/introducing-demark-html-to-markdown-in-swift/",
    "wordCount": 562
  },
  "name": "Archived snapshot: Introducing Demark: HTML in. MD out. Blink-fast.",
  "preview": null,
  "reading_minutes": 3,
  "replicated_at": null,
  "source": "steipete-me",
  "source_name": "Peter Steinberger",
  "summary": "How I vibe coded my first Swift package using existing JavaScript libraries and AI assistance to solve HTML to Markdown conversion in Swift.",
  "tags": [],
  "temporalCoverage": "2026-09-27T19:29:15.293681927+00:00",
  "title": "Introducing Demark: HTML in. MD out. Blink-fast.",
  "url": "https://aggr.aymericbeaumet.com/items/steipete-me/2025-06-01-introducing-demark-html-in-md-out-blink-fast/",
  "word_count": 562
}