npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@plugdash/fromghost

v0.2.0

Published

Import a Ghost JSON export into EmDash

Downloads

709

Readme

@plugdash/fromghost

Imports a Ghost JSON export (Settings > Labs > Export your content) into EmDash. Registers a Ghost import source with EmDash's import registry, so posts, pages, tags and authors go through EmDash's own media download, taxonomy and content-creation pipeline.

EmDash's admin import screen only lists WordPress sources, so "Ghost Export File" does not appear there. Run the import through a script or the import API. Remove the plugin after the import.

Install

pnpm add @plugdash/fromghost

Register

// astro.config.mjs
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { fromghostPlugin } from "@plugdash/fromghost";

export default defineConfig({
	integrations: [
		emdash({
			plugins: [fromghostPlugin({ siteUrl: "https://blog.example.com" })],
		}),
	],
});

Options are passed to createPlugin(options) in the server runtime, so they are active in a production build.

Config options

Passed to fromghostPlugin({ ... }):

| Option | Type | Default | Description | | ---------------- | -------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | targetCollection | string | "posts" | Collection suggested for Ghost posts | | status | n/a | - | Not configurable - status comes from each post's own Ghost status (see below) | | preserveSlugs | boolean | true | Keep Ghost's slugs instead of regenerating from title | | importImages | boolean | true | Carry feature and inline images over | | importTags | boolean | true | Carry Ghost tags over as taxonomy terms | | siteUrl | string | "" | The Ghost site's URL, to resolve __GHOST_URL__ image paths | | paidPostsAs | "draft" \| "publish" \| "skip" | "draft" | Posts with Ghost visibility members, paid or tiers. The export holds their full body, so the default keeps them off the public site. meta.visibility is recorded either way |

siteUrl matters: Ghost writes images and links as __GHOST_URL__/... rather than an absolute URL. With siteUrl set, every placeholder in the post HTML is replaced before conversion, and inline images are listed in the analysis attachments so EmDash downloads them. Without it, site-relative feature images are skipped (the import continues without them).

Recoverable problems (Lexical-only drafts, duplicate slugs, unresolved images) are returned as warnings on the analysis. emdash 1.0.1's ImportAnalysis type has no warnings field, so this is an extra property on the object.

Import status (draft vs. published) is not a plugin setting - it is read straight from each post's own Ghost status via fetchContent's includeDrafts option, which EmDash's import screen controls.

Field mapping

| Ghost field | EmDash field | | ------------------------------------------- | -------------------------------------------------- | | title | title | | slug | slug (or regenerated, see preserveSlugs) | | html | content, via htmlToPortableText | | custom_excerpt (falls back to excerpt) | excerpt | | feature_image | featuredImage (after __GHOST_URL__ resolution) | | published_at (falls back to created_at) | date | | updated_at | modified | | meta_title | meta.seoTitle | | meta_description | meta.seoDescription | | tags via posts_tags | tags (public tags only) | | author via posts_authors | author (first author's slug) |

What it does

  • Parses Ghost's { db: [{ meta, data }] } export shape, and the looser { data } / { posts } shapes some third-party exporters use
  • Handles both Ghost 5 (type: "post" | "page") and Ghost 4 (page: boolean) post-type flags
  • Converts post body HTML to Portable Text via the same shared @plugdash/html-to-portable-text converter fromsubstack uses
  • Falls back to a plain-text recovery of Ghost 5 Lexical drafts that were never rendered to HTML (html: null), and warns when it does
  • Resolves tags and the primary author through the posts_tags / posts_authors join tables, in Ghost's own sort order
  • Skips duplicate slugs (keeping the first occurrence) and warns
  • Skips a feature image that cannot be resolved to an absolute URL and warns, rather than failing the whole post
  • Reports post/page counts, tag counts, attachment counts (feature and inline images) and warnings through ImportAnalysis
  • Loads the HTML converter (and linkedom) only when an import runs, so having the plugin registered costs nothing at startup

What it does not do

  • Does not convert Mobiledoc (Ghost 3 and older editor format) - such posts import with an empty body and a warning
  • Does not download or upload media itself - featuredImage is handed to EmDash's import pipeline as a URL, which owns the actual download
  • Does not import Ghost members, newsletters, or comments
  • Does not preserve Ghost's internal tags (visibility: "internal") as taxonomy - those are Ghost's own bookkeeping
  • Cannot be sandboxed - it registers directly into EmDash's import-source registry
  • Does not appear in the admin import screen (WordPress only in emdash 1.0.1)