# DTCoreText: rendering HTML as CoreText attributed strings on Apple platforms

> DTCoreText turns HTML into NSAttributedString and SwiftUI AttributedString for iOS, macOS and tvOS, using CoreText for layout so you avoid a web view. It is a Swift package under BSD-2-Clause, with a licence obligation worth reading before you ship.

**Cocoanetics/DTCoreText** — Methods to allow using HTML code with CoreText

- Repository: https://github.com/Cocoanetics/DTCoreText
- Stars: 6,392 · Forks: 1,183
- Language: Swift
- License: BSD-2-Clause
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/cocoanetics-dtcoretext

## What DTCoreText replaces, and for whom

Apple's native rich text stack expects attributed strings. Your content often arrives as HTML, from a CMS, an email body, a help centre export or a server-rendered fragment. The usual shortcut is to wrap a WKWebView and let the browser do the work. That costs you a second rendering engine inside the app, a heavier view hierarchy, and a layout you cannot measure or cache the way you measure text. DTCoreText exists for the other path: parse the HTML, produce an NSAttributedString (or a SwiftUI AttributedString), and hand it to CoreText for layout and drawing.

The audience is narrow and identifiable. You are building a reading surface, a feed of articles, a comment list, or a changelog viewer, and the markup is simple enough that a focused parser is acceptable. You want the text to behave like text: selectable, measurable, cacheable, and consistent with the rest of your typography. You do not want a web view in that cell. DTCoreText covers two areas according to its README: parsing and layout, and user interface classes such as DTAttributedTextView and DTAttributedLabel that render the result.

The library is written primarily in Swift and ships as a Swift package. It targets iOS, macOS and tvOS, which matters if you maintain one rendering path across those platforms and do not want three different HTML stories.

## How the HTML to CoreText pipeline is structured

The mechanism is a conversion, not a browser. HTML goes in, an attributed string comes out, and CoreText handles line breaking, glyph runs and drawing. The README describes the split plainly: one part of the project generates attributed strings from HTML and interfaces with CoreText, the other provides view classes for displaying them.

That division has a practical consequence. Because layout is CoreText, the result participates in the same measurement APIs as any other attributed text in your app. You can compute a height, cache it, and reuse it while scrolling. A web view does not give you that; it gives you a rectangle whose contents you influence but do not measure.

The repository layout reflects the same separation. Sources/ holds the code, Tests/ holds the test targets, and Documentation/ carries a Programming Guide template that the README points to as a source of solutions to common problems. Demo/ contains a DemoApp with its own resources and source files, which is the place to look when you want to see the view classes wired up rather than read about them. The README also links to documentation browsable on the Swift Package Index.

What the README does not do is enumerate which HTML elements and CSS properties are honoured. If your markup relies on a specific subset, the Tests/ directory and the Programming Guide are the places to check before you commit to the approach.

## Installing DTCoreText as a Swift package

There is no CocoaPods or Carthage instruction in the README. Installation is through Swift Package Manager, either from Xcode or from Package.swift. In Xcode, the README says to use File > Add Package Dependencies… and enter the repository URL:

```
https://github.com/Cocoanetics/DTCoreText.git
```

If you manage dependencies in a manifest instead, the README gives this example, which pins the package to version 2.0.0 or later within the same major line:

```swift
.package(url: "https://github.com/Cocoanetics/DTCoreText.git", from: "2.0.0")
```

After the package resolves, link the DTCoreText product to your target. That last step is easy to skip and produces a build that cannot find the module. Once linked, the first real use is the conversion itself: take an HTML string, produce an attributed string, and place it in one of the provided view classes. The README names DTAttributedTextView and DTAttributedLabel as the rendering classes, and the Demo app in Demo/ is where the wiring is demonstrated rather than described.

Before you pin a version, check GitHub Releases, which the README lists as the changelog. The most recent release listed there is 2.1.0 from 2026-06-13, following 2.0.0 on 2026-04-19. The 2.0.0 major version is what the README's Package.swift example references, so a project already on 1.x should read the release notes before moving.

## The attribution licence is a shipping decision, not a formality

DTCoreText is covered by a standard 2-clause BSD licence. The README states the obligation directly: you must mention Cocoanetics as the original author and reproduce the LICENSE text inside your app. That is not a footnote. It means a licence screen or an acknowledgements screen in your shipped binary, and it means the text has to be the actual licence text, not a link to a website.

The README also documents the alternative: a Non-Attribution-License sold for 75 Euros, for teams that do not want to include the LICENSE text. If your product has no acknowledgements surface, or legal review treats embedded licence text as a problem, that purchase is the path the project itself offers. Sponsorship for specific enhancements is mentioned as well, with an email contact in the README.

This article is not legal advice, and the licence terms are the ones in the LICENSE file at the repository root, not the summary here. Read that file. The practical point is that the adoption decision has a non-code component, and it is cheaper to resolve it before the release build than after.

## Where DTCoreText is the wrong tool

