Generate a man page for a Swift command-line tool

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
Search for a command to run...

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
No comments yet. Be the first to comment.
WWDC26 kicked off on June 8, 2026. The information in this article reflects the information published by Apple on that date. There are 14 new frameworks. Name Description AccessoryAccess Manage

WWDC25 kicked off on June 9, 2025. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AlarmKitSchedule prominent alarms and countdowns to help people manage their time. AVR...

WWDC25 is almost here, and I couldn’t be more excited! Whether you're attending the official events, community meetups, or just soaking in the energy around Cupertino, there’s no better time to connect, share ideas, and celebrate everything we love a...

In this blog post, I’ll share an observation and advice regarding the caching behavior of network responses by Apple’s APIs. If you are unfamiliar with caching of network responses then I recommend Apple’s article Accessing cached data that introduce...
WWDC24 kicked off on June 10, 2024. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AccessorySetupKitUse AccessorySetupKit to discover accessories with Bluetooth or Wi-Fi...

This blog post will teach you how to generate a manual page for your Swift command-line tool using Apple's swift-argument-parser. I will also teach you how to ensure that the man page will be installed along your command-line tool.
I'll use my command-line tool swiftplantuml as a concrete example.
A man page (short for manual page) is a form of software documentation usually found on a Unix or Unix-like operating system. Topics covered include computer programs (including library and system calls), formal standards and conventions, and even abstract concepts. A user may invoke a man page by issuing the man command.
Example

Apple's ArgumentParser includes a SwiftPM plugin for generating man pages with version 1.1.4.
Make sure you are declaring 1.1.4 in your Package.swift manifest as dependency:
dependencies: [
.package(
name: "swift-argument-parser",
url: "https://github.com/Apple/swift-argument-parser.git",
from: "1.1.4"
),
],
You can create a single main page including all subcommands:
swift package plugin generate-manual
Or you create multiple man pages, one per subcommand:
swift package plugin generate-manual --multi-page
The generated man page(s) can be found in folder .build/plugins/GenerateManualPlugin/outputs
When running the command for my command-line tool swiftplantuml then the file swiftplantuml.1 gets generated in .build/plugins/GenerateManualPlugin/outputs/swiftplantuml
The man command to view a man page will search in various directories.
man swiftplantuml
If the requested man page was not found then you will see a message like this:
No manual entry for swiftplantuml
I recommend you copy the generated man page to /usr/local/share/man/man1/ as /usr/local/share/man is part of the search path for man pages on Mac.
Note: You might have to create this directory. You can do so with mkdir -p /usr/local/share/man/man1
You can automate and make this step part of your tool installation.
For example, SwiftPlantUML offers a Makefile which can be used by tools like Homebrew to streamline the installation process. In SwiftPlantUML's Makefile I install not only the tools binary but also the man page. Below I share a snippet out of my Makefile:
install-man-files: $(SOURCES)
mkdir -p ${DESTDIR}${mandir}/man1
cp $(REPODIR)/man/swiftplantuml.1 ${DESTDIR}${mandir}/man1/swiftplantuml.1
build-swiftplantuml: $(SOURCES)
@swift build \
-c release \
--disable-sandbox \
--build-path "$(BUILDDIR)"
.PHONY: install
install: build-swiftplantuml
@install -d "$(bindir)"
@install "$(wildcard $(BUILDDIR)/**/release/swiftplantuml)" "$(bindir)"
@make install-man-files
You may notice that I don't generate the man page with the SPM plugin during make install. I previously generated and then checked-in the file, in a folder named man, in Git. Why? Because I don't want to make Xcode 13.3 (= Swift 5.6 in which SPM introduced plugins) a requirement for installation.
I even revert to a dependency < 1.1.0 as ArgumentParser@1.1.0 and higher will require Swift 5.5. (Xcode 13 => macOS 11.3) and SwiftPlantUML shall be buildable from source from lower OS versions.
You might ask: "What is the advantage of man pages over the generated help option?"
I raised the raise question in Swift Forums ⬇️
I leave you with the following answer:
Overall, man pages are simply the standard, conventional way of providing documentation for command line tools. Sticking to that convention makes your docs more easily accessible and useful, even if they have the same content as a --help.