<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Selfish Blog</title><link>https://selfpubli.sh/blog/</link><description>Notes on independent publishing, static sites and building Selfish.</description><generator>Hugo</generator><language>en-GB</language><copyright>© 2026 Selfish</copyright><lastBuildDate>Tue, 15 Sep 2026 09:30:00 +0100</lastBuildDate><atom:link href="https://selfpubli.sh/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>A blogging app for iPhone that publishes plain HTML</title><link>https://selfpubli.sh/blog/iphone-blogging-app-that-publishes-html/</link><pubDate>Tue, 15 Sep 2026 09:30:00 +0100</pubDate><guid>https://selfpubli.sh/blog/iphone-blogging-app-that-publishes-html/</guid><description>What to look for in an iPhone blogging app if you want plain HTML you own, and an honest look at WordPress, Micro.blog, Ghost, Working Copy and iA Writer.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Plenty of apps let you write a blog post on an iPhone. Far fewer let you finish the job there – turn that post into a web page and put it on a server you control – without a platform in the middle.&lt;/p&gt;&#10;&lt;p&gt;If what you want at the end is plain HTML files on your own domain, readable in any browser in twenty years&amp;rsquo; time, the choice narrows quickly. This is a guide to what to look for, what the main options actually do at the time of writing, and where each one fits.&lt;/p&gt;&#10;&lt;h2 id="what-to-look-for"&gt;What to look for&lt;/h2&gt;&#10;&lt;p&gt;Six questions sort the field.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;What is the output?&lt;/strong&gt; Some apps post into a platform&amp;rsquo;s database; the page only exists while that platform runs. Others produce actual files: HTML, CSS, images, a feed. Files are the durable option. You can copy them, archive them and serve them from anywhere.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Where does it publish?&lt;/strong&gt; A hosted platform, or a destination you choose: your own server over SFTP, object storage such as S3, or a static host such as Netlify, Cloudflare Pages or GitHub Pages.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Does it work on the phone alone?&lt;/strong&gt; Many &amp;ldquo;mobile&amp;rdquo; workflows quietly depend on a computer or a cloud build service to do the real work. That is fine if you know it going in.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Is there an account?&lt;/strong&gt; Every account is a dependency, and a place your writing and credentials sit that you don&amp;rsquo;t control.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;How are credentials stored?&lt;/strong&gt; Server passwords, SSH keys and API tokens should live in the iOS Keychain, not in an app&amp;rsquo;s own database or synced in plain text.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Can you see exactly what will be published?&lt;/strong&gt; A preview that matches the live page saves a lot of republishing.&lt;/p&gt;&#10;&lt;h2 id="the-landscape"&gt;The landscape&lt;/h2&gt;&#10;&lt;h3 id="wordpress-and-jetpack-apps"&gt;WordPress and Jetpack apps&lt;/h3&gt;&#10;&lt;p&gt;The official WordPress app is a capable mobile editor for WordPress sites, with the block editor, media uploads and drafts. Automattic splits its mobile features between it and the Jetpack app, which adds stats, notifications and more.&lt;/p&gt;&#10;&lt;p&gt;The output is WordPress: posts go into the site&amp;rsquo;s database and pages are generated by PHP on the server. If you already run WordPress, these apps are the obvious choice and they are good at it. They do not produce HTML files you own; they edit an application you have to keep running and patched. We compare the two approaches in &lt;a href="https://selfpubli.sh/blog/wordpress-vs-static-site/"&gt;WordPress vs a static site&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h3 id="microblog"&gt;Micro.blog&lt;/h3&gt;&#10;&lt;p&gt;Micro.blog is the closest thing to &amp;ldquo;blogging from your phone&amp;rdquo; as a complete, friendly service. There are native apps for iPhone, Mac and Android, hosted blogs, custom domain support, cross-posting to social networks and, on higher plans, email newsletters and multiple blogs. At the time of writing hosted plans start at $1 a month for Micro.one, with the full Micro.blog plan at $5 a month.&lt;/p&gt;&#10;&lt;p&gt;Under the hood, Micro.blog builds hosted blogs with Hugo, a static site generator, and it offers an export of your theme and posts as Markdown in a Hugo-style folder. That is a better exit than most platforms offer. But the site is hosted by Micro.blog, not published to a server you run, and it is a subscription. For many people that trade is exactly right.&lt;/p&gt;&#10;&lt;h3 id="ghost-in-the-browser"&gt;Ghost in the browser&lt;/h3&gt;&#10;&lt;p&gt;Ghost does not have an official native iPhone app for writing. Its admin editor runs in Safari and works on a phone, and there is at least one third-party app, Publisher for Ghost, that talks to a Ghost site.&lt;/p&gt;&#10;&lt;p&gt;Ghost pages are rendered by a Node.js application backed by a database, whether on Ghost(Pro) or on your own server. It is a strong platform with newsletters and memberships built in – see &lt;a href="https://selfpubli.sh/blog/substack-alternatives-you-own/"&gt;Substack alternatives that you actually own&lt;/a&gt; – but it is not plain HTML.&lt;/p&gt;&#10;&lt;h3 id="working-copy-and-a-static-site-generator"&gt;Working Copy and a static site generator&lt;/h3&gt;&#10;&lt;p&gt;This is the developer&amp;rsquo;s route, and it genuinely works. Working Copy is a Git client for iOS: you clone the repository holding your Hugo, Jekyll or Eleventy site, write Markdown in its editor (or in any app that can open files in its folders), commit and push.&lt;/p&gt;&#10;&lt;p&gt;The catch is what happens next. The iPhone does not build the site. The push triggers a build elsewhere – GitHub Actions, Netlify, Cloudflare Pages – and that service produces the HTML. You need the site set up from a computer first, you need to be comfortable with Git, and pushing requires Working Copy&amp;rsquo;s paid pro features (a one-off purchase of $35.99 at the time of writing; the app is free to download and has a trial).&lt;/p&gt;&#10;&lt;p&gt;For developers who already live in Git, it is a fine setup. For everyone else it is a lot of moving parts for a blog post.&lt;/p&gt;&#10;&lt;h3 id="ia-writer-and-other-writing-apps"&gt;iA Writer and other writing apps&lt;/h3&gt;&#10;&lt;p&gt;iA Writer is an excellent place to write, and on iPhone and iPad it can send a document to WordPress, Ghost, Medium, Micro.blog or any Micropub endpoint. It creates a &lt;strong&gt;draft&lt;/strong&gt; on the destination, which you then open and publish there.&lt;/p&gt;&#10;&lt;p&gt;That makes it a writing front end for a platform, not a publisher. The output is whatever the destination produces. Several other writing apps take the same approach. If you love the writing experience and already have a platform, this pairing works well.&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Output&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Publishes to your own server&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Needs a computer or build service&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Cost (at the time of writing)&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;WordPress app&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;WordPress site&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Your WordPress install&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;No, but needs a running WordPress&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Free app; hosting extra&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Micro.blog&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hosted site (built with Hugo)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;No, hosted by Micro.blog&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;No&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;From $1/month&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ghost in Safari&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ghost site&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Your Ghost install, if self-hosted&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;No, but needs a running Ghost&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ghost(Pro) or your server&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Working Copy + SSG&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Static HTML&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yes, via a build service&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;$35.99 one-off for push&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;iA Writer&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Draft on a platform&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;No&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;No&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;One-off app purchase&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;None of these is wrong. They answer different questions. What most of them don&amp;rsquo;t do is let you write on the phone and have the phone produce the finished static site and upload it to a place you chose.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;That gap is what Selfish is for: a native app for iPhone, iPad and Mac – £3.99 once, no subscription – that builds a complete static site – HTML, feeds, sitemap – and publishes it over SFTP or to S3-compatible storage, Netlify, Cloudflare Pages or GitHub Pages, with credentials kept in the Keychain and no Selfish account. It does not do comments, newsletters or imports from other platforms. It is out now &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt;, at a £3.99 introductory price, rising to £9.99 in December; the &lt;a href="https://selfpubli.sh/guide/"&gt;user guide&lt;/a&gt; shows how writing works, and the &lt;a href="https://selfpubli.sh/themes/"&gt;themes page&lt;/a&gt; shows what the output looks like.&lt;/p&gt;&#10;</content:encoded></item><item><title>Selfish vs Medium: your own site or a borrowed audience</title><link>https://selfpubli.sh/blog/selfish-vs-medium/</link><pubDate>Tue, 08 Sep 2026 11:05:00 +0100</pubDate><guid>https://selfpubli.sh/blog/selfish-vs-medium/</guid><description>An honest comparison of Selfish and Medium: ownership, cost, custom domains, the Partner Program, discovery and export, and when Medium is the better pick.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Here&amp;rsquo;s the short answer. Medium is the better choice if you want readers soon and don&amp;rsquo;t mind writing inside someone else&amp;rsquo;s product to get them. Selfish is the better choice if you want a site that is entirely yours: plain HTML files on hosting you control, with no account and no platform between you and whoever reads it. Medium lends you an audience and a way to get paid. Selfish gives you ownership and nothing else. You can&amp;rsquo;t get both from either one, so the real question is which of the two you&amp;rsquo;d miss more.&lt;/p&gt;&#10;&lt;h2 id="at-a-glance"&gt;At a glance&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Selfish&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Medium&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ownership&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;You own the files and choose the host&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Medium runs the platform your stories live on&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cost&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;£3.99 once for the app, introductory — £9.99 from December. Optional premium themes at £1.99 each. You pay for your own hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Free to write. Membership is $5 a month or $50 a year at the time of writing, and you need it for the Partner Program and custom domains&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where content lives&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;On your device (optional iCloud sync), published to your server&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;On Medium&amp;rsquo;s servers&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Custom domain&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Whatever domain you point at your own hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Members only. A root domain or subdomain, not a subdirectory&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Email/newsletter&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None. Selfish doesn&amp;rsquo;t send email, but it does publish RSS and JSON feeds&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Readers can subscribe to get your stories by email&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Monetisation&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Partner Program pays for member engagement with paywalled stories&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Audience/discovery&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Built-in readership, recommendations, publications, Boost&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Editing&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Native app for iPhone, iPad and Mac, with live preview&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Browser editor plus mobile apps&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Output&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A complete static site: HTML, sitemap, RSS and JSON feeds&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Pages on Medium&amp;rsquo;s platform&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Lock-in/export&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The published site is standard HTML with no Selfish code in it&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Export gives you HTML files in a .zip. Your followers stay on Medium&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="where-medium-genuinely-wins"&gt;Where Medium genuinely wins&lt;/h2&gt;&#10;&lt;h3 id="distribution"&gt;Distribution&lt;/h3&gt;&#10;&lt;p&gt;A new Selfish site starts with no readers. It has no feed or recommendation engine and no network of other writers sending people your way. That&amp;rsquo;s the cost of independence, and it&amp;rsquo;s a real cost.&lt;/p&gt;&#10;&lt;p&gt;Medium starts you somewhere else. It has a readership that&amp;rsquo;s already there, publications you can submit to, and a recommendation system that can put a story from a brand-new account in front of strangers. It also runs Boost, which gives selected stories wider distribution. Medium&amp;rsquo;s own explanation of Partner Program earnings says boosted stories earn at a higher rate. If your aim is for strangers to read your first ten posts, Medium is the stronger bet.&lt;/p&gt;&#10;&lt;h3 id="getting-paid-for-words"&gt;Getting paid for words&lt;/h3&gt;&#10;&lt;p&gt;The Medium Partner Program is the simplest way to earn money from writing without building anything yourself. Medium&amp;rsquo;s help centre currently lists the eligibility rules as:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;an active Medium membership&lt;/li&gt;&#10;&lt;li&gt;at least one published story&lt;/li&gt;&#10;&lt;li&gt;a complete profile&lt;/li&gt;&#10;&lt;li&gt;a bank account in a supported country&lt;/li&gt;&#10;&lt;li&gt;being 18 or over&lt;/li&gt;&#10;&lt;li&gt;agreeing to the programme terms and the paywall content policy&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Earnings depend on how paying members engage with your member-only stories. That covers reading and listening time plus interactions such as claps, highlights and replies.&lt;/p&gt;&#10;&lt;p&gt;Selfish has nothing comparable. It has no paywall, no payments and no revenue share. If you want to be paid inside the place where you publish, that settles it.&lt;/p&gt;&#10;&lt;h3 id="zero-setup"&gt;Zero setup&lt;/h3&gt;&#10;&lt;p&gt;With Medium you sign up and write. You don&amp;rsquo;t deal with hosting, DNS, credentials or deploys. Selfish removes most of the friction from self-publishing, but you still need somewhere to publish to. That could be a server you reach over SFTP, an S3-compatible bucket, or an account on Netlify, Cloudflare Pages or GitHub Pages. For some people that one-off setup is enough reason to stay on a platform.&lt;/p&gt;&#10;&lt;h3 id="email-to-followers"&gt;Email to followers&lt;/h3&gt;&#10;&lt;p&gt;Medium lets readers subscribe to a writer and get new stories by email. Selfish doesn&amp;rsquo;t send email of any kind. Your readers can follow the RSS feed, and plenty of people still do, but a feed isn&amp;rsquo;t an inbox.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-wins"&gt;Where Selfish wins&lt;/h2&gt;&#10;&lt;h3 id="the-address-is-yours-unconditionally"&gt;The address is yours, unconditionally&lt;/h3&gt;&#10;&lt;p&gt;Medium supports custom domains, but only while you&amp;rsquo;re a paying member. Its help centre also restricts you to a root domain or a subdomain, so you can&amp;rsquo;t serve Medium from &lt;code&gt;yourdomain.com/blog&lt;/code&gt;. With Selfish your domain points at your own hosting, and no subscription stands between them. The domain and the hosting are both yours. Selfish just writes files to them.&lt;/p&gt;&#10;&lt;h3 id="the-reader-gets-a-web-page"&gt;The reader gets a web page&lt;/h3&gt;&#10;&lt;p&gt;Once you join the Partner Program, stories you put behind the paywall are part of Medium&amp;rsquo;s membership. Non-members hit the limits Medium sets. A Selfish site is a set of static pages. It has no membership prompts, no third-party scripts and no Selfish code. Themes use no web fonts and send nothing back to anyone. Readers load a page and read it.&lt;/p&gt;&#10;&lt;h3 id="the-files-are-the-site"&gt;The files are the site&lt;/h3&gt;&#10;&lt;p&gt;When you publish with Selfish, the output is a complete static site. It has standalone HTML for every post and page, archive pages for categories and tags, a sitemap, RSS and JSON feeds, and canonical links. Any web server on earth can serve that, and it will still be readable in twenty years. Your drafts stay on your device, optionally synced through your own iCloud account. Selfish has no servers holding a copy.&lt;/p&gt;&#10;&lt;h3 id="cost-is-predictable"&gt;Cost is predictable&lt;/h3&gt;&#10;&lt;p&gt;Selfish costs £3.99, once, with no subscription, no per-site fee and no paywall on publishing. That is an introductory price; it rises to £9.99 in December. The only optional purchases are three premium themes at £1.99 each, bought once. Your ongoing cost is whatever your hosting costs, and static files are about the cheapest thing there is to host.&lt;/p&gt;&#10;&lt;h2 id="leaving-medium-if-you-decide-to"&gt;Leaving Medium, if you decide to&lt;/h2&gt;&#10;&lt;p&gt;Medium makes it reasonably easy to get your writing out:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;On the web, click your profile picture and open &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;Go to the &lt;strong&gt;Security and apps&lt;/strong&gt; tab.&lt;/li&gt;&#10;&lt;li&gt;Click &lt;strong&gt;Download your information&lt;/strong&gt;, then &lt;strong&gt;Export&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;Medium emails you a link to a .zip archive of your stories as HTML files.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Be clear about what that archive is. It&amp;rsquo;s your text, in HTML. It doesn&amp;rsquo;t bring your followers or your stats with it, and every link anyone has shared still points at Medium. Selfish doesn&amp;rsquo;t import Medium archives either. Moving posts means copying them across by hand, which is tedious for a large back catalogue and quite manageable for a few dozen posts. We&amp;rsquo;ve written more about the process in &lt;a href="https://selfpubli.sh/blog/leaving-medium/"&gt;leaving Medium for good&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;You also don&amp;rsquo;t have to choose outright. Many writers publish on their own site first, then republish selected pieces on Medium with a link back to the original. That way they keep the canonical home and still get some of the reach.&lt;/p&gt;&#10;&lt;h2 id="choose-medium-if"&gt;Choose Medium if…&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You want an audience you didn&amp;rsquo;t have to build, and you&amp;rsquo;re happy for the platform to decide who sees what.&lt;/li&gt;&#10;&lt;li&gt;You want to earn from your writing without setting up payments yourself, and the Partner Program&amp;rsquo;s rules and eligibility suit you.&lt;/li&gt;&#10;&lt;li&gt;You&amp;rsquo;d rather pay a membership than think about hosting at all.&lt;/li&gt;&#10;&lt;li&gt;Email notifications to followers matter to you.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="choose-selfish-if"&gt;Choose Selfish if…&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You want your writing on your own domain, your own hosting and your own terms, with no membership keeping it there.&lt;/li&gt;&#10;&lt;li&gt;You care that the published site is plain, fast HTML with no tracking and no platform code.&lt;/li&gt;&#10;&lt;li&gt;You write on an iPhone, iPad or Mac and want a native app with a preview that matches the published page exactly.&lt;/li&gt;&#10;&lt;li&gt;You&amp;rsquo;re fine with finding readers the slow way, through search, links, feeds and people sharing your work.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;Selfish is &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt; for iPhone, iPad and Mac. It&amp;rsquo;s a one-time £3.99 purchase — introductory, rising to £9.99 in December — and you can run as many independent sites as you like from one app. If you&amp;rsquo;re weighing up ownership against reach, the &lt;a href="https://selfpubli.sh/guide/"&gt;user guide&lt;/a&gt; shows what writing and publishing look like, and the &lt;a href="https://selfpubli.sh/docs/"&gt;publishing docs&lt;/a&gt; cover each hosting route. Medium will still be there if you want the reach as well.&lt;/p&gt;&#10;</content:encoded></item><item><title>Own your blog: leaving Medium for good</title><link>https://selfpubli.sh/blog/leaving-medium/</link><pubDate>Wed, 02 Sep 2026 08:50:00 +0100</pubDate><guid>https://selfpubli.sh/blog/leaving-medium/</guid><description>A practical guide to leaving Medium: exporting your archive, moving posts, canonical links, what you can't redirect, and keeping a mirror that points home.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Medium is a pleasant place to write and a poor place to keep things. The editor is good, the reading experience is clean and there is a built-in audience you will not get on your own site overnight. But the address is theirs, the paywall is theirs, the distribution rules are theirs, and they have changed all three more than once.&lt;/p&gt;&#10;&lt;p&gt;Leaving is not hard. It is fiddly, and the fiddly parts are worth doing properly because you only do them once. This guide covers the whole move: getting your archive, getting your posts into a new home, and dealing honestly with the links you can&amp;rsquo;t take with you.&lt;/p&gt;&#10;&lt;h2 id="step-1-download-your-medium-archive"&gt;Step 1: Download your Medium archive&lt;/h2&gt;&#10;&lt;p&gt;Medium lets you export everything it holds about you as a zip file. At the time of writing the path on the web is:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Click your profile picture, then &lt;strong&gt;Settings&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;Open the &lt;strong&gt;Security and apps&lt;/strong&gt; tab.&lt;/li&gt;&#10;&lt;li&gt;Click &lt;strong&gt;Download your information&lt;/strong&gt; and confirm with &lt;strong&gt;Export&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;In the iOS and Android apps it is under Settings → Account → Security and apps. Either way, Medium emails you a download link when the archive is ready, usually within minutes.&lt;/p&gt;&#10;&lt;p&gt;Do this first, even if you are not ready to move. An export you have is worth more than one you meant to get.&lt;/p&gt;&#10;&lt;h2 id="step-2-understand-whats-in-the-archive"&gt;Step 2: Understand what&amp;rsquo;s in the archive&lt;/h2&gt;&#10;&lt;p&gt;Unzip the file and you will find a README and a set of folders – posts, bookmarks, claps, highlights, lists, profile and so on. The one that matters is &lt;code&gt;posts&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;A few things to know before you start:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Each post is a standalone HTML file.&lt;/strong&gt; Not Markdown, not JSON. It opens in any browser, and the text copies out cleanly.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Drafts and responses are mixed in with published stories.&lt;/strong&gt; Every comment you ever left on someone else&amp;rsquo;s story was a &amp;ldquo;response&amp;rdquo;, and Medium treats responses as posts, so they all land in the same folder. Expect to sift before you start moving anything.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Images are not in the zip.&lt;/strong&gt; The HTML files reference images on Medium&amp;rsquo;s CDN. They will load for now, but if you want to own them you need to download each one and host it yourself. Several open-source scripts exist to do this in bulk if you have a lot of posts.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Your followers are not in it.&lt;/strong&gt; The archive lists the accounts &lt;em&gt;you&lt;/em&gt; follow, not the email addresses of people who follow you. Treat your Medium followers as an audience you will invite to the new place rather than one you can move.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="step-3-choose-where-the-posts-are-going"&gt;Step 3: Choose where the posts are going&lt;/h2&gt;&#10;&lt;p&gt;This is the decision that makes everything else easier. Pick a home at your own domain. It can be WordPress, Ghost, a static site generator such as Hugo, or a native app that builds a static site for you. We compare the options in &lt;a href="https://selfpubli.sh/blog/self-host-a-personal-blog/"&gt;the best way to self-host a personal blog&lt;/a&gt;, and weigh the two biggest camps in &lt;a href="https://selfpubli.sh/blog/wordpress-vs-static-site/"&gt;WordPress vs a static site&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;Whatever you pick, buy the domain first and put it on a registrar you trust. The domain is the part of this move that keeps future moves painless.&lt;/p&gt;&#10;&lt;h2 id="step-4-move-the-posts"&gt;Step 4: Move the posts&lt;/h2&gt;&#10;&lt;p&gt;Some platforms have Medium importers; WordPress.com, for instance, accepts the Medium export file and keeps original dates and tags. If yours does not, you will be copying by hand, and for most personal blogs that is less work than it sounds.&lt;/p&gt;&#10;&lt;p&gt;A workable routine, one post at a time:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Open the exported HTML file in a browser.&lt;/li&gt;&#10;&lt;li&gt;Copy the body text into your new editor. Formatting such as headings, bold, italics, links and quotes usually survives a paste; check it.&lt;/li&gt;&#10;&lt;li&gt;Save each image from the page and attach it to the new post.&lt;/li&gt;&#10;&lt;li&gt;Set the publication date to the original date, so your archive stays in order.&lt;/li&gt;&#10;&lt;li&gt;Note the old Medium URL next to the new one in a spreadsheet. You will need that list later.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Be ruthless while you do it. Old posts that you would not write today can stay behind. A smaller archive you are proud of beats a complete one you are not.&lt;/p&gt;&#10;&lt;h2 id="step-5-accept-what-you-cant-redirect"&gt;Step 5: Accept what you can&amp;rsquo;t redirect&lt;/h2&gt;&#10;&lt;p&gt;This is the part people get wrong, so to be plain about it: &lt;strong&gt;you cannot redirect &lt;code&gt;medium.com&lt;/code&gt; URLs.&lt;/strong&gt; You do not control that domain or its server. Every link to &lt;code&gt;medium.com/@you/some-post-a1b2c3d4e5f6&lt;/code&gt; that already exists on the web will keep pointing at Medium for as long as the post exists there. If you delete the post, those links break.&lt;/p&gt;&#10;&lt;p&gt;There is one exception. If you connected your &lt;strong&gt;own custom domain&lt;/strong&gt; to Medium, you control that domain, and you can point it at your new host.&lt;/p&gt;&#10;&lt;p&gt;Custom domains have a history on Medium. They were once a paid add-on, were withdrawn for new users for a while, and have since returned; at the time of writing Medium offers them free to paying members. If you used one, the move is much kinder:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Point the domain&amp;rsquo;s DNS at your new host.&lt;/li&gt;&#10;&lt;li&gt;Set up redirects from each old Medium-style path (a slug ending in a string of hex characters) to the matching new URL, using the spreadsheet from Step 4. Most hosts support a redirects file; on your own server, an Nginx &lt;code&gt;return 301&lt;/code&gt; per line works.&lt;/li&gt;&#10;&lt;li&gt;Disconnect the domain in your Medium settings too, so Medium is no longer configured to use it.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;If you never used a custom domain, there is nothing to redirect. The fix is the next step.&lt;/p&gt;&#10;&lt;h2 id="step-6-keep-a-medium-mirror-that-points-home"&gt;Step 6: Keep a Medium mirror that points home&lt;/h2&gt;&#10;&lt;p&gt;You don&amp;rsquo;t have to delete your Medium posts, and there is a good argument for not doing so. Old links keep working, and Medium still sends readers. What you want is for search engines to treat your own site as the original.&lt;/p&gt;&#10;&lt;p&gt;That is what a canonical link does. Medium lets you set one on an existing story:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Open the story and choose &lt;strong&gt;Edit story&lt;/strong&gt; from the three-dot menu.&lt;/li&gt;&#10;&lt;li&gt;In edit mode, open the three-dot menu again and choose &lt;strong&gt;More settings&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;Under &lt;strong&gt;Advanced Settings&lt;/strong&gt;, select &lt;strong&gt;This story was originally published elsewhere&lt;/strong&gt;, paste the URL of the post on your new site and save.&lt;/li&gt;&#10;&lt;li&gt;Republish the story.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Medium&amp;rsquo;s page now carries &lt;code&gt;&amp;lt;link rel=&amp;quot;canonical&amp;quot;&amp;gt;&lt;/code&gt; pointing at your site. Readers on Medium can still read it; search engines are told where the original lives.&lt;/p&gt;&#10;&lt;p&gt;For new writing, reverse the flow. Publish on your own site first, then use Medium&amp;rsquo;s &lt;strong&gt;Import a story&lt;/strong&gt; feature, which copies the post into Medium and sets the canonical link to your original automatically. Your site stays the source; Medium becomes a distribution channel, which is what it is best at.&lt;/p&gt;&#10;&lt;p&gt;It is also worth adding a line at the end of each Medium story – &amp;ldquo;This post lives at yourname.com&amp;rdquo; – so human readers find their way home too.&lt;/p&gt;&#10;&lt;h2 id="step-7-tell-people"&gt;Step 7: Tell people&lt;/h2&gt;&#10;&lt;p&gt;Update your Medium bio to point at your site. Update your social profiles. If you had an email list, send one message explaining where to find you. Then write something new on the new site, because an archive with no fresh posts gives nobody a reason to visit.&lt;/p&gt;&#10;&lt;h2 id="doing-the-move-with-selfish"&gt;Doing the move with Selfish&lt;/h2&gt;&#10;&lt;p&gt;Selfish has no Medium importer. Posts move the way Step 4 describes: open the exported HTML, paste the text into the composer, attach the images and set the date. Once they are in, Selfish generates your site with canonical links, an RSS feed and a sitemap, and publishes it to your own server or host. It is &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt; as a one-time purchase, at a £3.99 introductory price, rising to £9.99 in December; the &lt;a href="https://selfpubli.sh/guide/"&gt;user guide&lt;/a&gt; covers writing and publishing, and &lt;a href="https://selfpubli.sh/blog/selfish-vs-medium/"&gt;Selfish vs Medium&lt;/a&gt; is the side-by-side.&lt;/p&gt;&#10;</content:encoded></item><item><title>Selfish vs Substack: a newsletter platform or a site you own</title><link>https://selfpubli.sh/blog/selfish-vs-substack/</link><pubDate>Tue, 25 Aug 2026 10:40:00 +0100</pubDate><guid>https://selfpubli.sh/blog/selfish-vs-substack/</guid><description>Selfish and Substack compared honestly: email, paid subscriptions, fees, custom domains, discovery and export. Plus when Substack is simply the right tool.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Here&amp;rsquo;s the honest answer. If you want to send a newsletter, and especially if you want readers to pay for it, use Substack. Selfish doesn&amp;rsquo;t send email and has no payment features. If what you want is a website, meaning a blog on your own domain made of plain files on hosting you control, Selfish is the better fit. Substack is a newsletter business in a box that also puts your posts on the web. Selfish is a publishing tool that puts your posts on the web and stops there. They overlap less than the &amp;ldquo;Substack alternative&amp;rdquo; framing suggests.&lt;/p&gt;&#10;&lt;h2 id="at-a-glance"&gt;At a glance&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Selfish&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Substack&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ownership&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;You own the files and choose the host&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Substack hosts your publication. You can export your posts and list&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cost&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;£3.99 once for the app, introductory — £9.99 from December. Optional premium themes at £1.99 each. You pay for your own hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Free to publish. If you charge, 10% of each transaction plus Stripe fees, at the time of writing&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where content lives&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;On your device (optional iCloud sync), published to your server&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;On Substack&amp;rsquo;s servers&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Custom domain&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Whatever domain you point at your own hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;One-time $50 fee at the time of writing. Must be a subdomain such as &lt;code&gt;www&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Email/newsletter&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None. Selfish doesn&amp;rsquo;t send email. It publishes RSS and JSON feeds&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Core feature. Every post can go out as an email&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Monetisation&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Paid subscriptions through Stripe&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Audience/discovery&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Substack network, Recommendations, the Substack app, Notes&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Editing&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Native app for iPhone, iPad and Mac, with live preview&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Web editor and mobile apps&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Output&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A complete static site: HTML, sitemap, RSS and JSON feeds&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Pages and emails on Substack&amp;rsquo;s platform&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Lock-in/export&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The published site is standard HTML with no Selfish code in it&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Export includes posts, subscriber list and stats. Newsletters are sent from a substack.com address&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="where-substack-genuinely-wins"&gt;Where Substack genuinely wins&lt;/h2&gt;&#10;&lt;h3 id="email-is-the-product"&gt;Email is the product&lt;/h3&gt;&#10;&lt;p&gt;The biggest difference comes first. &lt;strong&gt;Selfish does not send email newsletters.&lt;/strong&gt; It has no subscriber list, no mailing and no inbox delivery. Substack is built around exactly those things. You write a post and it lands in your subscribers&amp;rsquo; inboxes as well as on the web. For a lot of writers, email is the only channel that reliably reaches people, so this matters.&lt;/p&gt;&#10;&lt;p&gt;A Selfish site does publish an RSS feed, and some email services can turn a feed into a newsletter automatically. But then you&amp;rsquo;re running two tools and managing a list yourself. Substack handles all of it for you.&lt;/p&gt;&#10;&lt;h3 id="payments-are-built-in"&gt;Payments are built in&lt;/h3&gt;&#10;&lt;p&gt;Substack lets you switch on paid subscriptions and connect Stripe, and readers can then pay monthly or annually. You don&amp;rsquo;t have to build anything. Selfish has no payment or subscription features of any kind.&lt;/p&gt;&#10;&lt;p&gt;Here&amp;rsquo;s what that convenience costs, taken from Substack&amp;rsquo;s help centre at the time of writing:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Substack:&lt;/strong&gt; 10% of each transaction.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Stripe, cards:&lt;/strong&gt; 2.9% + $0.30 per transaction.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Stripe Billing:&lt;/strong&gt; 0.7% on recurring payments.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;On a $10 monthly subscription that works out as roughly $1.00 to Substack, about $0.59 in card fees and $0.07 in billing fees. You keep a little over $8.30. Stripe&amp;rsquo;s fees vary by country and payment method, so check your own Stripe dashboard for the real figures. Publishing itself is free however many subscribers you have. Apart from the optional custom domain fee, Substack only earns when you do.&lt;/p&gt;&#10;&lt;h3 id="the-network"&gt;The network&lt;/h3&gt;&#10;&lt;p&gt;This is Substack&amp;rsquo;s quiet advantage. Its Recommendations feature lets writers suggest each other&amp;rsquo;s publications. New subscribers are shown those suggestions right after they sign up, and Substack&amp;rsquo;s dashboard shows how many subscriptions each recommendation brought in. Add the Substack reader apps, Notes and the network&amp;rsquo;s search and leaderboards, and a new publication has ways to be found that a standalone site simply doesn&amp;rsquo;t. A Selfish site has no built-in audience or discovery.&lt;/p&gt;&#10;&lt;h3 id="community-features"&gt;Community features&lt;/h3&gt;&#10;&lt;p&gt;Substack has threaded comments, subscriber chat, direct messages, podcast hosting and video. Selfish has none of these, and no comments either. If you want conversation to happen where you publish, Substack gives you that from the start.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-wins"&gt;Where Selfish wins&lt;/h2&gt;&#10;&lt;h3 id="its-a-website-first"&gt;It&amp;rsquo;s a website first&lt;/h3&gt;&#10;&lt;p&gt;A Substack publication is a newsletter with a web archive. A Selfish site is a website. You get posts and standalone pages, categories and tags with their own archive pages, and a choice of themes. Each theme is a single self-contained CSS file with automatic dark mode. The output is a complete static site with a sitemap, feeds and canonical links. That shape suits a blog, a portfolio or a project site better than an inbox-first product does.&lt;/p&gt;&#10;&lt;h3 id="your-domain-your-root"&gt;Your domain, your root&lt;/h3&gt;&#10;&lt;p&gt;Substack&amp;rsquo;s custom domains cost a one-time fee, and they must use a subdomain such as &lt;code&gt;www&lt;/code&gt;. You can redirect the root domain, but the publication lives on the subdomain. Substack also sends your emails from a substack.com address, whatever domain you use. With Selfish there&amp;rsquo;s no platform in the way. Your domain points at your hosting, and your site sits at whatever address you configure.&lt;/p&gt;&#10;&lt;h3 id="no-platform-code-on-the-page"&gt;No platform code on the page&lt;/h3&gt;&#10;&lt;p&gt;A Selfish site carries no Selfish code, no tracking and no analytics, and its themes phone nothing home. Readers get HTML and CSS. On Substack the page belongs to Substack&amp;rsquo;s platform and comes wrapped in Substack&amp;rsquo;s own interface. That&amp;rsquo;s reasonable for them, but it isn&amp;rsquo;t your page.&lt;/p&gt;&#10;&lt;h3 id="nobody-elses-terms"&gt;Nobody else&amp;rsquo;s terms&lt;/h3&gt;&#10;&lt;p&gt;Your drafts live on your device, optionally synced through your own iCloud account. Selfish has no account and no servers holding your writing. The published site sits on hosting you pay for. No change of platform policy, pricing or ownership can take it down.&lt;/p&gt;&#10;&lt;h2 id="exporting-from-substack"&gt;Exporting from Substack&lt;/h2&gt;&#10;&lt;p&gt;Substack is better about exports than its reputation suggests. In your publication&amp;rsquo;s &lt;strong&gt;Settings&lt;/strong&gt;, open &lt;strong&gt;Exports&lt;/strong&gt; and choose &lt;strong&gt;Create new export&lt;/strong&gt;. Substack builds a .zip with your posts, subscriber list and related statistics, and emails you when it&amp;rsquo;s ready. You can also export just the subscriber list as a CSV from the Subscribers page.&lt;/p&gt;&#10;&lt;p&gt;The subscriber list is the valuable part. Keep a recent copy even if you never plan to leave. Just remember that Selfish doesn&amp;rsquo;t import Substack exports, and it can&amp;rsquo;t do anything with an email list, because it doesn&amp;rsquo;t send email.&lt;/p&gt;&#10;&lt;h2 id="the-combination-some-writers-use"&gt;The combination some writers use&lt;/h2&gt;&#10;&lt;p&gt;Plenty of writers don&amp;rsquo;t choose. They keep a newsletter on Substack or another email service for the inbox, and run their own site for the permanent, linkable, searchable version of their work. The website is the canonical home and the newsletter is how it&amp;rsquo;s delivered. If email matters to you and so does ownership, that split is often more sensible than forcing one tool to do both jobs. We cover the wider options in &lt;a href="https://selfpubli.sh/blog/substack-alternatives-you-own/"&gt;Substack alternatives that you actually own&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="choose-substack-if"&gt;Choose Substack if…&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Email is how you want to reach readers.&lt;/li&gt;&#10;&lt;li&gt;You want paid subscriptions without building payments, and 10% plus Stripe fees is a price you&amp;rsquo;re happy with.&lt;/li&gt;&#10;&lt;li&gt;You want to be discovered through Recommendations and Substack&amp;rsquo;s app and network.&lt;/li&gt;&#10;&lt;li&gt;You want comments, chat, podcasts or video in the same place.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="choose-selfish-if"&gt;Choose Selfish if…&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You want a website on your own domain and hosting, not a newsletter with an archive.&lt;/li&gt;&#10;&lt;li&gt;You don&amp;rsquo;t need to send email, or you&amp;rsquo;re happy to handle email separately.&lt;/li&gt;&#10;&lt;li&gt;You want clean static HTML with no tracking, no platform prompts and no account.&lt;/li&gt;&#10;&lt;li&gt;You write on an iPhone, iPad or Mac and want to publish straight to SFTP, S3-compatible storage, Netlify, Cloudflare Pages or GitHub Pages.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;Selfish is &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt; as one app for iPhone, iPad and Mac, for a one-time £3.99 introductory price that rises to £9.99 in December. It won&amp;rsquo;t replace a newsletter platform, and it isn&amp;rsquo;t trying to. If you want a quiet, durable website that&amp;rsquo;s entirely yours, the &lt;a href="https://selfpubli.sh/guide/"&gt;user guide&lt;/a&gt; shows how it works and the &lt;a href="https://selfpubli.sh/themes/"&gt;themes page&lt;/a&gt; shows what your site could look like.&lt;/p&gt;&#10;</content:encoded></item><item><title>Substack alternatives that you actually own</title><link>https://selfpubli.sh/blog/substack-alternatives-you-own/</link><pubDate>Wed, 19 Aug 2026 09:25:00 +0100</pubDate><guid>https://selfpubli.sh/blog/substack-alternatives-you-own/</guid><description>What owning a newsletter really means – domain, export, subscriber list, URLs – and how Ghost, Buttondown, beehiiv, Kit and a plain static site compare.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Most &amp;ldquo;Substack alternatives&amp;rdquo; lists compare features. That misses the reason people leave. They leave because they want to own the thing they have built, and &amp;ldquo;own&amp;rdquo; is a slippery word. Every platform will tell you that you own your content. Fewer will tell you what happens to your readers, your links and your income on the day you walk away.&lt;/p&gt;&#10;&lt;p&gt;So before the alternatives, a working definition.&lt;/p&gt;&#10;&lt;h2 id="what-own-actually-means"&gt;What &amp;ldquo;own&amp;rdquo; actually means&lt;/h2&gt;&#10;&lt;p&gt;Ownership is not a feeling. It is four things you can check.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The domain.&lt;/strong&gt; If your writing lives at &lt;code&gt;yourname.substack.com&lt;/code&gt;, every link anyone has ever shared points at someone else&amp;rsquo;s address. If it lives at &lt;code&gt;yourname.com&lt;/code&gt;, the links are yours, and you can point that domain anywhere you like. This is the single most important item on the list, and it is the cheapest: a domain costs a few pounds a year.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The content export.&lt;/strong&gt; Can you get every post out, in a format something else can read, without asking permission? HTML or Markdown is good. A PDF of each post is not an export.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The subscriber list.&lt;/strong&gt; A CSV of email addresses you can take to another tool. Paid subscribers are harder: the billing relationship usually lives in Stripe, and whether it can move depends on the platform.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The URLs.&lt;/strong&gt; When you move, do the old links keep working? That needs a domain you control and a host that lets you set redirects. Without both, every inbound link you have earned eventually breaks.&lt;/p&gt;&#10;&lt;p&gt;Substack, to be fair, does better on this than its reputation suggests. At the time of writing it is free to start and takes 10% of paid subscription revenue, on top of Stripe&amp;rsquo;s processing fees. It lets you connect your own domain for a one-off $50 fee, and its export gives you your posts (as HTML, with a CSV index) and your subscriber list. What you cannot take with you is the network: recommendations, app followers and the discovery that Substack itself provides. That network is the genuine reason to stay, and it is worth being honest with yourself about how much of your readership came from it.&lt;/p&gt;&#10;&lt;h2 id="ghost"&gt;Ghost&lt;/h2&gt;&#10;&lt;p&gt;Ghost is the closest like-for-like replacement: a publishing platform with memberships, paid subscriptions and newsletters built in. It is open source under the MIT licence, which gives you two ways to run it.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Ghost(Pro)&lt;/strong&gt; is the hosted service run by the Ghost Foundation. At the time of writing, plans start at $18 a month billed yearly for the Starter tier, which does not include paid subscriptions; the Publisher tier, which does, is $29 a month billed yearly for up to 1,000 members. Ghost takes 0% of your subscription revenue on the tiers that support it; you pay Stripe&amp;rsquo;s fees and nothing else. Custom domains are included.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Self-hosted Ghost&lt;/strong&gt; costs nothing in licence fees, but it is a real server to run: Ubuntu, Node.js, MySQL and a reverse proxy, plus a Mailgun account, because Mailgun is the only bulk email service Ghost supports for sending newsletters. If you already run servers, this is the most complete form of ownership on this list. If you don&amp;rsquo;t, the maintenance is a job you are signing up for.&lt;/p&gt;&#10;&lt;p&gt;Ghost scores well on all four tests: your domain, a JSON content export, a members CSV export, and a redirects file you control.&lt;/p&gt;&#10;&lt;h2 id="buttondown"&gt;Buttondown&lt;/h2&gt;&#10;&lt;p&gt;Buttondown is a small, independent newsletter tool that writes in Markdown and stays out of the way. At the time of writing it is free for up to 100 subscribers, then priced by the number of subscribers you actually send to, with optional features sold as add-ons. Paid subscriptions are one of those add-ons, and Buttondown takes no cut of the revenue.&lt;/p&gt;&#10;&lt;p&gt;It hosts a web archive of your issues, and serving that archive from your own domain is an add-on too. That makes Buttondown a very good fit for the &amp;ldquo;own site plus separate newsletter&amp;rdquo; pattern described below: let Buttondown do the email, and keep your canonical writing on your own site.&lt;/p&gt;&#10;&lt;h2 id="beehiiv"&gt;beehiiv&lt;/h2&gt;&#10;&lt;p&gt;beehiiv is built for growth: referral programmes, a recommendation network, ad placements and detailed analytics. At the time of writing its free Launch plan covers up to 2,500 subscribers and includes a custom domain. Paid subscriptions require a paid plan (Scale, at $43 a month, is the entry point), and on those plans beehiiv advertises a 0% take rate on subscription revenue.&lt;/p&gt;&#10;&lt;p&gt;It is a strong choice if growing a list is the point. It is less of a choice if the point is a quiet place to write, because much of what you are paying for is growth machinery.&lt;/p&gt;&#10;&lt;h2 id="kit"&gt;Kit&lt;/h2&gt;&#10;&lt;p&gt;Kit (formerly ConvertKit) is email marketing software for creators: automations, sequences, landing pages and digital product sales. At the time of writing its free plan covers up to 10,000 subscribers, with paid plans adding automations and paid newsletters. Kit charges a transaction fee on sales and subscriptions (3.5% plus 30 cents at the time of writing), so it is not a 0% platform.&lt;/p&gt;&#10;&lt;p&gt;Kit is the most &amp;ldquo;business&amp;rdquo; option here. It is excellent if your newsletter feeds a course or a product. It is heavy if all you want is to send your latest post to people who asked for it.&lt;/p&gt;&#10;&lt;h2 id="a-static-site-plus-a-separate-newsletter-tool"&gt;A static site plus a separate newsletter tool&lt;/h2&gt;&#10;&lt;p&gt;This is the unfashionable answer, and for many writers the best one.&lt;/p&gt;&#10;&lt;p&gt;Split the job in two. Your writing lives on a plain static website at your own domain: HTML files, an RSS feed, nothing to patch. Your email list lives in a newsletter tool – Buttondown, beehiiv, Kit, even self-hosted Ghost used purely for email. The site is the canonical home of every post. The newsletter points readers to it, or carries the full text with a link back.&lt;/p&gt;&#10;&lt;p&gt;What you get:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Every URL is yours&lt;/strong&gt;, on a domain you control, served by whichever host you pick this year.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;The archive outlives the newsletter.&lt;/strong&gt; If you change email tools, the posts do not move. Only the subscriber CSV does.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Your site costs little or nothing to host.&lt;/strong&gt; Static hosting on Netlify, Cloudflare Pages, GitHub Pages or an ordinary web server is cheap and very hard to break.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Your RSS feed can drive the email.&lt;/strong&gt; Several newsletter tools can turn a new item in your feed into an email – Buttondown offers RSS-to-email as an add-on, for example – so publishing on the site can trigger the send.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;What you give up is integration. Paywalled posts, member-only pages and &amp;ldquo;subscribe to read the rest&amp;rdquo; need a platform that controls both the site and the list. A static site cannot gate content by itself. If paid, members-only writing is your model, Ghost or Substack will serve you better, and that is fine.&lt;/p&gt;&#10;&lt;h2 id="a-quick-comparison"&gt;A quick comparison&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Own domain&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Free to start&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Platform&amp;rsquo;s cut of paid subs (at the time of writing)&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Substack&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yes ($50 one-off)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;10%, plus Stripe fees&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ghost(Pro)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;No&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;0% on Publisher and above, plus Stripe fees&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Self-hosted Ghost&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Software is free; server and Mailgun are not&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;0%, plus Stripe fees&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Buttondown&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Archive on your domain is an add-on&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Up to 100 subscribers&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;0% (paid subscriptions are an add-on)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;beehiiv&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Up to 2,500 subscribers&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;0% on paid plans&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Kit&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;For landing pages&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Up to 10,000 subscribers&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;3.5% + 30c per transaction&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Static site + newsletter tool&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yes&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hosting can be free&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Depends on the newsletter tool&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;Check each provider&amp;rsquo;s current terms before you commit. Pricing in this market changes often.&lt;/p&gt;&#10;&lt;h2 id="how-to-choose"&gt;How to choose&lt;/h2&gt;&#10;&lt;p&gt;If you need paid subscriptions and do not want to run a server, Ghost(Pro) is the cleanest move away from Substack. If you want the most control and don&amp;rsquo;t mind administration, self-host Ghost. If you mostly write in public and want email as a delivery channel, put the writing on your own static site and pair it with Buttondown or a similar tool. If growth is the whole game, beehiiv is built for it.&lt;/p&gt;&#10;&lt;p&gt;Whatever you pick, buy the domain first. It is the one decision that keeps every other decision reversible. We go into the hosting side in more detail in &lt;a href="https://selfpubli.sh/blog/self-host-a-personal-blog/"&gt;the best way to self-host a personal blog&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;Selfish does not send email and has no subscriber list. It is the site half of &amp;ldquo;own site plus separate newsletter&amp;rdquo;: a native app for iPhone, iPad and Mac – £3.99 once – that turns your posts into a complete static site with an RSS feed and publishes it to your own server or host. It is out now &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt;, at a £3.99 introductory price, rising to £9.99 in December; the &lt;a href="https://selfpubli.sh/docs/"&gt;publishing guide&lt;/a&gt; shows the hosts it supports, and there is a head-to-head in &lt;a href="https://selfpubli.sh/blog/selfish-vs-substack/"&gt;Selfish vs Substack&lt;/a&gt;.&lt;/p&gt;&#10;</content:encoded></item><item><title>Selfish vs WordPress.com: hosted platform or static site you own</title><link>https://selfpubli.sh/blog/selfish-vs-wordpress-com/</link><pubDate>Tue, 11 Aug 2026 14:10:00 +0100</pubDate><guid>https://selfpubli.sh/blog/selfish-vs-wordpress-com/</guid><description>Selfish and WordPress.com compared: plans, plugins, comments, newsletters, custom domains, payment fees and export, and where WordPress.com is the better pick.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Here&amp;rsquo;s the short answer. WordPress.com does far more than Selfish does. It has comments, newsletters, payments, a plugin catalogue and a large ecosystem. The price of all that is a plan, a dashboard and a site that runs on someone else&amp;rsquo;s platform. Selfish does one thing: it turns what you write on your iPhone, iPad or Mac into a plain static site and publishes it to hosting you control. If you need features, WordPress.com wins. If you want a small, fast site that&amp;rsquo;s simply yours, Selfish is the better fit.&lt;/p&gt;&#10;&lt;p&gt;First, a distinction worth getting right. &lt;strong&gt;WordPress.com&lt;/strong&gt; is a hosted service. You sign up, pick a plan, and the site runs on its infrastructure. &lt;strong&gt;WordPress.org&lt;/strong&gt; is where the free, open-source WordPress software lives, which you install and run on your own server. This post compares Selfish with WordPress.com. Self-hosted WordPress is a different trade-off, which we cover in &lt;a href="https://selfpubli.sh/blog/wordpress-vs-static-site/"&gt;WordPress vs a static site&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="at-a-glance"&gt;At a glance&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Selfish&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;WordPress.com&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ownership&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;You own the files and choose the host&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;You own your content. The site runs on WordPress.com&amp;rsquo;s platform&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cost&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;£3.99 once for the app, introductory — £9.99 from December. Optional premium themes at £1.99 each. You pay for your own hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Free plan with ads. Paid plans are Personal, Premium, Business and Commerce&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where content lives&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;On your device (optional iCloud sync), published to your server&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;In WordPress.com&amp;rsquo;s database&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Custom domain&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Whatever domain you point at your own hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Paid plans only. Annual plans include a domain free for the first year&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Email/newsletter&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None. Selfish doesn&amp;rsquo;t send email. It publishes RSS and JSON feeds&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Built in. New posts can be emailed to subscribers&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Monetisation&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Paid newsletters and payments via Stripe, with a fee that depends on your plan&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Audience/discovery&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The WordPress.com Reader, follows and likes&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Editing&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Native app for iPhone, iPad and Mac, with live preview&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The WordPress block editor in the browser&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Output&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A complete static site: HTML, sitemap, RSS and JSON feeds&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A dynamic WordPress site&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Lock-in/export&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The published site is standard HTML with no Selfish code in it&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;XML (WXR) export of posts, pages, comments, categories and tags. Media exported separately&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="where-wordpresscom-genuinely-wins"&gt;Where WordPress.com genuinely wins&lt;/h2&gt;&#10;&lt;h3 id="plugins-and-the-ecosystem"&gt;Plugins and the ecosystem&lt;/h3&gt;&#10;&lt;p&gt;This is the headline. According to WordPress.com&amp;rsquo;s support pages at the time of writing, you can install plugins on every paid plan: Personal, Premium, Business and Commerce. The free plan can&amp;rsquo;t. The pricing page points to a catalogue of over 60,000 plugins. Forms, memberships, shops, courses, booking, SEO tooling: someone has almost certainly built what you need.&lt;/p&gt;&#10;&lt;p&gt;Selfish has no plugin system. You get themes, header and footer snippets, and nothing more. For a blog that&amp;rsquo;s usually enough. If your site has to &lt;em&gt;do&lt;/em&gt; things, it isn&amp;rsquo;t.&lt;/p&gt;&#10;&lt;h3 id="comments-and-community"&gt;Comments and community&lt;/h3&gt;&#10;&lt;p&gt;WordPress.com sites come with comments, likes and follows. The WordPress.com Reader pulls public WordPress.com sites and Jetpack-connected WordPress sites into one feed, where readers can discover and follow them. Selfish has no comments and no built-in discovery. Readers find a Selfish site through search, links and RSS.&lt;/p&gt;&#10;&lt;h3 id="newsletters-and-payments"&gt;Newsletters and payments&lt;/h3&gt;&#10;&lt;p&gt;Every WordPress.com site includes a newsletter feature. Subscribers can get each new post by email, and you can add paid tiers through Stripe. WordPress.com&amp;rsquo;s support guide lists the payment fee by plan. At the time of writing it&amp;rsquo;s 10% on Free, 8% on Personal, 4% on Premium, 2% on Business and 0% on Commerce.&lt;/p&gt;&#10;&lt;p&gt;Stripe also takes 2.9% + $0.30 per payment in the US, and the fee differs elsewhere. If your plan lapses, WordPress.com says the fee goes back to 10%. It&amp;rsquo;s a flexible setup, because you can trade a higher plan price for a lower cut. Selfish sends no email and handles no payments.&lt;/p&gt;&#10;&lt;h3 id="growing-into-more"&gt;Growing into more&lt;/h3&gt;&#10;&lt;p&gt;On the Business plan and above, WordPress.com lists SFTP and SSH access, WP-CLI, Git commands and GitHub deployments, along with real-time backups. A site can start as a blog and grow into a shop or a membership site without moving house. Selfish is deliberately smaller than that.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-wins"&gt;Where Selfish wins&lt;/h2&gt;&#10;&lt;h3 id="nothing-to-maintain"&gt;Nothing to maintain&lt;/h3&gt;&#10;&lt;p&gt;A WordPress site is software. It has a database, a PHP runtime, a theme and possibly dozens of plugins, all of which change over time. WordPress.com handles much of the maintenance for you, but the moving parts are still there. A Selfish site is a folder of HTML, CSS and images. It has nothing to patch, no admin login to protect on the published site, and no database to back up at the server end.&lt;/p&gt;&#10;&lt;h3 id="its-fast-because-its-static"&gt;It&amp;rsquo;s fast because it&amp;rsquo;s static&lt;/h3&gt;&#10;&lt;p&gt;Every page on a Selfish site is pre-built. The themes are single CSS files with automatic dark mode and no web fonts, and they send nothing back to anyone. Pages load quickly on any cheap host because the server only hands over files.&lt;/p&gt;&#10;&lt;h3 id="no-ads-no-plan-to-keep-up"&gt;No ads, no plan to keep up&lt;/h3&gt;&#10;&lt;p&gt;The free WordPress.com plan shows WordPress.com&amp;rsquo;s ads to your visitors and doesn&amp;rsquo;t let you connect your own domain. To remove the ads and use your domain, you need a paid plan. At the time of writing, the UK pricing page shows Personal starting at £3 a month billed yearly and renewing at £5 a month. Prices vary by region and change with promotions. Selfish itself is a one-time £3.99 — an introductory price, rising to £9.99 in December — with no subscription and no per-site fee. You pay only for the hosting you choose, and your site carries no ads unless you add them.&lt;/p&gt;&#10;&lt;h3 id="writing-in-a-native-app"&gt;Writing in a native app&lt;/h3&gt;&#10;&lt;p&gt;WordPress&amp;rsquo;s block editor is powerful, and complicated with it. Selfish&amp;rsquo;s composer is plain text with light formatting: bold, italic, links, H2 and H3 headings, and quotes. Under the hood that&amp;rsquo;s stored as a small Markdown subset. You get autosave, drafts, and a live preview that matches the published page exactly. Photos are optimised automatically. It&amp;rsquo;s a smaller tool, and that&amp;rsquo;s the point.&lt;/p&gt;&#10;&lt;h3 id="your-hosting-your-choice"&gt;Your hosting, your choice&lt;/h3&gt;&#10;&lt;p&gt;Selfish publishes over SFTP or to S3-compatible storage, Netlify, Cloudflare Pages or GitHub Pages. Credentials stay in Apple&amp;rsquo;s Keychain. Your content lives on your device, optionally synced through your own iCloud account. You never need a Selfish account.&lt;/p&gt;&#10;&lt;h2 id="exporting-from-wordpresscom"&gt;Exporting from WordPress.com&lt;/h2&gt;&#10;&lt;p&gt;WordPress.com&amp;rsquo;s export gives you an XML file, also called a WXR file. It contains your posts, pages, comments, categories and tags, plus &lt;em&gt;links&lt;/em&gt; to your media rather than the media itself. You can download the media library separately. The export doesn&amp;rsquo;t include your theme design, customisations or plugins. The WXR format is widely supported, so moving to self-hosted WordPress or another platform that reads it is straightforward. Selfish doesn&amp;rsquo;t import WordPress exports, so moving to Selfish means bringing posts across by hand.&lt;/p&gt;&#10;&lt;h2 id="choose-wordpresscom-if"&gt;Choose WordPress.com if…&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You need plugins: shops, forms, memberships, bookings.&lt;/li&gt;&#10;&lt;li&gt;You want comments and a community around your posts.&lt;/li&gt;&#10;&lt;li&gt;You want newsletters and paid subscriptions on the same site.&lt;/li&gt;&#10;&lt;li&gt;You&amp;rsquo;d rather have a managed dashboard than look after hosting yourself, and a plan price is fine with you.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="choose-selfish-if"&gt;Choose Selfish if…&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You want a blog or personal site, not an application.&lt;/li&gt;&#10;&lt;li&gt;You want static HTML on hosting you choose, with no database and no plugins to maintain.&lt;/li&gt;&#10;&lt;li&gt;You don&amp;rsquo;t need comments, email or payments, or you&amp;rsquo;re happy to handle them elsewhere.&lt;/li&gt;&#10;&lt;li&gt;You write on an iPhone, iPad or Mac and want a native app that publishes straight to your own host.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;Selfish is &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt; as one app for iPhone, iPad and Mac, for a one-time £3.99 introductory price that rises to £9.99 in December. It won&amp;rsquo;t replace WordPress.com for anyone who needs its plugins or community features. If a quiet, fast site that&amp;rsquo;s entirely yours sounds better, the &lt;a href="https://selfpubli.sh/docs/"&gt;publishing docs&lt;/a&gt; explain each hosting route and the &lt;a href="https://selfpubli.sh/themes/"&gt;themes page&lt;/a&gt; shows the look.&lt;/p&gt;&#10;</content:encoded></item><item><title>WordPress vs a static site for a personal blog</title><link>https://selfpubli.sh/blog/wordpress-vs-static-site/</link><pubDate>Thu, 06 Aug 2026 10:30:00 +0100</pubDate><guid>https://selfpubli.sh/blog/wordpress-vs-static-site/</guid><description>An honest comparison of WordPress and a static site for a personal blog: security, plugins, comments, forms, search, cost, speed and backups.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;WordPress runs a vast share of the web, and for good reasons. It is also, for a lot of personal blogs, more machine than the job needs. A static site – plain HTML files generated once and served as they are – sits at the other end of the scale.&lt;/p&gt;&#10;&lt;p&gt;This is a comparison for one use case only: a personal blog, written mostly by one person. For a newsroom, a shop or a membership site the answer is different, and usually it is WordPress or something like it.&lt;/p&gt;&#10;&lt;h2 id="the-fundamental-difference"&gt;The fundamental difference&lt;/h2&gt;&#10;&lt;p&gt;A self-hosted WordPress site is an application. Every page view can run PHP code, query a MySQL or MariaDB database and assemble the page on the fly (caching softens this, but the application is always there). Your writing lives in that database.&lt;/p&gt;&#10;&lt;p&gt;A static site is a folder of files. Something – a generator on your computer, a build service, an app – turns your posts into finished HTML, CSS and images once, and a web server hands those files out unchanged. Your writing lives wherever the generator keeps its source.&lt;/p&gt;&#10;&lt;p&gt;Almost every trade-off below follows from that one difference.&lt;/p&gt;&#10;&lt;h2 id="security-and-patching"&gt;Security and patching&lt;/h2&gt;&#10;&lt;p&gt;WordPress is well maintained and its core team takes security seriously. Since WordPress 3.7, minor releases – which carry most security fixes – install themselves automatically, and new installs since 5.6 auto-update major releases too. Since 5.5 you can switch on automatic updates for plugins and themes, one by one.&lt;/p&gt;&#10;&lt;p&gt;The exposure comes from what you add. Each plugin and theme is code from a different author, running on your server with access to your database. Most are fine. Some are abandoned. The login page is a permanent target for password-guessing bots. Running WordPress safely means staying on top of updates, pruning plugins you don&amp;rsquo;t use and keeping good backups, indefinitely.&lt;/p&gt;&#10;&lt;p&gt;A static site has almost nothing to attack. There is no login page on the public server, no database, no code running per request. The remaining risk is the server or host itself, and the credentials you use to upload. For a site you might not touch for months, that difference is the main argument.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; static, clearly, for a solo blog.&lt;/p&gt;&#10;&lt;h2 id="plugins-and-features"&gt;Plugins and features&lt;/h2&gt;&#10;&lt;p&gt;This is where WordPress wins, and it is not close. The plugin directory covers almost anything you can imagine: SEO tools, galleries, events, bookings, shops, memberships, translations. You can add a feature to a live site in a few clicks without writing code.&lt;/p&gt;&#10;&lt;p&gt;A static site can only do what its generator, its theme and client-side scripts can do. That covers the essentials of a blog – posts, pages, tags, feeds, sitemaps – very well. It does not cover &amp;ldquo;add a booking calendar this afternoon&amp;rdquo;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; WordPress.&lt;/p&gt;&#10;&lt;h2 id="comments"&gt;Comments&lt;/h2&gt;&#10;&lt;p&gt;WordPress has comments built in, with moderation, threading and email notifications, plus Akismet for spam. It works on day one.&lt;/p&gt;&#10;&lt;p&gt;A static site has no server-side code, so comments have to come from somewhere else. The honest options:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;A third-party embed.&lt;/strong&gt; giscus, for example, is free, open source and stores comments in GitHub Discussions – which means commenters need a GitHub account. Fine for a developer blog, a barrier for most others.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;A self-hosted comment server&lt;/strong&gt; such as Remark42. Good, private, and one more service for you to run and patch – which gives back part of the security advantage.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;No comments.&lt;/strong&gt; Many personal blogs now link to an email address or a social post instead. Replies arrive in private, the spam problem disappears and the page stays static.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; WordPress, if comments matter to you. If they don&amp;rsquo;t, this stops being a factor.&lt;/p&gt;&#10;&lt;h2 id="forms"&gt;Forms&lt;/h2&gt;&#10;&lt;p&gt;WordPress has several mature form plugins, and form submissions go straight into your database or inbox.&lt;/p&gt;&#10;&lt;p&gt;A static site needs a form backend. Some hosts provide one: Netlify Forms detects a form marked with &lt;code&gt;data-netlify=&amp;quot;true&amp;quot;&lt;/code&gt; at deploy time and collects submissions for you. Otherwise a service such as Formspree receives the submission and emails it on. Both work well for a contact form. Both mean someone else handles your readers&amp;rsquo; messages, and free tiers have limits, so check them.&lt;/p&gt;&#10;&lt;p&gt;The simplest contact form is still a &lt;code&gt;mailto:&lt;/code&gt; link.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; WordPress is more flexible; a static site is fine for a single contact form.&lt;/p&gt;&#10;&lt;h2 id="search"&gt;Search&lt;/h2&gt;&#10;&lt;p&gt;WordPress has search out of the box, querying the database.&lt;/p&gt;&#10;&lt;p&gt;Static sites used to be weak here. Not any more: Pagefind builds a search index from your finished HTML and runs entirely in the reader&amp;rsquo;s browser, with no server. For a blog of a few hundred posts it is fast and good. Some generators do not include it by default, though, and adding it may mean a build step.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; roughly even, with a little more setup on the static side.&lt;/p&gt;&#10;&lt;h2 id="cost"&gt;Cost&lt;/h2&gt;&#10;&lt;p&gt;WordPress needs hosting that runs PHP and a database. Cheap shared hosting can do it; decent managed WordPress hosting, which handles updates and caching for you, costs more, and you will want backups on top. Premium themes and plugins often carry yearly licences.&lt;/p&gt;&#10;&lt;p&gt;A static site can be hosted on almost anything: a basic web server you reach over SFTP, object storage such as S3 or Cloudflare R2, or the free tiers of Netlify, Cloudflare Pages and GitHub Pages. For a personal blog the hosting bill is frequently zero, and the domain name is the only fixed cost.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; static.&lt;/p&gt;&#10;&lt;h2 id="speed"&gt;Speed&lt;/h2&gt;&#10;&lt;p&gt;A well-configured WordPress site with page caching and a CDN can be very fast. Many are not well configured, and a heavy theme with a dozen plugins can load a lot of scripts on every page.&lt;/p&gt;&#10;&lt;p&gt;A static page is already finished when the request arrives. It is trivially cacheable and, with a light theme, small. It is hard to make a static blog slow.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; static by default; WordPress can match it with effort.&lt;/p&gt;&#10;&lt;h2 id="backups-and-portability"&gt;Backups and portability&lt;/h2&gt;&#10;&lt;p&gt;Backing up WordPress means backing up two things – the database and the &lt;code&gt;wp-content&lt;/code&gt; folder – and testing that you can restore them. Plugins such as UpdraftPlus automate this. It is not difficult, but it has to be done.&lt;/p&gt;&#10;&lt;p&gt;A static site&amp;rsquo;s output is a folder of files. Copy it anywhere and you have a working backup of the published site. The source of your posts needs backing up too, wherever your generator keeps it, but there is no database to dump and nothing to reassemble. Moving host means uploading the same files somewhere else.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; static.&lt;/p&gt;&#10;&lt;h2 id="editing-and-multiple-authors"&gt;Editing and multiple authors&lt;/h2&gt;&#10;&lt;p&gt;WordPress has a proper browser-based editor, user accounts and roles (administrator, editor, author, contributor), drafts, revisions and scheduling. A non-technical co-writer can log in from any computer and contribute. That is a real strength.&lt;/p&gt;&#10;&lt;p&gt;Most static generators assume one person with a text editor and a command line, and &amp;ldquo;multi-author&amp;rdquo; usually means &amp;ldquo;everyone uses Git&amp;rdquo;. Tools exist to put a friendlier editor on top, but they add moving parts.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; WordPress, especially for teams or non-technical writers.&lt;/p&gt;&#10;&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;WordPress&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Static site&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Security upkeep&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ongoing&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Minimal&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Plugins and features&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Vast&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;What the generator provides&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Comments&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Third-party or none&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Forms&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Plugins&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Host feature or third-party service&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Search&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Client-side (e.g. Pagefind)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hosting cost&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;PHP hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Often free&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Speed&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Good with tuning&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Fast by default&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Backups&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Database + files&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Copy a folder&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Multi-author editing&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Excellent&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Limited&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;Choose WordPress if you need plugins, built-in comments or several non-technical authors. Choose a static site if it is your own writing, you want it fast and cheap, and you would rather not be on call for security updates. For more on the hosting side, see &lt;a href="https://selfpubli.sh/blog/how-to-host-a-static-blog-on-your-own-server/"&gt;how to host a static blog on your own server&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;The usual catch with static sites is the command line. Selfish is a native app for iPhone, iPad and Mac – £3.99 once, no subscription – that writes, builds and publishes a static site – over SFTP or to S3-compatible storage, Netlify, Cloudflare Pages or GitHub Pages – with no terminal involved. It does not do comments or forms. It is out now &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt;, at a £3.99 introductory price, rising to £9.99 in December; the &lt;a href="https://selfpubli.sh/docs/"&gt;publishing setup guide&lt;/a&gt; and &lt;a href="https://selfpubli.sh/blog/selfish-vs-wordpress-com/"&gt;Selfish vs WordPress.com&lt;/a&gt; have the detail.&lt;/p&gt;&#10;</content:encoded></item><item><title>Selfish vs Hugo and Jekyll: static sites, with or without code</title><link>https://selfpubli.sh/blog/selfish-vs-hugo-and-jekyll/</link><pubDate>Thu, 30 Jul 2026 09:05:00 +0100</pubDate><guid>https://selfpubli.sh/blog/selfish-vs-hugo-and-jekyll/</guid><description>Selfish, Hugo and Jekyll all publish static sites. An honest look at templating, speed, git workflows, portability and who should use which.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;The short answer: all three produce the same kind of thing, a folder of static HTML you can host anywhere. Hugo and Jekyll are developer tools. They give you templates, total control and a git-based workflow, and they expect a terminal and a text editor in return. Selfish is a native app for iPhone, iPad and Mac. It gives you a finished writing and publishing workflow and much less control over the machinery. If you enjoy building the site as much as writing on it, use Hugo or Jekyll. If you&amp;rsquo;d rather just write and publish, Selfish removes the toolchain.&lt;/p&gt;&#10;&lt;p&gt;For full disclosure, the site you&amp;rsquo;re reading is built with Hugo. It&amp;rsquo;s a marketing site with custom layouts, which is exactly the kind of job Hugo is good at.&lt;/p&gt;&#10;&lt;h2 id="at-a-glance"&gt;At a glance&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Selfish&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Hugo&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Jekyll&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ownership&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yours: files on your hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yours: files on your hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Yours: files on your hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cost&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;£3.99 once, introductory — £9.99 from December. Optional premium themes at £1.99 each&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Free, open source&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Free, open source&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Where content lives&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;In the app on your device (optional iCloud sync)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Markdown files in a folder, usually a git repo&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Markdown files in a folder, usually a git repo&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Custom domain&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Whatever domain you point at your hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Same&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Same&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Email/newsletter&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Monetisation&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None built in&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Audience/discovery&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Editing&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Native composer with toolbar and live preview&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Any text editor&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Any text editor&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Templating&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Choose a theme. Add header and footer snippets&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Go templates, fully customisable&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Liquid templates, fully customisable&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Output&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Static HTML, sitemap, RSS and JSON feeds&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Static site, whatever your templates produce&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Static site, whatever your templates produce&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Lock-in/export&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Standard HTML output. No Markdown file export&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Plain Markdown source files&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Plain Markdown source files&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;None of the three gives you an audience, email or payments. Those are platform features, and all three of these are tools.&lt;/p&gt;&#10;&lt;h2 id="where-hugo-and-jekyll-genuinely-win"&gt;Where Hugo and Jekyll genuinely win&lt;/h2&gt;&#10;&lt;h3 id="flexibility"&gt;Flexibility&lt;/h3&gt;&#10;&lt;p&gt;This is the big one. Hugo uses Go&amp;rsquo;s &lt;code&gt;html/template&lt;/code&gt; and &lt;code&gt;text/template&lt;/code&gt; packages. Jekyll uses Liquid. With either, you control every byte of the output. You can build custom page types, data-driven pages, landing pages, documentation, multilingual sites, or whatever structure your content needs. Hugo describes its taxonomy system as &amp;ldquo;powerful&amp;rdquo; and it is. Categories and tags are just the start.&lt;/p&gt;&#10;&lt;p&gt;Selfish offers a fixed set of choices. You get posts and pages, categories and tags, a theme, and custom header and footer snippets. The four free themes and three premium ones are each a single CSS file. A custom theme editor is something we&amp;rsquo;re considering, not something that exists. If you need a layout Selfish&amp;rsquo;s themes don&amp;rsquo;t offer, a static site generator is the right tool.&lt;/p&gt;&#10;&lt;h3 id="speed-at-scale"&gt;Speed at scale&lt;/h3&gt;&#10;&lt;p&gt;Hugo is written in Go, and its own documentation says it &amp;ldquo;renders a complete site in seconds, often less&amp;rdquo;. For large sites with thousands of pages that speed genuinely matters. Selfish is designed for personal sites and skips unchanged files when it uploads. Hugo is the one to reach for when a site gets big.&lt;/p&gt;&#10;&lt;h3 id="git-workflows"&gt;Git workflows&lt;/h3&gt;&#10;&lt;p&gt;With Hugo or Jekyll, your content is Markdown files in a repository. That gets you version history, branches, pull requests, collaborators, CI builds, and deploys triggered by a push. Jekyll has a special relationship with GitHub Pages. GitHub&amp;rsquo;s documentation describes it as having built-in support there. GitHub Pages can only build a limited set of Jekyll plugins itself, and GitHub now recommends GitHub Actions for anything beyond that.&lt;/p&gt;&#10;&lt;p&gt;Selfish can publish to GitHub Pages by committing the generated site into a repository. That repo holds the output, though, not an editable Markdown source tree. If your team reviews posts in pull requests, stick with a generator.&lt;/p&gt;&#10;&lt;h3 id="price"&gt;Price&lt;/h3&gt;&#10;&lt;p&gt;Hugo and Jekyll are free and open source. Selfish is a one-time £3.99 purchase — an introductory price that rises to £9.99 in December — plus optional premium themes. If you&amp;rsquo;re already comfortable in a terminal, the generators cost you nothing but time.&lt;/p&gt;&#10;&lt;h3 id="portability-of-source"&gt;Portability of source&lt;/h3&gt;&#10;&lt;p&gt;Your Hugo or Jekyll content is a folder of text files with front matter. Moving between generators is work, but the words themselves are never trapped. Selfish stores your writing as a small Markdown subset inside the app. The published output is standard HTML that belongs to you, but Selfish doesn&amp;rsquo;t currently export Markdown files. Folder export is on the list of things we&amp;rsquo;re considering. That&amp;rsquo;s a real difference, and you should weigh it.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-wins"&gt;Where Selfish wins&lt;/h2&gt;&#10;&lt;h3 id="no-toolchain"&gt;No toolchain&lt;/h3&gt;&#10;&lt;p&gt;Here&amp;rsquo;s the Hugo quick start at the time of writing:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo new project quickstart&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd quickstart&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git init&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git submodule add https://github.com/gohugo-ananke/ananke themes/ananke&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;theme = &amp;#39;ananke&amp;#39;&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; hugo.toml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo server&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Jekyll&amp;rsquo;s getting-started guide asks for Ruby 2.7.0 or later, RubyGems, GCC and Make, then:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gem install jekyll bundler&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;jekyll new myblog&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd myblog&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bundle exec jekyll serve&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;None of that is hard if you&amp;rsquo;re a developer. But it happens on a computer, it breaks when versions drift, and it&amp;rsquo;s the reason plenty of people who&amp;rsquo;d like a static blog never finish setting one up. Selfish has no installation step beyond the app, no dependencies and no build command.&lt;/p&gt;&#10;&lt;h3 id="writing-and-publishing-from-an-iphone"&gt;Writing and publishing from an iPhone&lt;/h3&gt;&#10;&lt;p&gt;Hugo and Jekyll need a computer to build the site. You can wire up a phone-to-git-to-CI pipeline, but it&amp;rsquo;s a project in itself. Selfish runs natively on iPhone, iPad and Mac. It has autosave, drafts, automatic photo optimisation, photos placed inline where you put them, and a live preview that matches the published page exactly. You write, you publish, and the upload goes straight from your device.&lt;/p&gt;&#10;&lt;h3 id="deployment-is-included"&gt;Deployment is included&lt;/h3&gt;&#10;&lt;p&gt;With a generator, building and deploying are separate problems. You pick a host, script an upload or set up CI, and manage the credentials. Selfish handles SFTP (password or SSH key, with RSA and Ed25519), S3-compatible storage, Netlify, Cloudflare Pages and GitHub Pages directly. It has a Test Connection button and shows per-file progress. Credentials live in Apple&amp;rsquo;s Keychain, and SFTP host keys are pinned on first use. The &lt;a href="https://selfpubli.sh/docs/"&gt;publishing docs&lt;/a&gt; walk through each route.&lt;/p&gt;&#10;&lt;h3 id="sensible-output-by-default"&gt;Sensible output by default&lt;/h3&gt;&#10;&lt;p&gt;Out of the box, a Selfish site has a sitemap, RSS and JSON feeds, canonical links, meta tags, responsive themes and automatic dark mode. The themes use no web fonts and no trackers. Hugo and Jekyll can do all of this and more, but the quality of what you get depends on the theme you pick or the templates you write.&lt;/p&gt;&#10;&lt;h2 id="choose-hugo-or-jekyll-if"&gt;Choose Hugo or Jekyll if…&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You want full control of templates and site structure.&lt;/li&gt;&#10;&lt;li&gt;Your site is large, multilingual, or more than a blog.&lt;/li&gt;&#10;&lt;li&gt;You want your source in git, with branches, reviews and CI.&lt;/li&gt;&#10;&lt;li&gt;You want your writing stored as plain Markdown files you can take anywhere.&lt;/li&gt;&#10;&lt;li&gt;You&amp;rsquo;re comfortable in a terminal. For Hugo, prebuilt binaries for most platforms. For Jekyll, the Ruby ecosystem and native GitHub Pages support.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="choose-selfish-if"&gt;Choose Selfish if…&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You want a static site without installing or maintaining a toolchain.&lt;/li&gt;&#10;&lt;li&gt;You write on an iPhone, iPad or Mac and want to publish from there.&lt;/li&gt;&#10;&lt;li&gt;A good theme and header and footer snippets are all the customisation you need.&lt;/li&gt;&#10;&lt;li&gt;You&amp;rsquo;d rather have publishing, credentials and uploads handled for you.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;Selfish is &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt; as one app for iPhone, iPad and Mac, for a one-time £3.99 introductory price that rises to £9.99 in December. It isn&amp;rsquo;t trying to replace Hugo or Jekyll for people who want to build their own machinery. It&amp;rsquo;s for people who want the result without the machinery. If that&amp;rsquo;s you, the &lt;a href="https://selfpubli.sh/guide/"&gt;user guide&lt;/a&gt; shows the workflow and our post on &lt;a href="https://selfpubli.sh/blog/static-site-generator-without-the-command-line/"&gt;a static site generator without the command line&lt;/a&gt; goes into more depth.&lt;/p&gt;&#10;</content:encoded></item><item><title>The best way to self-host a personal blog in 2026</title><link>https://selfpubli.sh/blog/self-host-a-personal-blog/</link><pubDate>Thu, 23 Jul 2026 11:20:00 +0100</pubDate><guid>https://selfpubli.sh/blog/self-host-a-personal-blog/</guid><description>Static site, Ghost or WordPress, on a VPS, object storage or a free static host: an honest look at the cost, maintenance and security of each option.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;&amp;ldquo;Self-hosting&amp;rdquo; covers a wide range. At one end, you rent a Linux server and run everything yourself. At the other, you keep your writing on your own machine and hand a folder of HTML to a free static host. Both count, because the thing that matters is the same: your words are in a format you control, and you can move them without asking anyone&amp;rsquo;s permission.&lt;/p&gt;&#10;&lt;p&gt;This is a survey of the real options in 2026, with the trade-offs stated plainly. There are two decisions to make: &lt;strong&gt;what software produces the blog&lt;/strong&gt;, and &lt;strong&gt;where the result is served from&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;h2 id="part-one-the-software"&gt;Part one: the software&lt;/h2&gt;&#10;&lt;h3 id="a-static-site"&gt;A static site&lt;/h3&gt;&#10;&lt;p&gt;A static blog is pre-built HTML files. Nothing runs when a visitor arrives; the server just hands over a file.&lt;/p&gt;&#10;&lt;p&gt;You can produce those files two ways. The traditional route is a static site generator: Hugo, Jekyll, Eleventy and Astro are the best known. You write posts as Markdown files, run a build command, and get a folder of HTML. The alternative is an app that does the writing and building for you, which avoids the terminal entirely. There&amp;rsquo;s a longer look at that in &lt;a href="https://selfpubli.sh/blog/static-site-generator-without-the-command-line/"&gt;a static site generator without the command line&lt;/a&gt;.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Cost:&lt;/strong&gt; the software is free. Hosting can be free too (see part two).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Maintenance:&lt;/strong&gt; close to none once it&amp;rsquo;s running. There&amp;rsquo;s no server-side software to patch on the blog itself.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; the best of the three by a distance. There&amp;rsquo;s no login page, no database and no code executing per request, so there&amp;rsquo;s very little to attack.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Limits:&lt;/strong&gt; anything dynamic needs a third-party service. Comments, search and newsletters are bolted on, not built in. The command-line generators also carry a real learning curve.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="ghost-self-hosted"&gt;Ghost, self-hosted&lt;/h3&gt;&#10;&lt;p&gt;Ghost is an open-source publishing platform with a polished editor and built-in memberships and email newsletters. You can pay for Ghost(Pro), the official hosting, which starts at $18 a month billed yearly at the time of writing, or run it yourself for free.&lt;/p&gt;&#10;&lt;p&gt;Self-hosting it is a proper server job. Ghost&amp;rsquo;s official Ubuntu guide asks for Ubuntu 22.04, 24.04 or 26.04, MySQL 8, nginx, a supported Node.js version and at least 1 GB of RAM, installed through the Ghost-CLI tool. There&amp;rsquo;s also a newer Docker Compose method.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Cost:&lt;/strong&gt; a small VPS, plus a transactional email service if you want to send newsletters in volume.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Maintenance:&lt;/strong&gt; regular. Ghost, Node.js, MySQL and the operating system all need updating, and major upgrades occasionally need care.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; reasonable if you keep up with updates. There&amp;rsquo;s an admin login and a database, so there&amp;rsquo;s more surface than a static site.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Where it wins:&lt;/strong&gt; if you want paid subscriptions and email newsletters from your own domain, Ghost does that well, and a static site doesn&amp;rsquo;t do it at all.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="wordpress-self-hosted"&gt;WordPress, self-hosted&lt;/h3&gt;&#10;&lt;p&gt;WordPress needs no introduction. The self-hosted version from wordpress.org is free software; you supply a server with PHP and a database. At the time of writing, WordPress recommends PHP 8.3 or newer and MySQL 8.0 or MariaDB 10.11 or newer.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Cost:&lt;/strong&gt; shared hosting or a small VPS. Plenty of hosts offer one-click installs.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Maintenance:&lt;/strong&gt; the highest of the three. Core, themes and plugins update constantly, and a plugin that goes unmaintained becomes a liability.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; a popular target, precisely because it&amp;rsquo;s everywhere. Automated attacks on login pages and known plugin vulnerabilities are routine. A carefully maintained install with few plugins is fine; a neglected one is a problem.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Where it wins:&lt;/strong&gt; the plugin ecosystem is unmatched. If you need something unusual, somebody has probably built it.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="part-two-where-its-served-from"&gt;Part two: where it&amp;rsquo;s served from&lt;/h2&gt;&#10;&lt;p&gt;Ghost and WordPress need a server that runs code, so a VPS or managed hosting is your only option. A static site can go almost anywhere.&lt;/p&gt;&#10;&lt;h3 id="your-own-vps"&gt;Your own VPS&lt;/h3&gt;&#10;&lt;p&gt;A virtual server from a provider such as Hetzner, DigitalOcean or Linode. At the time of writing, Hetzner&amp;rsquo;s cheapest cloud server is €5.49 a month excluding VAT in Germany and Finland. You install a web server, point your domain at it, and upload files over SFTP. The steps are in &lt;a href="https://selfpubli.sh/blog/how-to-host-a-static-blog-on-your-own-server/"&gt;how to host a static blog on your own server&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;This is the most independent option. Nobody&amp;rsquo;s terms of service apply except your provider&amp;rsquo;s, and moving is a matter of copying a folder. It&amp;rsquo;s also the one that makes you responsible for operating-system updates.&lt;/p&gt;&#10;&lt;h3 id="object-storage"&gt;Object storage&lt;/h3&gt;&#10;&lt;p&gt;S3-compatible storage (Amazon S3, Cloudflare R2, Backblaze B2 and others) can serve a static site directly from a bucket. Cloudflare R2&amp;rsquo;s free tier, at the time of writing, includes 10 GB of storage a month and charges nothing for egress. That&amp;rsquo;s more than a personal blog will ever use.&lt;/p&gt;&#10;&lt;p&gt;One catch worth knowing: Amazon S3&amp;rsquo;s static website endpoints don&amp;rsquo;t support HTTPS. AWS&amp;rsquo;s documentation points you to CloudFront or Amplify Hosting in front of the bucket, which adds a layer of setup.&lt;/p&gt;&#10;&lt;h3 id="free-static-hosts"&gt;Free static hosts&lt;/h3&gt;&#10;&lt;p&gt;Three platforms will host a static site for nothing, with HTTPS and a global CDN. Their free tiers differ in ways that matter.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Free tier at the time of writing&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Watch out for&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;GitHub Pages&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;1 GB published site, soft limit of 100 GB bandwidth a month&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Free accounts must publish from a public repository; not for sites that are primarily commercial&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Cloudflare Pages&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;500 builds a month, up to 20,000 files per site&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cloudflare now also offers static hosting through Workers, with a migration guide from Pages&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Netlify&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;300 credits a month on a hard limit&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Bandwidth costs 20 credits per GB and each production deploy 15; the paid Personal plan is $9 a month&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;The Netlify figures deserve a closer look. Under its credit-based pricing, 300 credits covers roughly 15 GB of bandwidth if you spent them on nothing else, and every production deploy draws from the same pot. For a small blog that&amp;rsquo;s usually fine. But if a post takes off, the free plan doesn&amp;rsquo;t bill you; it pauses your projects, all of them on the account, until the next billing cycle or until you upgrade. That&amp;rsquo;s worth knowing before you rely on it.&lt;/p&gt;&#10;&lt;p&gt;The honest trade-off with all three: they&amp;rsquo;re convenient, fast and free, but you&amp;rsquo;re on someone else&amp;rsquo;s platform and subject to their limits and policy changes. Because your site is plain files, though, leaving is easy. That&amp;rsquo;s the difference between hosting on a platform and publishing on one.&lt;/p&gt;&#10;&lt;h2 id="so-which-should-you-pick"&gt;So which should you pick&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;If you want the least work and the most security,&lt;/strong&gt; use a static site. Host it on GitHub Pages or Cloudflare Pages if free matters most, or on a small VPS if you want full independence.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;If you need paid memberships and newsletters,&lt;/strong&gt; self-hosted Ghost is the strongest option you can own, as long as you accept the server upkeep. Ghost(Pro) is a fair compromise if you don&amp;rsquo;t.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;If you need a specific plugin or a site that&amp;rsquo;s really an application,&lt;/strong&gt; WordPress is still the practical choice. Budget time for updates.&lt;/p&gt;&#10;&lt;p&gt;For most personal blogs, the answer is a static site. The writing is the point; everything else should be quiet.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;Selfish is a native app for iPhone, iPad and Mac, &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt; for a one-time £3.99 (an introductory price, rising to £9.99 in December), that writes and builds a static blog and publishes it to your choice of SFTP server, S3-compatible storage, Netlify, Cloudflare Pages or GitHub Pages. Your content stays on your device, and the published site carries no Selfish code. The &lt;a href="https://selfpubli.sh/docs/"&gt;publishing docs&lt;/a&gt; explain each route.&lt;/p&gt;&#10;</content:encoded></item><item><title>How to publish a website over SFTP</title><link>https://selfpubli.sh/blog/how-to-publish-a-website-over-sftp/</link><pubDate>Tue, 14 Jul 2026 08:55:00 +0100</pubDate><guid>https://selfpubli.sh/blog/how-to-publish-a-website-over-sftp/</guid><description>What SFTP is, how to find your host, user, port and path on a VPS, cPanel or NAS, how to set up SSH keys and fingerprints, and how to fix common errors.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;SFTP is the least glamorous way to publish a website and one of the most durable. It works with almost any Linux server, most shared hosting and most home NAS boxes. It needs no account with a platform, no build pipeline and no API token that expires. You have a folder of files; SFTP puts them on a server.&lt;/p&gt;&#10;&lt;p&gt;This guide explains what SFTP actually is, how to find the four details every SFTP client asks for, how to set up keys properly, and how to fix the errors you&amp;rsquo;re most likely to meet.&lt;/p&gt;&#10;&lt;h2 id="sftp-ftp-and-ftps-are-three-different-things"&gt;SFTP, FTP and FTPS are three different things&lt;/h2&gt;&#10;&lt;p&gt;The names are confusingly similar. The protocols are not.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;FTP&lt;/strong&gt; is the original File Transfer Protocol, from the early days of the internet. It usually listens on port 21 and sends your username and password in plain text. Avoid it.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;FTPS&lt;/strong&gt; is FTP wrapped in TLS, the same encryption HTTPS uses. It fixes the plain-text problem but keeps FTP&amp;rsquo;s awkward separate data connections, which firewalls dislike.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;SFTP&lt;/strong&gt; is the SSH File Transfer Protocol. Despite the name, it isn&amp;rsquo;t FTP at all. It runs inside an SSH connection, usually on port 22, so it&amp;rsquo;s encrypted end to end and authenticates the same way SSH does: a password or, better, a key.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;If your server lets you log in with &lt;code&gt;ssh&lt;/code&gt;, it almost certainly supports SFTP already. OpenSSH, the SSH server on nearly every Linux system, includes it.&lt;/p&gt;&#10;&lt;h2 id="the-four-details-you-need"&gt;The four details you need&lt;/h2&gt;&#10;&lt;p&gt;Every SFTP client asks for the same things: &lt;strong&gt;host&lt;/strong&gt;, &lt;strong&gt;port&lt;/strong&gt;, &lt;strong&gt;username&lt;/strong&gt; and &lt;strong&gt;remote path&lt;/strong&gt;. Where you find them depends on the kind of server.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Host&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Port&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Username&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Remote path&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;VPS&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;IP address or domain&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;22 unless you changed it&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the user you created, e.g. &lt;code&gt;deploy&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;wherever your web server&amp;rsquo;s root points, e.g. &lt;code&gt;/var/www/example.com&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;cPanel hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;your domain or the server hostname from your welcome email&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;22, or a custom port some hosts use&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;your cPanel username&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;usually &lt;code&gt;/home/&amp;lt;username&amp;gt;/public_html&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Synology NAS&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the NAS&amp;rsquo;s local IP or a hostname&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;22 by default, configurable&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;a DSM user account&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;the Web Station shared folder, &lt;code&gt;/web&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;A few notes on each.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;VPS.&lt;/strong&gt; You set these up yourself, so you know them. The remote path is whatever &lt;code&gt;root&lt;/code&gt; says in your nginx or Caddy configuration. If you haven&amp;rsquo;t got that far, &lt;a href="https://selfpubli.sh/blog/how-to-host-a-static-blog-on-your-own-server/"&gt;how to host a static blog on your own server&lt;/a&gt; walks through it.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;cPanel.&lt;/strong&gt; Not every host enables SSH, and SFTP depends on it. If there&amp;rsquo;s an &lt;strong&gt;SSH Access&lt;/strong&gt; page in cPanel, you&amp;rsquo;re probably fine. If not, ask your host. Some use a non-standard port; it&amp;rsquo;ll be in your account details or their help pages.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Synology.&lt;/strong&gt; In DSM, go to &lt;strong&gt;Control Panel › File Services › FTP&lt;/strong&gt; and tick &lt;strong&gt;Enable SFTP service&lt;/strong&gt;. The default port is 22. If you use Web Station, it serves files from a shared folder called &lt;code&gt;web&lt;/code&gt;, and Synology&amp;rsquo;s own guidance is that the &lt;code&gt;http&lt;/code&gt; group needs at least read permission on it.&lt;/p&gt;&#10;&lt;h2 id="use-an-ssh-key-not-a-password"&gt;Use an SSH key, not a password&lt;/h2&gt;&#10;&lt;p&gt;Passwords work, but keys are both safer and more convenient. A key pair has a private half that stays on your machine and a public half that you give to the server.&lt;/p&gt;&#10;&lt;p&gt;Create one on your Mac or Linux machine:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-keygen -t ed25519 -C &lt;span style="color:#e6db74"&gt;&amp;#34;laptop-2026&amp;#34;&lt;/span&gt; -f ~/.ssh/id_ed25519_site&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Give it a passphrase when asked. Ed25519 has been &lt;code&gt;ssh-keygen&lt;/code&gt;&amp;rsquo;s default since OpenSSH 9.5; spelling it out makes the command behave the same on older systems. A few older tools and hosts only accept RSA. If you meet one, use &lt;code&gt;ssh-keygen -t rsa -b 4096&lt;/code&gt; instead.&lt;/p&gt;&#10;&lt;p&gt;Now install the public half on the server. On a VPS where you can still log in with a password:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-copy-id -i ~/.ssh/id_ed25519_site.pub deploy@example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On cPanel, go to &lt;strong&gt;SSH Access › Manage SSH Keys › Import Key&lt;/strong&gt; and paste the contents of &lt;code&gt;id_ed25519_site.pub&lt;/code&gt;. Then &lt;strong&gt;authorise&lt;/strong&gt; the key. cPanel won&amp;rsquo;t use a key until you do, and this is the step people miss.&lt;/p&gt;&#10;&lt;p&gt;Test it:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh -i ~/.ssh/id_ed25519_site deploy@example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="check-the-host-key-fingerprint"&gt;Check the host key fingerprint&lt;/h2&gt;&#10;&lt;p&gt;The first time you connect, SSH shows something like this:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;The authenticity of host &amp;#39;example.com (203.0.113.10)&amp;#39; can&amp;#39;t be established.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ED25519 key fingerprint is SHA256:JX+wL0OQDpSU1C1rv2FWspDkZeUv7DI8us/vG8Hppbc.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Are you sure you want to continue connecting (yes/no/[fingerprint])?&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That fingerprint identifies the server. Typing &lt;code&gt;yes&lt;/code&gt; without checking it means trusting whoever answered, which is almost always your server, but checking is how you know.&lt;/p&gt;&#10;&lt;p&gt;Get the real fingerprint through a channel an attacker can&amp;rsquo;t tamper with. Many VPS providers offer a web console; log in there and run:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the two match, accept. You can also fetch the key over the network and fingerprint it:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-keyscan -t ed25519 example.com | ssh-keygen -lf -&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Be clear about what that proves. &lt;code&gt;ssh-keyscan&lt;/code&gt; trusts the network just as much as your first connection does. It&amp;rsquo;s useful for recording the fingerprint, or comparing it later, but it&amp;rsquo;s not independent verification.&lt;/p&gt;&#10;&lt;p&gt;If the key ever changes, SSH refuses to connect with a loud &lt;code&gt;REMOTE HOST IDENTIFICATION HAS CHANGED&lt;/code&gt; warning. Sometimes that&amp;rsquo;s legitimate: you rebuilt the server. Confirm that&amp;rsquo;s what happened, then remove the old entry:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-keygen -R example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="upload-the-files"&gt;Upload the files&lt;/h2&gt;&#10;&lt;h3 id="with-sftp"&gt;With sftp&lt;/h3&gt;&#10;&lt;p&gt;The &lt;code&gt;sftp&lt;/code&gt; command comes with OpenSSH. From the folder that contains your built site (&lt;code&gt;public&lt;/code&gt; here):&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sftp -i ~/.ssh/id_ed25519_site -P &lt;span style="color:#ae81ff"&gt;22&lt;/span&gt; deploy@example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note the capital &lt;code&gt;-P&lt;/code&gt; for the port; &lt;code&gt;ssh&lt;/code&gt; uses lower-case &lt;code&gt;-p&lt;/code&gt;. Then, at the &lt;code&gt;sftp&amp;gt;&lt;/code&gt; prompt:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd /var/www/example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;lcd public&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;put -r *&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;lcd&lt;/code&gt; changes the local directory; &lt;code&gt;put -r *&lt;/code&gt; uploads everything in it, recursively. Two limitations: the &lt;code&gt;*&lt;/code&gt; skips hidden files such as &lt;code&gt;.htaccess&lt;/code&gt;, and &lt;code&gt;sftp&lt;/code&gt; never deletes anything on the server. Remove a page locally and it stays online until you delete it by hand.&lt;/p&gt;&#10;&lt;h3 id="with-rsync"&gt;With rsync&lt;/h3&gt;&#10;&lt;p&gt;&lt;code&gt;rsync&lt;/code&gt; mirrors a folder over SSH, sending only what changed and optionally removing what&amp;rsquo;s gone:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rsync -avz --delete --dry-run &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -e &lt;span style="color:#e6db74"&gt;&amp;#34;ssh -i ~/.ssh/id_ed25519_site -p 22&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; public/ deploy@example.com:/var/www/example.com/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Read the output, then run it again without &lt;code&gt;--dry-run&lt;/code&gt;. The trailing slash on &lt;code&gt;public/&lt;/code&gt; means &amp;ldquo;the contents of this folder&amp;rdquo;. Without it you get &lt;code&gt;/var/www/example.com/public/&lt;/code&gt;. And be careful with &lt;code&gt;--delete&lt;/code&gt;: pointed at the wrong path, it&amp;rsquo;ll empty it.&lt;/p&gt;&#10;&lt;p&gt;Two caveats. rsync must also be installed on the server; some locked-down SFTP-only accounts don&amp;rsquo;t allow it. And since macOS Sequoia 15.4, the &lt;code&gt;rsync&lt;/code&gt; that ships with macOS is actually openrsync, which supports fewer options. The command above works with it. For the full feature set, &lt;code&gt;brew install rsync&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="common-errors-and-what-they-mean"&gt;Common errors and what they mean&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;Permission denied (publickey)&lt;/code&gt;.&lt;/strong&gt; The server didn&amp;rsquo;t accept your key. Check that you&amp;rsquo;re using the right username and the right &lt;code&gt;-i&lt;/code&gt; key file, that the public key is in &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; on the server (or authorised, on cPanel), and that permissions are tight: &lt;code&gt;chmod 700 ~/.ssh&lt;/code&gt; and &lt;code&gt;chmod 600 ~/.ssh/authorized_keys&lt;/code&gt;. OpenSSH ignores keys in files other users can write to.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;Permission denied&lt;/code&gt; when uploading.&lt;/strong&gt; You&amp;rsquo;re logged in, but your user can&amp;rsquo;t write to that directory. Fix ownership on the server: &lt;code&gt;sudo chown -R deploy:deploy /var/www/example.com&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;No such file or directory&lt;/code&gt;.&lt;/strong&gt; Wrong remote path. Some hosts restrict SFTP users to their home directory, so &lt;code&gt;/&lt;/code&gt; means your home rather than the real root, and absolute paths from the documentation won&amp;rsquo;t match. Connect, run &lt;code&gt;pwd&lt;/code&gt; and &lt;code&gt;ls&lt;/code&gt;, and work from what you see.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;Connection refused&lt;/code&gt; or a timeout.&lt;/strong&gt; Wrong port, SSH disabled, or a firewall in the way. On a NAS at home, reaching it from outside also needs port forwarding on your router.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The upload works, but the site shows &lt;code&gt;403 Forbidden&lt;/code&gt;.&lt;/strong&gt; The web server can&amp;rsquo;t read the files. This happens when your local umask or the server&amp;rsquo;s SFTP settings create files readable only by you (&lt;code&gt;600&lt;/code&gt;). The web server needs directories at &lt;code&gt;755&lt;/code&gt; and files at &lt;code&gt;644&lt;/code&gt;. Fix everything in one go:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh -i ~/.ssh/id_ed25519_site deploy@example.com &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;find /var/www/example.com -type d -exec chmod 755 {} + &amp;amp;&amp;amp; find /var/www/example.com -type f -exec chmod 644 {} +&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;sftp&lt;/code&gt; prompt has a &lt;code&gt;chmod&lt;/code&gt; command too, but it isn&amp;rsquo;t recursive, so it&amp;rsquo;s only practical for a file or two.&lt;/p&gt;&#10;&lt;h2 id="publishing-with-selfish"&gt;Publishing with Selfish&lt;/h2&gt;&#10;&lt;p&gt;Selfish, a native app for iPhone, iPad and Mac that&amp;rsquo;s out now &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt;, publishes over SFTP with the same four details and either a password or an SSH key (Ed25519 or RSA, with passphrases). It pins the server&amp;rsquo;s SHA256 host key on first connection and refuses to upload if it changes, skips files that haven&amp;rsquo;t changed, and keeps credentials in Apple&amp;rsquo;s Keychain. The &lt;a href="https://selfpubli.sh/docs/"&gt;publishing docs&lt;/a&gt; cover the setup screen by screen.&lt;/p&gt;&#10;</content:encoded></item><item><title>How to host a static blog on your own server</title><link>https://selfpubli.sh/blog/how-to-host-a-static-blog-on-your-own-server/</link><pubDate>Thu, 09 Jul 2026 10:15:00 +0100</pubDate><guid>https://selfpubli.sh/blog/how-to-host-a-static-blog-on-your-own-server/</guid><description>A practical guide to hosting a static blog yourself: choosing a server, configuring Caddy or nginx, HTTPS, file permissions and getting your files there.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;A static blog is a folder of HTML, CSS and images. That is the whole of it. There is no database to back up, no PHP version to chase and no admin login for bots to hammer. Hosting one yourself is mostly a matter of putting that folder somewhere a web server can read it, and then leaving it alone.&lt;/p&gt;&#10;&lt;p&gt;This guide covers the practical steps: where the server lives, which web server to run, HTTPS, where the files go, who owns them, and how new files get there.&lt;/p&gt;&#10;&lt;h2 id="pick-where-it-lives"&gt;Pick where it lives&lt;/h2&gt;&#10;&lt;p&gt;There are three realistic homes for a self-hosted static site.&lt;/p&gt;&#10;&lt;h3 id="a-small-vps"&gt;A small VPS&lt;/h3&gt;&#10;&lt;p&gt;A virtual private server gives you a Linux machine with root access and a public IP address. For a static blog, the smallest plan any mainstream provider sells is plenty. A static site serves thousands of visitors on hardware that would struggle to run a busy WordPress install.&lt;/p&gt;&#10;&lt;p&gt;Prices move, so check before you commit. At the time of writing, Hetzner&amp;rsquo;s cheapest cloud server, the CX23, is €5.49 a month excluding VAT in its German and Finnish locations, following a price rise in June 2026. Other providers sit in a similar range.&lt;/p&gt;&#10;&lt;p&gt;This is the option the rest of this guide assumes. It&amp;rsquo;s also the most instructive, because you control every layer.&lt;/p&gt;&#10;&lt;h3 id="shared-hosting"&gt;Shared hosting&lt;/h3&gt;&#10;&lt;p&gt;If you already pay for shared hosting with a cPanel account, you can put a static site there today. You won&amp;rsquo;t configure the web server yourself; you&amp;rsquo;ll upload into a folder the host already serves, usually &lt;code&gt;public_html&lt;/code&gt;. Many shared hosts now provide free certificates automatically, but check your control panel rather than assuming. The trade-off is less control and occasionally slower support for things like SSH keys.&lt;/p&gt;&#10;&lt;h3 id="a-box-at-home"&gt;A box at home&lt;/h3&gt;&#10;&lt;p&gt;A Raspberry Pi or an old laptop can serve a blog perfectly well. The difficulties are all networking: residential IP addresses change, some broadband providers put you behind carrier-grade NAT so inbound connections never reach you, and some forbid running servers in their terms. If you want to try it anyway, a tunnelling service such as Cloudflare Tunnel runs a small daemon that makes outbound-only connections, so you don&amp;rsquo;t need to open ports on your router. Your electricity, your uptime, your problem.&lt;/p&gt;&#10;&lt;h2 id="point-your-domain-at-it"&gt;Point your domain at it&lt;/h2&gt;&#10;&lt;p&gt;Before HTTPS will work, your domain has to resolve to the server. In your DNS provider&amp;rsquo;s panel, create:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;an &lt;code&gt;A&lt;/code&gt; record for &lt;code&gt;example.com&lt;/code&gt; pointing to the server&amp;rsquo;s IPv4 address&lt;/li&gt;&#10;&lt;li&gt;an &lt;code&gt;AAAA&lt;/code&gt; record if the server has IPv6&lt;/li&gt;&#10;&lt;li&gt;the same records, or a &lt;code&gt;CNAME&lt;/code&gt; to &lt;code&gt;example.com&lt;/code&gt;, for &lt;code&gt;www&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;DNS changes can take a while to propagate. Check with &lt;code&gt;dig +short example.com&lt;/code&gt; from your own machine before moving on.&lt;/p&gt;&#10;&lt;h2 id="choose-a-web-server"&gt;Choose a web server&lt;/h2&gt;&#10;&lt;p&gt;For a static site you want something small, fast and boring. Two sensible choices:&lt;/p&gt;&#10;&lt;h3 id="caddy"&gt;Caddy&lt;/h3&gt;&#10;&lt;p&gt;Caddy&amp;rsquo;s selling point for this job is automatic HTTPS. If your domain resolves to the server and ports 80 and 443 are reachable, Caddy obtains certificates from Let&amp;rsquo;s Encrypt (falling back to ZeroSSL) and renews them in the background. There&amp;rsquo;s nothing else to install.&lt;/p&gt;&#10;&lt;p&gt;Install it from Caddy&amp;rsquo;s official package repository (the instructions on caddyserver.com cover Debian, Ubuntu and others), then put this in &lt;code&gt;/etc/caddy/Caddyfile&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-caddyfile" data-lang="caddyfile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;example.com {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;root&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;*&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/var/www/example.com&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;encode&lt;/span&gt; &lt;span style="color:#e6db74"&gt;zstd&lt;/span&gt; &lt;span style="color:#e6db74"&gt;gzip&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;file_server&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;www.example.com {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#66d9ef"&gt;redir&lt;/span&gt; &lt;span style="color:#e6db74"&gt;https://example.com&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;{uri}&lt;/span&gt; &lt;span style="color:#e6db74"&gt;permanent&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Reload it:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo systemctl reload caddy&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is a complete, production-ready configuration for a static blog, HTTPS included.&lt;/p&gt;&#10;&lt;h3 id="nginx"&gt;nginx&lt;/h3&gt;&#10;&lt;p&gt;nginx is everywhere and extremely well documented. It needs a separate tool for certificates, but that tool does most of the work. On Debian or Ubuntu, install it with &lt;code&gt;sudo apt install nginx&lt;/code&gt;, then create &lt;code&gt;/etc/nginx/sites-available/example.com&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-nginx" data-lang="nginx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;server&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;listen&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;listen&lt;/span&gt; &lt;span style="color:#e6db74"&gt;[::]:80&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;server_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;example.com&lt;/span&gt; &lt;span style="color:#e6db74"&gt;www.example.com&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;root&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/var/www/example.com&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;index&lt;/span&gt; &lt;span style="color:#e6db74"&gt;index.html&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;location&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;try_files&lt;/span&gt; $uri $uri/ =&lt;span style="color:#ae81ff"&gt;404&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;error_page&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;404&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/404.html&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Enable it, test the configuration and reload:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo nginx -t &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo systemctl reload nginx&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="add-https"&gt;Add HTTPS&lt;/h2&gt;&#10;&lt;p&gt;With Caddy, you already have it. With nginx, use Certbot, the Let&amp;rsquo;s Encrypt client from the EFF. The snap package is the method Certbot recommends:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo snap install --classic certbot&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ln -s /snap/bin/certbot /usr/local/bin/certbot&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo certbot --nginx -d example.com -d www.example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Certbot edits your nginx configuration to add the certificate and an HTTP-to-HTTPS redirect. It also installs a timer that renews certificates before they expire. Confirm renewal works with:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo certbot renew --dry-run&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="open-the-firewall-and-only-that"&gt;Open the firewall, and only that&lt;/h2&gt;&#10;&lt;p&gt;If you use &lt;code&gt;ufw&lt;/code&gt;, allow SSH first so you don&amp;rsquo;t lock yourself out, then the web ports:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw allow OpenSSH&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw allow 80/tcp&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw allow 443/tcp&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo ufw enable&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Port 80 stays open even though you serve everything over HTTPS. Certificate challenges and the redirect both use it.&lt;/p&gt;&#10;&lt;h2 id="where-the-files-go-and-who-owns-them"&gt;Where the files go, and who owns them&lt;/h2&gt;&#10;&lt;p&gt;Convention on Linux is &lt;code&gt;/var/www/&amp;lt;domain&amp;gt;&lt;/code&gt;. The directory that holds your site should be:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;owned by the account that uploads&lt;/strong&gt;, so publishing never needs &lt;code&gt;sudo&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;readable by the web server&lt;/strong&gt;, which runs as its own user (&lt;code&gt;www-data&lt;/code&gt; for nginx on Debian and Ubuntu, &lt;code&gt;caddy&lt;/code&gt; for Caddy&amp;rsquo;s packages)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Create a dedicated upload user rather than publishing as root:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo adduser --disabled-password --gecos &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt; deploy&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mkdir -p /var/www/example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chown deploy:deploy /var/www/example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chmod &lt;span style="color:#ae81ff"&gt;755&lt;/span&gt; /var/www/example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The permissions you want are &lt;code&gt;755&lt;/code&gt; for directories and &lt;code&gt;644&lt;/code&gt; for files: the owner can write, everyone else can read. The web server doesn&amp;rsquo;t need to write anything, and it shouldn&amp;rsquo;t be able to. If uploaded files arrive as &lt;code&gt;600&lt;/code&gt;, visitors will see &lt;code&gt;403 Forbidden&lt;/code&gt;. Fix them in one go:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;find /var/www/example.com -type d -exec chmod &lt;span style="color:#ae81ff"&gt;755&lt;/span&gt; &lt;span style="color:#f92672"&gt;{}&lt;/span&gt; +&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;find /var/www/example.com -type f -exec chmod &lt;span style="color:#ae81ff"&gt;644&lt;/span&gt; &lt;span style="color:#f92672"&gt;{}&lt;/span&gt; +&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add your public SSH key to &lt;code&gt;/home/deploy/.ssh/authorized_keys&lt;/code&gt; so the deploy account can log in without a password. Once key login works, consider setting &lt;code&gt;PasswordAuthentication no&lt;/code&gt; in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="getting-files-onto-the-server"&gt;Getting files onto the server&lt;/h2&gt;&#10;&lt;p&gt;Your static site generator, whatever it is, produces a folder: &lt;code&gt;public/&lt;/code&gt;, &lt;code&gt;_site/&lt;/code&gt;, &lt;code&gt;dist/&lt;/code&gt;. Publishing means making the server&amp;rsquo;s &lt;code&gt;/var/www/example.com&lt;/code&gt; match that folder.&lt;/p&gt;&#10;&lt;p&gt;The standard ways to do that are SFTP and rsync, both of which run over SSH, so the key you set up above is all the authentication you need. For a one-off copy:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rsync -avz --delete public/ deploy@example.com:/var/www/example.com/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The trailing slash on &lt;code&gt;public/&lt;/code&gt; matters: it copies the folder&amp;rsquo;s contents rather than the folder itself. &lt;code&gt;--delete&lt;/code&gt; removes files on the server that no longer exist locally, which is what you want for a mirror, and exactly what you don&amp;rsquo;t want if you point it at the wrong directory. Add &lt;code&gt;--dry-run&lt;/code&gt; the first time.&lt;/p&gt;&#10;&lt;p&gt;SFTP has more to it than fits here: host keys, fingerprints, paths on shared hosting and NAS boxes, and the errors you&amp;rsquo;re likely to meet. That&amp;rsquo;s all in &lt;a href="https://selfpubli.sh/blog/how-to-publish-a-website-over-sftp/"&gt;how to publish a website over SFTP&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="keeping-it-running"&gt;Keeping it running&lt;/h2&gt;&#10;&lt;p&gt;A static server needs very little maintenance, but not none.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Security updates.&lt;/strong&gt; On Debian and Ubuntu, &lt;code&gt;sudo apt install unattended-upgrades&lt;/code&gt; applies security patches automatically.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Backups.&lt;/strong&gt; Your source of truth is the copy on your own machine, not the server. If the VPS disappears, you rebuild and re-upload. Keep that local copy backed up.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Monitoring.&lt;/strong&gt; A free uptime checker that emails you when the site stops responding is worth the two minutes it takes to set up.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;That&amp;rsquo;s it. No plugin updates, no database dumps, no admin panel to secure. This is the quiet reward of static hosting.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;Selfish is a native app for iPhone, iPad and Mac that writes your blog and generates the static site for you, then publishes it over SFTP to a server like the one above, with the host key pinned on first connection. It&amp;rsquo;s &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt; as a one-time purchase, at a £3.99 introductory price, rising to £9.99 in December. The &lt;a href="https://selfpubli.sh/docs/"&gt;publishing docs&lt;/a&gt; show what it needs from your server: the same host, user, key and path you&amp;rsquo;ve just set up.&lt;/p&gt;&#10;</content:encoded></item><item><title>A static site generator without the command line</title><link>https://selfpubli.sh/blog/static-site-generator-without-the-command-line/</link><pubDate>Thu, 02 Jul 2026 09:40:00 +0100</pubDate><guid>https://selfpubli.sh/blog/static-site-generator-without-the-command-line/</guid><description>What a static site generator does, why the Node, Go and Ruby toolchains put people off, and the options that let you publish static HTML without a terminal.</description><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/">&lt;p&gt;Static sites are the best way to publish most personal writing. They&amp;rsquo;re fast, cheap to host, close to unhackable and easy to move. The trouble is that the usual way to make one assumes you&amp;rsquo;re comfortable in a terminal, and plenty of good writers aren&amp;rsquo;t. Nor should they have to be.&lt;/p&gt;&#10;&lt;p&gt;This post explains what a static site generator actually does, where the friction comes from, and the realistic ways to get the result without the toolchain.&lt;/p&gt;&#10;&lt;h2 id="what-a-static-site-generator-does"&gt;What a static site generator does&lt;/h2&gt;&#10;&lt;p&gt;A static site generator (SSG) is a program that turns your writing into a finished website before anyone visits it.&lt;/p&gt;&#10;&lt;p&gt;You give it three things:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Content&lt;/strong&gt;, usually posts written as Markdown files, each with a little metadata at the top: title, date, tags.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Templates&lt;/strong&gt;, which describe how a post page, the home page and an archive page should look.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Configuration&lt;/strong&gt;: the site&amp;rsquo;s name, its address, how URLs should be structured.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;It gives you back a folder of plain HTML, CSS and images. It also generates the pieces a blog needs around the posts: index pages, tag archives, an RSS feed, a sitemap.&lt;/p&gt;&#10;&lt;p&gt;You upload that folder to any web server or static host, and you&amp;rsquo;re done. Nothing runs when a reader arrives. There&amp;rsquo;s no database and no admin panel. That&amp;rsquo;s why static sites are so fast and so hard to break.&lt;/p&gt;&#10;&lt;h2 id="why-the-toolchain-puts-people-off"&gt;Why the toolchain puts people off&lt;/h2&gt;&#10;&lt;p&gt;The concept is simple. The tooling is not, at least for anyone who hasn&amp;rsquo;t spent time as a developer. Each popular generator brings its own ecosystem.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Hugo&lt;/strong&gt; is written in Go and ships as a single executable, which is about as easy as it gets. But themes are commonly installed as Git submodules or Hugo Modules, and Hugo&amp;rsquo;s documentation lists both Git and Go as prerequisites for modules. If your theme uses Sass, you&amp;rsquo;ll need the extended edition.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Jekyll&lt;/strong&gt; is a Ruby gem. Its installation guide asks for Ruby 2.7 or newer with development headers, RubyGems, and the GCC and Make build tools. Getting a working Ruby environment on a Mac is a rite of passage many people would happily skip.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Eleventy&lt;/strong&gt; needs Node.js 18 or newer and is installed with &lt;code&gt;npm&lt;/code&gt;. &lt;strong&gt;Astro&lt;/strong&gt; needs Node.js 22.12 or newer, and its documentation specifically notes that odd-numbered releases such as v23 aren&amp;rsquo;t supported.&lt;/p&gt;&#10;&lt;p&gt;None of that is unreasonable for a developer. But look at what a non-developer has to learn before writing a single post:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;installing a language runtime, and later keeping it at a supported version&lt;/li&gt;&#10;&lt;li&gt;a package manager, and what to do when it prints forty warnings&lt;/li&gt;&#10;&lt;li&gt;Git, at least enough to add a theme&lt;/li&gt;&#10;&lt;li&gt;where the content folder is, and what the front matter at the top of each file must look like&lt;/li&gt;&#10;&lt;li&gt;running a local preview server, then a build&lt;/li&gt;&#10;&lt;li&gt;deploying: SFTP, rsync, or connecting a Git repository to a host that builds for you&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;And then, six months later, updating something and finding the theme no longer builds. That&amp;rsquo;s the real cost. It&amp;rsquo;s not the first afternoon; it&amp;rsquo;s the maintenance tax on something that was meant to be low-maintenance.&lt;/p&gt;&#10;&lt;h2 id="the-options-that-avoid-the-terminal"&gt;The options that avoid the terminal&lt;/h2&gt;&#10;&lt;p&gt;There are three broad approaches. Each moves the complexity somewhere else rather than removing it, so it&amp;rsquo;s worth knowing where it goes.&lt;/p&gt;&#10;&lt;h3 id="a-cms-front-end-on-top-of-an-ssg"&gt;A CMS front-end on top of an SSG&lt;/h3&gt;&#10;&lt;p&gt;Git-based content management systems give you a web editor for a site that&amp;rsquo;s still built by Hugo, Jekyll, Eleventy or similar. Two open-source examples:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Decap CMS&lt;/strong&gt; (formerly Netlify CMS) adds an editing interface that saves your posts as commits to a GitHub, GitLab or Bitbucket repository.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Pages CMS&lt;/strong&gt; does the same for GitHub repositories, with no database or extra backend. It&amp;rsquo;s free and MIT-licensed.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Once set up, these are pleasant for writing. The catch is &amp;ldquo;once set up&amp;rdquo;. Someone still has to create the repository, choose and configure the generator, configure the CMS and connect a host that builds on every commit. They&amp;rsquo;re excellent when a developer sets up a site for a writer. They don&amp;rsquo;t help much if you&amp;rsquo;re both.&lt;/p&gt;&#10;&lt;h3 id="a-hosted-builder"&gt;A hosted builder&lt;/h3&gt;&#10;&lt;p&gt;Services like CloudCannon take on the whole pipeline: they connect to your repository, build your site, host it, and give you a visual editor. It&amp;rsquo;s a serious product aimed at agencies and teams, and it&amp;rsquo;s priced accordingly. At the time of writing its Standard plan is $55 a month, or $49 a month billed annually. That&amp;rsquo;s good value for a business, and a lot for a personal blog.&lt;/p&gt;&#10;&lt;h3 id="a-native-app"&gt;A native app&lt;/h3&gt;&#10;&lt;p&gt;The third approach puts the generator inside an application on your own computer. You write in the app, it builds the site locally, and it uploads the result.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Publii&lt;/strong&gt; is the established example: a free, open-source desktop app for Windows, macOS and Linux. It includes themes, works offline, and publishes to an SFTP server, Amazon S3, Netlify or GitHub Pages, among others. If you want a desktop tool on any operating system, it&amp;rsquo;s well worth a look.&lt;/p&gt;&#10;&lt;p&gt;The appeal of this model is that the complexity really does disappear rather than moving to a server you have to operate. There&amp;rsquo;s no runtime to install, no repository to manage and nothing to build in the cloud. The output is a normal static site you can host anywhere.&lt;/p&gt;&#10;&lt;p&gt;The limits are real too. You get the themes and features the app provides, not the unlimited flexibility of writing your own templates. You can&amp;rsquo;t install a plugin to add something the app doesn&amp;rsquo;t do. And your writing lives in the app&amp;rsquo;s own storage, so it matters how open that app&amp;rsquo;s output is.&lt;/p&gt;&#10;&lt;h2 id="where-selfish-fits"&gt;Where Selfish fits&lt;/h2&gt;&#10;&lt;p&gt;Selfish takes the native-app approach on Apple devices. It&amp;rsquo;s a single app for iPhone, iPad and Mac (running iOS 26, iPadOS 26 or macOS 26), &lt;a href="https://apps.apple.com/app/id6779574096"&gt;on the App Store&lt;/a&gt; as a one-time purchase, at a £3.99 introductory price, rising to £9.99 in December.&lt;/p&gt;&#10;&lt;p&gt;You write in a plain-text composer with a small formatting toolbar, or type a small subset of Markdown directly. The preview matches the published page exactly. Selfish generates a complete static site, with an RSS feed, a JSON feed, a sitemap and category and tag archives. It then publishes to your own server over SFTP, to S3-compatible storage, or to Netlify, Cloudflare Pages or GitHub Pages. Four themes are free; three more are optional one-time purchases. The &lt;a href="https://selfpubli.sh/themes/"&gt;themes page&lt;/a&gt; shows them all.&lt;/p&gt;&#10;&lt;p&gt;It&amp;rsquo;s fair to be clear about what it doesn&amp;rsquo;t do. There&amp;rsquo;s no custom theme editor (it&amp;rsquo;s being considered, not built), no plugins, no comments and no email newsletters. It&amp;rsquo;s Apple-only. And if you enjoy crafting templates in Hugo, you&amp;rsquo;ll find a curated set of themes more limiting than a blank canvas. For that, Hugo is the better tool, and we&amp;rsquo;d say so.&lt;/p&gt;&#10;&lt;p&gt;But if what you want is to write a post on your phone and have it appear as plain HTML on a server you control, without ever opening a terminal, that&amp;rsquo;s the job Selfish is built for. The &lt;a href="https://selfpubli.sh/guide/"&gt;user guide&lt;/a&gt; shows how it works.&lt;/p&gt;&#10;</content:encoded></item></channel></rss>