The honest limitation is scope. DTCoreText generates attributed strings from HTML and lays them out with CoreText. It is not a browser, and nothing in the README claims otherwise. If your content depends on a full CSS layout engine, flexbox, web fonts loaded from a stylesheet, or script-driven DOM changes, a WKWebView is the correct component and DTCoreText is not. Choosing it there means fighting the abstraction.

The second limitation is documentation depth. The README is short and points outward: online documentation on the Swift Package Index, a Programming Guide in Documentation/, and the Demo app. It does not publish a support matrix of HTML tags, CSS properties or platform quirks. For a library whose entire job is interpreting markup, that silence is the thing to probe first. The Tests/ directory is the most reliable place to learn what the maintainers consider supported behaviour, because tests encode decisions that prose often omits.

The third is maintenance cadence. The repository is not archived, and the last push was on 2026-07-15, so it is current. Releases are infrequent rather than continuous: 2.1.0 in June 2026, 2.0.0 in April 2026, and 1.6.28 back in September 2024. That pattern suggests a project that ships when there is something to ship. If your roadmap assumes a fast upstream fix for an edge case in the parser, plan around the release rhythm rather than against it.

## DTCoreText against the WKWebView approach

The real alternative is not another parsing library. It is the WKWebView you were probably going to use. The difference in approach is where layout happens. With a web view, WebKit parses the HTML, applies CSS, performs layout, and paints into a view you embed. With DTCoreText, parsing produces an attributed string and CoreText performs layout, so the text is an object in your process from the start.

That difference shows up in three places. Measurement: an attributed string can be sized before it is displayed, which matters for self-sizing cells in a list. Caching: you can keep the parsed attributed string and reuse it, whereas a web view re-renders. Consistency: the text inherits the same font, colour and line-height conventions as the rest of your interface, because it is the same text system.

The cost is fidelity. WebKit renders what a browser renders. DTCoreText renders what its parser and CoreText support. If your HTML is authored by people who expect browser behaviour, the web view will match their expectations more often. The honest framing is that this is a fidelity-versus-integration trade, and the README's own description of the project, methods to use HTML code with CoreText, tells you which side it picked.

## Deciding whether to adopt it

Adopt DTCoreText when the HTML is a means to an end and the text is the product. Article bodies, release notes, comment threads, onboarding copy delivered from a CMS. In those cases the parser does not need to be perfect, it needs to be predictable, and CoreText layout gives you measurement and caching that a web view does not.

Do not adopt it when the HTML is the product. If authors expect browser fidelity, or the markup leans on layout features that only a full engine implements, a WKWebView is the right answer and DTCoreText will look like a constraint. Do not adopt it either if a licence screen in your binary is unacceptable and you are unwilling to buy the non-attribution licence, because the BSD-2-Clause obligation is explicit in the README.

The verification list before you write production code is short and specific. Read the LICENSE file at the repository root rather than the summary in the README. Check GitHub Releases for the current tag and read the 2.0.0 notes if you are coming from 1.x. Skim Tests/ to see which HTML behaviour is asserted, since that is the closest thing to a support matrix. Then open Demo/ and run the demo app, because the README's own documentation path leads there for the view classes.

## Conclusion

Adopt DTCoreText if you need HTML-derived rich text laid out by CoreText and you accept the BSD-2-Clause attribution requirement, or you are willing to buy the non-attribution licence. Do not adopt it if you need a browser-grade HTML engine, because it is not one. Before writing code, verify the current release tag on GitHub Releases, confirm the DTCoreText product links to your target, and decide whether the LICENSE text ships inside your app or you purchase the non-attribution option. The last push to the repository was on 2026-07-15.

## FAQ

### How do I install DTCoreText in an Xcode project?

Add it as a Swift package. The README says to use File > Add Package Dependencies… and enter the repository URL, then link the DTCoreText product to your target.

### Does DTCoreText work on macOS and tvOS, or only iOS?

The README states that DTCoreText generates NSAttributedString and SwiftUI AttributedString from HTML on iOS, macOS and tvOS, so all three platforms are covered.

### What does the DTCoreText licence require me to do?

It is a standard 2-clause BSD licence. The README says you must mention Cocoanetics as the original author and reproduce the LICENSE text inside your app, and that a Non-Attribution-License is available for 75 Euros if you do not want to include that text.

### Do I need a web view to display HTML with DTCoreText?

No. The README describes generating attributed strings from HTML and using CoreText for layout and rendering, which is the alternative to embedding a web view.

## Sources

- [Cocoanetics/DTCoreText on GitHub](https://github.com/Cocoanetics/DTCoreText)
- [Issues](https://github.com/Cocoanetics/DTCoreText/issues)
- [License: BSD-2-Clause](https://github.com/Cocoanetics/DTCoreText/blob/main/LICENSE)
- [README](https://github.com/Cocoanetics/DTCoreText/blob/main/README.md)
- [Releases](https://github.com/Cocoanetics/DTCoreText/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cocoanetics-dtcoretext
