A collection of tools for migrating to Ghost.
Each tool has its own detailed documentation:
- Ghost
- beehiiv
- beehiiv API
- beehiiv API Members
- beehiiv Members
- Blogger
- Buttondown
- Chorus
- Curated
- Curated members
- Jekyll
- Letterdrop
- Libsyn
- Mailchimp Members
- Medium Content
- Medium Members
- Squarespace
- Stripe
- Substack
- Substack members
- Tiny News
- Tiny News Members
- WordPress API
- WordPress XML
Migrate is a set of command line tools, install them globally:
npm install --global @tryghost/migrate
Run migrate --help to see a list of available commands.
Basic usage is migrate [source] source-info:
E.g.
migrate medium --pathToZip /path/to/export.zip
migrate wp-api --url https://mywpsite.com
Each source comes with optional flags to customise the migration:
migrate [source] --help will give more detail
This is a mono repository, managed with Nx and pnpm workspaces.
git clonethis repo &cdinto it as usualpnpm installto install all dependencies
To make sure the TypeScript packages are built (immediately and after file changes), use
pnpm build:watchOr run pnpm build once if you don't need the watching.
To run a local development copy, cd into this directory, and use pnpm dev instead of migrate like so:
pnpm dev [source]pnpm lintrun just eslintpnpm testrun lint and tests
Knip is used to find unused dependencies, exports, and files across the monorepo. Run it with:
pnpm knipSome dependencies are intentionally kept despite not being directly imported (e.g. optional peer dependencies like sharp). These are listed in knip.json under ignoreDependencies for the relevant workspace.
Packages are published to npm automatically via GitHub Actions using OIDC trusted publishers — no npm token is needed.
- Run
pnpm shiplocally to interactively version bump, tag, and push to git- Uses
nx releaseunder the hood — prompts per-package for the bump level - Also updates any packages which depend on changed packages
- Uses
- The push to
maintriggers the publish workflow, which builds and publishes all bumped packages to npm
You can also trigger a dry-run from the Actions tab to preview what would be published without actually publishing.
When publishing a package for the first time:
- Create the package in
packages/(see CLAUDE.md for the template) - Set
"version": "0.0.0"in itspackage.json - Commit and merge to
main - From the repo root, version, tag, and push just the new package:
pnpm ship:first-release --projects=@tryghost/mg-<name>
- Manually publish the package to npm (CI can only update packages that already exist on npm):
cd packages/mg-<name> pnpm build && npm publish --access public # If the package has a prerelease tag, add --tag pre pnpm build && npm publish --access public --tag pre
- Register the package as a trusted publisher so CI can handle future releases:
npm trust github <package-name> --repo TryGhost/migrate --file publish.yml --yes # Example: npm trust github @tryghost/mg-example-package --repo TryGhost/migrate --file publish.yml --yes
Copyright (c) 2013-2026 Ghost Foundation - Released under the MIT license.