Open-source Swift-DocC separates documentation compilation from rendering
Swift-DocC is now open source, including the compiler and related rendering libraries. Its symbol-graph and documentation-catalog inputs connect API reference material with conceptual writing in one compilation workflow.
An API reference can describe every declaration in a library and still leave a reader unable to understand how its pieces fit together. Separately maintained conceptual documentation has the opposite maintenance problem, because its examples and terminology can drift away from the code. Swift-DocC became open source on October 13, bringing its combined documentation workflow into the Swift project.
DocC was announced at WWDC21 and is already included in Xcode 13. Today's change makes the implementation and related projects available for community work. The relevant architecture goes beyond a comment-to-HTML converter. A compiler combines structured API information with authored material into an archive, and a separate web application renders that archive.
I value documentation that explains the state and behavior a library expects callers to understand. Swift's type system supplies useful information, but a declaration alone cannot explain why a caller should choose one operation or what relationship must hold between several calls. DocC gives that explanatory material a place beside the API it describes.
Symbol graphs connect documentation to declarations
The launch-day project README describes two main input categories. Symbol graph files contain machine-readable API information. A documentation catalog contains authored articles and tutorials. Compiling both inputs produces a documentation archive.
Symbol graph files use the .symbols.json extension. They represent a module's APIs, including documentation comments and relationships among symbols. The README says the Swift compiler can emit them as of Swift 5.5. This supplies a defined intermediate representation between source compilation and documentation compilation.
That division matters because documentation tools need more than a sequence of comments. They need to know which declarations those comments describe and how the declarations relate. A graph exported by the compiler supplies that information in a form another program can consume. DocC can then combine source-level reference information with material written specifically for readers.
The related SymbolKit package supplies the format's specification and reference model. Its existence makes the representation useful to tools beyond a single documentation frontend. A consumer can work with a shared description of symbols instead of independently reconstructing API relationships from rendered pages or source text.
Catalogs contain authored explanations
A documentation catalog uses the .docc extension. It can contain Markdown files that extend symbol documentation or provide free-form articles. Tutorial files use a separate .tutorial extension for step-by-step material. Assets such as images or movies can accompany that content, and an optional Info.plist supplies metadata that can also come through command-line options.
This organization makes different kinds of writing part of one input set without requiring them to be identical. Reference pages explain individual symbols. A conceptual article can explain a design across several symbols. Tutorials can introduce the operations in a deliberate learning sequence. Each form has a purpose that a generated declaration list cannot supply by itself.
The important maintenance choice is that these inputs can live with the software they explain. A change to behavior can include the corresponding article or tutorial revision in the same source-control workflow. That does not force authors to keep prose current, but it removes a separate publication system as a prerequisite for doing so.
I find this useful for reviewing a library change. Documentation can state the public behavior the implementation intends to provide. When the prose and code change together, a reviewer can assess whether the explanation matches the actual contract. Good tooling makes that comparison possible without claiming to automate the judgement itself.
Compilation produces a renderer-independent archive
DocC outputs machine-readable compiled documentation. The archive includes render JSON files describing documentation pages. Swift-DocC-Render is the web application that consumes that representation and displays it. The compiler and the renderer therefore have different responsibilities, even when an integrated tool presents them as one action.
This structure leaves room for other tools to process documentation data. A consumer can work with the archive's page representation without treating HTML as the primary data model. It also means that compiling an archive and displaying a usable web interface are separate stages to diagnose when something goes wrong.
Swift Markdown is another related project. It handles parsing and manipulating Markdown documents, including the block directives used by tutorial content. Separating that functionality makes Markdown processing available independently of the entire DocC compilation workflow. The open-source release includes components with uses beyond generating a particular package's documentation.
Source comments retain familiar Swift documentation conventions. Symbol links can use double backticks around a symbol name, allowing reference material to connect related API declarations. These links matter because describing an operation often requires pointing to another operation or type. A documentation system that understands the relationship can support those references more precisely than an unstructured prose URL.
The command-line workflow exposes each input
The README requires Swift 5.5 for building DocC. It documents building the package and running the command-line executable through SwiftPM. Generating documentation for a package begins by asking the compiler to emit symbol graphs during a target build.
The project provides this command shape for its own SwiftDocC target. It is an example from the DocC source checkout rather than a command for an arbitrary package with a different target name.
mkdir -p .build/symbol-graphs
swift build --target SwiftDocC \
-Xswiftc -emit-symbol-graph \
-Xswiftc -emit-symbol-graph-dir -Xswiftc .build/symbol-graphs
That command can emit graphs for dependencies as well as the chosen target. The documented workflow then selects the graphs belonging to SwiftDocC into a dedicated directory. This makes the intended documentation input explicit. Having a directory full of graphs does not necessarily mean every module in that directory belongs in the archive being compiled.
The preview command combines the catalog and the graph directory. Fallback metadata supplies a display name, bundle identifier and version when the catalog does not supply those values.
docc preview Sources/SwiftDocC/SwiftDocC.docc \
--fallback-display-name SwiftDocC \
--fallback-bundle-identifier org.swift.SwiftDocC \
--fallback-bundle-version 1.0.0 \
--additional-symbol-graph-dir .build/swift-docc-symbol-graphs
The preview operation converts documentation and starts a local server. It monitors the supplied catalog for changes so authors can revise material while inspecting the result. That feedback loop applies to the authored documentation inputs. It should not be confused with regenerating API graphs after every source change without another build step.
A renderer remains a configured dependency
The launch README asks users to set DOCC_HTML_DIR to the renderer location. Xcode 13 includes a renderer that can be used locally. Alternatively, the separate renderer project can be built from source, with the README identifying Node.js 14 for that workflow.
This is a practical distinction for users outside the integrated Xcode experience. Obtaining the compiler source does not automatically establish that a renderer has been built and located. Previewing documentation needs both the compiled documentation path and the resources that display it. The documented environment variable supplies that connection.
Xcode also permits testing a locally built DocC through the DOCC_EXEC build setting. The next documentation build can then use the selected executable, and its build log identifies the command involved. This gives contributors a defined way to evaluate compiler changes inside an existing documentation authoring environment.
The README distinguishes versioning of the command-line tool from the SwiftDocC library. Command releases are intended to follow Swift toolchain versioning. The library is separately versioned, under active development and without guaranteed source stability. A tool integrating with the library needs to account for that stated contract instead of assuming the CLI's release relationship makes every library API stable.
These boundaries also give a documentation failure a more specific place to investigate. Missing API declarations call attention to graph generation and selection. Incorrect conceptual text belongs in the catalog, while a page that exists in the compiled representation but displays incorrectly raises a renderer question. The architecture does not guarantee that every failure fits neatly into one component, but it gives contributors concrete artifacts to compare between stages. That is more useful than treating the generated website as an indivisible output.
For maintainers, the source release makes those intermediate contracts inspectable. An integration can identify which graph files it supplied and which catalog revision it compiled. A renderer can be evaluated against the resulting archive. Keeping that information alongside the relevant tool versions provides a reproducible description of the documentation build, including stages that an IDE otherwise hides behind a menu item.
The announcement describes wider toolchain distribution and SwiftPM plugin integration as next steps. Those are plans as of today, while Xcode integration and the newly available sources are concrete. The open-source architecture now exposes the compiler inputs, archive format and rendering dependency well enough for other tool authors to examine how documentation generation can fit their own build workflows.