Andy Regensky

Getting started with static-site generation in Swift using Publish

Publish is an open source static-site generator written entirely in swift. Together with Ink and Plot, it enables to implement whole websites in swift. Thereby, Ink is responsible for parsing markdown syntax into html, while Plot is a domain specific language (DSL) to define html documents using conventional swift syntax. Both features in itself are incredibly powerful, but their combination into the Publish static-site generator brings them onto an even higher level.

So how do you generate your first static website using Publish? There are a number of possibilites to getting started, but the most convenient way is using the publish Command Line Interface (CLI). To start the setup process, clone the publish github repository.

git clone

Once the repository is checked out, enter the directory and run make to build and install the CLI.

cd publish

The publish CLI is now installed and you can use it to generate the necessary project structure for a new publish website. Leave the publish repository, then create a folder named after your project. Let's use Homepage as an example. Enter the project directory and initialize the publish project using the CLI command new.

cd Homepage
publish new

Open Package.swift in XCode to inspect the generated files. You'll see a number of files and folders. Package.swift is the swift package description and contains information on your project targets and its dependencies. You can learn more about swift packages and the Swift Package Manager (SPM) in the official SPM documentation or an excellent post by John Sundell. The folder Content contains markdown files which are one way to define your website's content. The folder Resources contains any resources for your project such as images, videos or css files. Finally, the folder Source contains the actual website description. Open the main.swift file, to have a look at the website description.

import Foundation
import Publish
import Plot

// This type acts as the configuration for your website.
struct Homepage: Website {
    enum SectionID: String, WebsiteSectionID {
        // Add the sections that you want your website to contain here:
        case posts

    struct ItemMetadata: WebsiteItemMetadata {
        // Add any site-specific metadata that you want to use here.

    // Update these properties to configure your website:
    var url = URL(string: "")!
    var name = "Homepage"
    var description = "A description of Homepage"
    var language: Language { .english }
    var imagePath: Path? { nil }

// This will generate your website using the built-in Foundation theme:
try Homepage().publish(withTheme: .foundation)

As you see, the struct Homepage implements the Website protocol and defines the general structure of the website. The SectionID enum is used to define the different sections of the website. The struct ItemMetadata is used to define additional metadata types for your website items. Sections and Items are related in a parent child relationship, meaning that any section may have multiple items (e.g. posts), but an item is related to exactly one section. For now, the struct is empty, meaning that we do not define additional item metadata. Down the line, there are a number of additional properties to define the url you want to use for your website, its name, a description of your website, its main language as well as an image path that is used to represent your website if it's linked on social networks.

The website is then generated by creating an instance of Homepage and publishing it with the given theme. For now, the built-in foundation theme is used. Note however, that in general, you'll want to implement your own theme for your website. We'll explore theme creation as well as advanced publishing pipelines in a future post.

For now, have a look at your initial website by running

publish run

and opening http://localhost:8000 in your browser.

Congratulations, you generated your first static-site in Swift using Publish! You can now add new sections in your website description or add new posts by adding additional markdown files in your Content folder.

Happy coding, see you next time!

Tagged with: