← All playbooks
Newsletter migration

Substack → Ghost

Move a Substack publication to Ghost while reconciling content, free and paid members, Stripe continuity, custom-domain URLs, newsletter delivery, and a reversible first send.

Typical timeline5–8 calendar days before first full send10–16 hours active work
Statustested
Source testedSubstack publication export workflow documented 2026-07-18
Destination testedGhost built-in Substack migrator documented 2026-07-18
Last reviewed2026-07-18
Sources5
Before you migrate

Should you make this move?

Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.

Current platform

Substack

Reasons to stay
  • Publishing, email, recommendations, network discovery, and paid subscriptions work out of the box
  • Audience, campaigns, automations, and reporting live in one publishing system
Reasons to leave
  • Brand control, automation, data depth, and platform independence are limited
  • Automation logic, analytics history, and deliverability settings are not very portable
New platform

Ghost

What gets better
  • A focused publishing and membership platform is fast and pleasant for writers
  • Editors get a purpose-built publishing workflow instead of raw files
What gets worse
  • Its narrower ecosystem is less suitable for complex sites and custom application behavior
  • Themes, extensions, and content models add maintenance and portability constraints
Best of the move

Ghost: A focused publishing and membership platform is fast and pleasant for writers. This removes a major source-side concern: Brand control, automation, data depth, and platform independence are limited.

Worst of the move

What you lose: Publishing, email, recommendations, network discovery, and paid subscriptions work out of the box. What you inherit: Its narrower ecosystem is less suitable for complex sites and custom application behavior.

01At a glance

Know the shape of the move.

Transfer outcome13 features audited
Transfer outcome distributionClean transfer: 1, Partial transfer: 7, Manual rebuild: 2, Not transferred: 3.
Clean1
Partial7
Manual2
Lost3
Mapping route12 of 12 fields have a destination path

This timeline assumes

  • Profile: one publication with at most 2,000 posts, 25,000 total subscribers, one primary newsletter, one custom domain, and optional paid subscriptions in Stripe.
  • You control the Substack owner account, Ghost owner account, DNS, Stripe account, sending-domain records, and the publication's support email.
  • If paid members exist, Ghost is connected to the same Stripe account used by Substack before member import.
  • No full-audience Ghost email is sent until content, member, payment, domain, redirect, and seed-delivery checks pass.
  • The built-in migrator covers the documented content and member path; comments, Notes, recommendation relationships, referral data, and historical analytics are treated as non-portable unless a separate export proves otherwise.
02Loss matrix

What survives the move.

“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.

ItemOutcomeImpactWhat happensMitigation
Published postspartialhighGhost's built-in Substack migrator imports content from the Substack export, but theme presentation, complex embeds, buttons, captions, paywall placement, and email-only markup require visual verification.Compare representative public, paid, image-heavy, embedded, and email-originated posts before changing the domain.
Post imagespartialhighThe migrator handles content and images, but every source and rendered destination image still needs availability and ownership checks.Create an image URL inventory, request every destination asset, and keep the export ZIP unchanged.
Free subscriberscleancriticalGhost's Substack migrator accepts the free-subscriber CSV and imports members, subject to the data present in the export.Record source counts immediately before export and reconcile Ghost free and email-subscribed segments after import.
Paid subscribers and accesspartialcriticalPaid migration requires Ghost to use the same Stripe account connected to Substack. Member access depends on matching Stripe customers and imported member records.Connect the same live Stripe account first, import paid members separately, and test access with current monthly, annual, canceled-at-period-end, and complimentary cases.
Existing paid subscription feespartialhighGhost documents that Substack's 10% fee continues on existing paid subscriptions after migration unless it is removed through Ghost's migration support process.Model the continuing fee, contact Ghost before cutover if removal matters, and do not promise immediate fee savings for existing subscriptions.
Member names, labels, notes, and creation datespartialmediumGhost member CSV supports email, name, note, subscribed_to_emails, Stripe customer ID, complimentary plan, labels, and created_at, but the Substack export may not contain every destination field.Use only documented columns, preserve the source CSV, and list every field intentionally left blank.
Email subscription preferencespartialcriticalGhost maps imported members through subscribed_to_emails behavior. Multiple newsletters and prior unsubscribe state require explicit review.Import free and paid files deliberately, reconcile subscribed and unsubscribed totals, and never globally opt in an uncertain record.
Custom-domain post URLsmanualcriticalSubstack commonly uses /p/ in post URLs while Ghost reserves /p/ for previews. Ghost documents a specific negative-lookahead redirect pattern.Upload the documented redirects.yaml rule, test real historic URLs and Ghost preview URLs, and verify single-hop 301 results.
Publication design and navigationmanualmediumSubstack theme, layout, navigation, signup surfaces, and email design do not become a Ghost theme automatically.Configure the Ghost theme, Portal, navigation, logo, colors, publication metadata, and email settings before import acceptance.
Comments and discussion historylostmediumThe documented built-in migration covers content and members but does not state that Substack comments and discussion history are imported.Treat comments as unavailable, preserve public or exported records where permitted, and tell readers before the source is retired.
Substack Notes, recommendations, and referral networklostmediumThese Substack network features have no documented mapping in the Ghost migrator.Export available records for reference, recreate only essential outbound recommendations, and do not claim network continuity.
Historical email analytics and delivery eventslostmediumCampaign history may remain visible in Substack, but opens, clicks, deliverability events, and historical dashboard analytics are not imported into Ghost.Export required reports and record baseline engagement before the first Ghost send.
Sending-domain reputationpartialcriticalGhost custom sending domains require DNS and DMARC. Ghost documents automatic warm-up over approximately six weeks for a new custom sending domain.Configure early, allow 15 minutes to 24 hours for DNS, use Ghost's warm-up process, and monitor the first several sends.
03Field and feature mapping

Where each thing goes.

SourceDestinationMethodNotes
Substack post titleGhost post titleautomaticCompare encoded punctuation and the rendered email subject where the post is resent.
Substack post bodyGhost post contentautomaticInspect embeds, captions, buttons, footnotes, dividers, and paywall boundaries.
Substack post slugGhost post slug plus redirecttransformKeep the slug and redirect /p/:slug to /:slug without breaking Ghost UUID preview routes.
Substack publication export ZIPGhost Substack migrator content uploadautomaticUpload the unchanged ZIP from Settings → Advanced → Import/Export.
Free-subscriber CSV emailGhost member emailautomaticEmail is required and acts as the reconciliation key.
Free-subscriber nameGhost member nameautomaticName is optional; do not synthesize it from email.
Subscriber email statussubscribed_to_emailstransformPreserve opt-out state and review Ghost behavior when multiple newsletters subscribe new members.
Paid-subscriber email and Stripe customerGhost member plus stripe_customer_idtransformConnect the same Stripe account first and verify the customer/subscription association after import.
Complimentary accesscomplimentary_planmanualGhost supports complimentary plans; map duration and access intentionally.
Substack sections or audience groupingsGhost labels and newslettersmanualThere is no safe generic mapping; define audience and sending semantics before import.
Custom publication domainGhost custom domainmanualActivate in Ghost and apply the exact DNS records Ghost provides for the chosen root or subdomain setup.
Custom sending domainGhost custom sending domainmanualRequires an eligible Ghost(Pro) plan, a custom publication domain, provided DNS records, and DMARC.
04Before you begin

Make the move recoverable.

Backup procedure

Create the source-of-truth backup

Preserve an immutable publication, audience, billing, URL, DNS, and analytics snapshot before Ghost imports or sends anything.

  1. Record publication settings, theme and navigation screenshots, custom domain, sender name and address, email schedule, sections, recommendations, paid plans, prices, benefits, and active automations.
  2. Create and download a new Substack publication export ZIP; record its timestamp, size, and post count.
  3. Download free- and paid-subscriber CSV files separately and record total, email-subscribed, unsubscribed, paid, canceled, complimentary, monthly, and annual counts.
  4. Export Stripe customer and active-subscription reports; record the account ID, currencies, products, prices, coupon behavior, tax settings, statement descriptor, and current Substack fee treatment.
  5. Crawl public post and page URLs, including /p/ paths, archives, about, subscribe, and high-traffic landing pages.
  6. Export available email and web analytics reports, DNS records, sending-domain records, and screenshots of scheduled drafts.
  7. Store untouched files with checksums and a manifest; perform all cleaning or mapping on copies.

Proof to capture: One dated manifest with file checksums, post and member segment counts, Stripe account ID and subscription totals, public URL count, DNS records, scheduled-send inventory, and named restore owner.

Transformation · Ghost Admin → Settings → Advanced → Import/Export → Substack

Run the built-in Substack content migration

Import supported content through Ghost's documented migration path.

  1. Enter the public Substack URL and upload the unchanged publication export ZIP.
  2. Upload free and paid subscriber CSVs in the requested stages.
  3. Before confirming import, compare Ghost's previewed post and member counts with the backup manifest.
  4. Save the migration confirmation and any warnings; do not repeat the import blindly after a partial result.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · Ghost member CSV import and exported reconciliation worksheet

Reconcile and enrich members

Preserve consent, paid access, and useful audience metadata without creating duplicate or over-subscribed members.

  1. Normalize email for comparison without altering the untouched source file.
  2. Map only documented Ghost member columns and leave uncertain consent values unsubscribed.
  3. Join paid members to the same live Stripe account using the documented customer association.
  4. Compare source and Ghost segments by email and explain missing, duplicate, invalid, suppressed, and merged records.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · Ghost redirects.yaml

Preserve custom-domain URLs

Keep Substack post links working while preserving Ghost preview routes.

  1. Start with Ghost's documented negative-lookahead redirect for /p/ post paths.
  2. Add explicit mappings for any changed static pages, sections, or nonstandard slugs.
  3. Test the complete high-value source URL set plus a newly generated Ghost preview URL.
  4. Reject loops, chains, temporary status codes, and any rule that catches Ghost's UUID preview paths.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · Ghost newsletters, sending domain, DMARC, seed list, and Stripe settings

Configure sending safely

Start Ghost newsletters without duplicate sends or avoidable reputation damage.

  1. Configure publication identity, newsletter, reply-to, unsubscribe, Portal, membership access, and custom domain before the first send.
  2. Add the exact custom sending-domain DNS records Ghost provides and wait until Ghost shows the domain as active.
  3. Create a seed segment across major mailbox providers and send a private test before scheduling the full audience.
  4. Keep every Substack campaign paused once Ghost owns sending; verify no duplicate automation or scheduled draft remains.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

05Handle with care

The things most likely to hurt.

These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.

Payments

Connecting the wrong Stripe account

criticalpossible likelihood

Ghost instructs paid Substack migrations to use the same Stripe account connected to Substack.

Consequence
Existing paid members may import without recognized subscriptions or correct paid access.
Mitigation
Record and compare the Stripe account ID before Ghost connection and before paid-member import.

Stop if: The connected live Stripe account ID differs from the account containing current Substack subscriptions.

Payments

Assuming existing Substack fees disappear

highlikely likelihood

Ghost states that Substack's 10% fee continues on existing paid subscriptions unless separately removed.

Consequence
Revenue projections and member communications can be wrong.
Mitigation
Model continuing fees and resolve removal with Ghost before promising savings.

Stop if: The business case requires immediate fee removal but the removal path is not confirmed.

Members

Overwriting consent during member import

criticalpossible likelihood

Ghost's subscribed_to_emails field controls newsletter subscription behavior and interacts with multiple-newsletter defaults.

Consequence
Unsubscribed people can receive email or intended recipients can be suppressed.
Mitigation
Reconcile source consent states, use conservative mappings, and audit every destination newsletter segment.

Stop if: Opted-in and opted-out totals cannot be independently reconciled.

Routing

Breaking /p/ links or Ghost preview links

criticallikely likelihood

A simple /p/* redirect can capture Ghost's own post-preview URLs.

Consequence
Historic links can break or editors can lose preview access.
Mitigation
Use Ghost's documented negative-lookahead pattern and test both historic posts and UUID previews.

Stop if: Any high-value Substack URL or Ghost preview URL does not reach the intended page.

Email cutover

Sending before domain and seed checks

criticalpossible likelihood

Custom sending-domain DNS can take 15 minutes to 24 hours, and Ghost warms a new domain over approximately six weeks.

Consequence
Authentication, delivery, reputation, replies, or unsubscribe behavior can fail at full-audience scale.
Mitigation
Activate DNS early, allow Ghost's warm-up, send to a representative seed list, and monitor mailbox placement.

Stop if: Ghost does not show the sending domain active, DMARC is absent, or any seed authentication, link, reply, or unsubscribe test fails.

Email cutover

Duplicate full-audience sends

criticalpossible likelihood

Scheduled or automated Substack and Ghost campaigns can overlap during the move.

Consequence
Subscribers can receive duplicate messages and generate complaints or unsubscribes.
Mitigation
Inventory scheduled mail, assign one sending system, pause the other, and require a named send owner.

Stop if: Any unowned campaign, automation, or scheduled draft remains active in either platform.

06Precise timeline

Do the work in this order.

Estimate forUp to 2,000 posts, 25,000 members, one custom domain, one primary newsletter, optional Stripe paid members
Total elapsed5–8 calendar days before first full send
Active work10–16 hours
BufferReserve 24 hours for DNS and import review; treat Ghost's approximately six-week custom sending-domain warm-up as post-cutover monitoring, not active migration time.
01
Day 1Inventory publication, audience, billing, and URLs1 day
02
Day 2Configure Ghost, Stripe, domain, and sending1–2 days
03
Day 3Import content and membersHalf to one day
04
Day 4Verify content, access, redirects, and seed delivery1 day
05
Day 5Capture the final delta and switch the publication2–4 hours
06
Days 6–8Send deliberately and monitor2–3 days before cleanup; six weeks for full sending-domain warm-up
  1. Day 1 · inventory-backup

    Inventory publication, audience, billing, and URLs

    2–3 hours active1 day elapsedAllow Substack export generation to finish waiting
    • Capture settings, plans, scheduled mail, domains, URLs, analytics, content export, member CSVs, Stripe reports, and counts.
    • Store untouched files with checksums and create the reconciliation workbook.
    • Choose the exact first Ghost send date and working-backwards cutover window.
    Stop / go checkpoint

    Is the source state complete and frozen for planning?

    Go when: Post, audience, paid-subscription, URL, DNS, and scheduled-send inventories reconcile.

    Stop when: A paid segment, consent state, scheduled campaign, or required owner is unknown.

  2. Day 2 · ghost-setup

    Configure Ghost, Stripe, domain, and sending

    2–4 hours active1–2 days elapsed15 minutes to 24 hours for custom sending-domain DNS; approximately six weeks of automatic warm-up after activation waiting
    • Configure Ghost publication, theme, navigation, Portal, access, newsletters, tiers, staff, and email identity.
    • Connect the same live Stripe account and verify its account ID.
    • Activate the publication and sending domains using Ghost-provided DNS records and DMARC.

    Depends on: inventory-backup

    Stop / go checkpoint

    Is Ghost safe to receive members?

    Go when: The correct Stripe account is connected, domains are active, membership settings are explicit, and no production campaign is enabled.

    Stop when: Stripe, DNS, DMARC, plan access, or publication ownership is uncertain.

  3. Day 3 · import

    Import content and members

    2–3 hours activeHalf to one day elapsedAllow the Ghost migrator and member-import email confirmation to complete waiting
    • Upload the unchanged Substack export ZIP and separate free and paid member files through the built-in migrator.
    • Review Ghost's proposed counts before import and save every result or warning.
    • Reconcile posts, free members, paid members, subscribed members, and Stripe status.

    Depends on: ghost-setup

    Stop / go checkpoint

    Did the import preserve the recorded source state?

    Go when: All counts match or each variance has an evidence-backed explanation and owner.

    Stop when: Paid access, consent, duplicates, content totals, or import errors cannot be reconciled.

  4. Day 4 · preview-verify

    Verify content, access, redirects, and seed delivery

    3–4 hours active1 day elapsedAt least one hour between DNS activation and final seed test; longer if Ghost still reports verification pending waiting
    • Check representative public, member-only, paid, image-heavy, and embedded posts.
    • Upload and test redirects using historic /p/ URLs plus Ghost preview URLs.
    • Test free, paid, canceled, complimentary, unsubscribed, and new signup member journeys.
    • Send only to the seed list and verify authentication, links, reply, unsubscribe, and mailbox delivery.

    Depends on: import

    Stop / go checkpoint

    Can Ghost own the public domain and next send?

    Go when: Every blocking content, URL, member, payment, DNS, and seed-delivery check passes.

    Stop when: Any test recipient receives incorrect access, duplicate mail, broken links, or failed authentication.

  5. Day 5 · cutover

    Capture the final delta and switch the publication

    1–2 hours active2–4 hours elapsedObserve DNS and certificate activation before announcing waiting
    • Pause Substack publishing and scheduled sends; record the freeze time.
    • Import the final post and member delta and rerun count reconciliation.
    • Change the publication domain, run production checks, and keep the full Ghost audience unscheduled.

    Depends on: preview-verify

    Stop / go checkpoint

    Keep Ghost public or return the domain to Substack?

    Go when: Public URLs, SSL, member login, paid access, signup, redirects, analytics, and seed delivery pass on the real domain.

    Stop when: A blocking production check fails or a source delta is unexplained.

  6. Days 6–8 · first-send-monitor

    Send deliberately and monitor

    1 hour plus 20 minutes daily active2–3 days before cleanup; six weeks for full sending-domain warm-up elapsedWait 24 hours after the first full send before retiring any source send configuration waiting
    • Review the final audience segment and ensure Substack has no active campaign.
    • Send the first Ghost newsletter at the planned time with a named operator and observer.
    • Monitor accepted, delivered, bounced, complained, unsubscribed, clicked, replied, and paid-access signals.

    Depends on: cutover

    Stop / go checkpoint

    Can source sending be retired?

    Go when: The first full send completes without a rollback trigger and 24-hour metrics are within the agreed baseline.

    Stop when: Duplicate sends, authentication failures, abnormal bounces or complaints, broken links, or incorrect paid access appear.

07The point of change

Cut over with a way back.

Go live

Cutover

Make Ghost the public and sending system without losing the last Substack changes or sending the audience twice.

Recommended window: Cut over 48–72 hours before the next planned newsletter, during support hours, with the Ghost owner, DNS owner, and Stripe owner available.

  1. Begin the publication and campaign freeze; record UTC time and confirm all Substack scheduled sends and automations are paused.
  2. Export and import the final content and member delta; reconcile segment and Stripe counts again.
  3. Confirm Ghost custom domain, SSL, sending domain, DMARC, redirects, Portal, newsletter, tiers, and analytics configuration.
  4. Change the publication-domain DNS exactly as Ghost specifies and preserve the previous records.
  5. Run blocking production checks for content, redirects, member access, signup, paid access, email preferences, analytics, and seed delivery.
  6. Keep the full Ghost audience unscheduled until the public-domain report passes; announce the move only after approval.

Proof to capture: Freeze timestamp, final post and member reconciliation, Stripe account ID and paid totals, before/after DNS records, redirect results, member-journey captures, seed message headers, and named approval.

Return to safety

Rollback

Return the public domain and next send to Substack without creating duplicate campaigns or corrupting paid access.

Deadline: The cleanest rollback point is before the first full-audience Ghost send; keep Substack available and its sending configuration intact for at least seven days after that send.

  1. Declare rollback, cancel any Ghost campaign, disable new Ghost campaign scheduling, and preserve import and delivery logs.
  2. Restore the recorded publication-domain DNS values for Substack and confirm SSL and public URLs.
  3. Keep Ghost member and Stripe data unchanged for investigation; do not disconnect the shared Stripe account during an active incident.
  4. Reconcile any post, signup, unsubscribe, or payment changes made after freeze and assign a system of record for each.
  5. Confirm exactly one platform owns the next send and communicate the revised schedule.

Proof to capture: The custom domain serves Substack, critical posts and signup paths work, no duplicate campaign is scheduled, paid subscriptions remain active in the same Stripe account, and all cutover deltas are accounted for.

Rollback immediately when
  • Paid-member access or Stripe association fails for any representative active plan.
  • Email opt-in and opt-out totals cannot be reconciled.
  • Historic high-value URLs or Ghost preview URLs fail after one redirect correction.
  • Sending-domain authentication, seed delivery, reply, unsubscribe, or link checks fail.
  • A production-blocking problem cannot be corrected and fully reverified within two hours.
08Verification report

Prove the migration worked.

Every blocking check must pass. Capture the evidence before cleanup begins.

0%
Interactive report preview0 / 10 checks passed
PassIDCheckMethodExpected resultEvidence
CNT-01BlockingPost reconciliationCompare source export posts with Ghost posts by slug, date, title, visibility, and access level.Every expected post exists once or has an approved exception.Attach the post reconciliation CSV and exception list.
VIS-01BlockingRepresentative render parityCompare public, paid, image-heavy, embedded, and email-originated samples on desktop and mobile.Headings, body, images, captions, embeds, buttons, paywall boundary, metadata, and links are usable and deliberate.Attach paired source/destination captures.
MEM-01BlockingAudience segment reconciliationCompare total, free, paid, subscribed, unsubscribed, complimentary, monthly, and annual counts.Counts match or every variance is an explained invalid, duplicate, suppressed, or intentionally omitted record.Attach the segment table and variance notes.
PAY-01BlockingStripe account and paid accessConfirm the live Stripe account ID and test active monthly, annual, canceled-at-period-end, and complimentary members.The account ID matches Substack's account and each test member receives the correct Ghost access without a new charge.Attach redacted Stripe and Ghost member captures.
CON-01BlockingEmail preference preservationSample subscribed and unsubscribed records from each imported file and compare their Ghost newsletter state.No opted-out member is subscribed and no unexplained global opt-in occurred.Attach the sampled member IDs and aggregate counts.
URL-01BlockingHistoric /p/ URLs and Ghost previewsRequest all high-value source URLs, a random historic sample, and a newly generated Ghost UUID preview URL.Historic posts use one 301 to the correct post; Ghost preview URLs still render and are not caught by the redirect.Attach status, redirect chain, and final URL output.
DNS-01BlockingPublication domain and SSLResolve the custom domain from multiple public resolvers and request root, www or chosen subdomain, and critical paths over HTTPS.The canonical hostname serves Ghost with a valid certificate and the alternate hostname redirects deliberately.Attach DNS answers, certificate details, and HTTP results.
EML-01BlockingSeed delivery and authenticationSend to controlled addresses at major mailbox providers and inspect authentication, from, reply-to, links, images, unsubscribe, and placement.Ghost shows the domain active; SPF, DKIM, and DMARC align as configured; every seed message works and unsubscribes once.Attach redacted message headers, inbox captures, and unsubscribe result.
SCH-01BlockingSingle sending systemReview scheduled, draft, automated, and recurring sends in both platforms immediately before the first full send.Only one named Ghost campaign is eligible to send and Substack has no active campaign.Attach schedule captures and the named send owner.
ANA-01BlockingWeb and newsletter measurementGenerate one labeled pageview, signup, and test-email click on the production domain.The intended properties record the correct domain, path, campaign, and conversion once.Attach realtime or debug captures.
09Post-migration cleanup

Remove the scaffolding safely.

Safe after: One successful full-audience Ghost send, 24 hours of acceptable delivery metrics, seven stable public-domain days, and a signed verification report.

  1. Archive the final Substack export ZIP, free and paid member CSVs, Stripe reports, URL inventory, DNS records, analytics, and verification evidence with checksums.
  2. Cancel or remove every remaining Substack scheduled send and automation; confirm Ghost owns the next send.
  3. Update Stripe public details and statement descriptor where appropriate, while preserving existing subscription products and prices.
  4. Document any continuing Substack fee on existing subscriptions and the owner of its removal process.
  5. Revoke migration-only users and tokens; remove temporary seed labels and test members without deleting required evidence.
  6. Keep Substack readable for the agreed retention period before canceling; preserve content and billing records required for tax, support, and disputes.
  7. Update support replies, privacy policy, terms, unsubscribe documentation, publishing runbook, sender ownership, and next review date.
10Experiences from the field

When the plan met reality.

First-hand accounts are preferred. Vendor case studies are labeled, and every note below is an editorial paraphrase—follow the link for the full context.

First-person accountRey Katz · Amplify Respect

I migrated from Substack to Ghost. Here's all the details

Rey Katz explains a completed move from Substack to Ghost that was more difficult and more expensive than expected. Ghost restored a stronger sense of owning the site and mailing list, but it introduced hosting cost and lacked Substack’s built-in social and recommendation network. The migration included decisions around Ghost Pro versus self-hosting, DNS, design, and email deliverability rather than being only a content import.

What they recommend
  • Compare managed Ghost Pro with self-hosting using total operational and email-delivery cost, not hosting price alone.
  • Plan DNS, branding, sender authentication, and deliverability as first-class workstreams alongside posts and subscribers.
Worth noticing
  • Greater ownership came with direct platform cost and the loss of Substack’s discovery and social features.
  • The technical move reached beyond content and subscribers into identity, design, DNS, and mail operations.
Sources and maintenance

Built to be reviewed.

Tested 2026-07-18. Next scheduled review: 2026-10-18.

  1. Ghost: Migrating from SubstackAccessed 2026-07-18
  2. Ghost: Import membersAccessed 2026-07-18
  3. Ghost: Connect StripeAccessed 2026-07-18
  4. Ghost: Custom sending domainsAccessed 2026-07-18
  5. Ghost: Custom publication domainsAccessed 2026-07-18