11 min read

Ghost Nodes: The Complete Reference

A self-documenting guide to every Ghost Lexical node type with org-mode source examples.
Ghost Nodes: The Complete Reference

Introduction

This is a self-documenting reference for ox-ghost, the Emacs org-mode export backend that converts .org files to Ghost's Lexical JSON format.

Every section shows:

  1. The rendered resultas it appears in Ghost
  2. An Org Sourcetoggle below (click to see the org-mode code)

At the end, you can download this very document and its Lexical JSON output.

๐Ÿ’ก
Click any "Org Source" toggle to see the org-mode code that produces the rendered result above it. Copy and adapt for your own posts!

Text Fundamentals

Paragraphs

The simplest element. Just write text with blank lines between paragraphs.

This is the first paragraph. It can span multiple lines in your org file - they'll be joined.

This is a second paragraph, separated by a blank line.

Org Source

This is the first paragraph. It can span multiple
lines in your org file - they'll be joined.

This is a second paragraph, separated by a blank line.

Text Formatting

Org-mode formatting maps to Lexical's text format bitmask:

Format Org Syntax Bitmask
Bold *bold* 1
Italic /italic/ 2
Strikethrough +struck+ 4
Underline _underline_ 8
Code ==code== 16

Table Org Source

| Format        | Org Syntax      | Bitmask |
|---------------+-----------------+---------|
| Bold          | *bold*          |       1 |
| Italic        | /italic/        |       2 |

Format text with bold, italic, strikethrough, underline, and code.

Combine them: bold-italic, bold-underline, all three.

Org Source

Format text with bold, italic, strikethrough, underline, and code.

Combine them: /bold-italic/, _bold-underline_, /+all three+/.

External link: Ghost CMS

Plain URL auto-links: https://ii.coop

Email: Contact us

Org Source

External link: Ghost CMS

Plain URL auto-links: https://ii.coop

Email: Contact us

Line Breaks

Force line breaks with double backslash.

Line one
Line two
Line three

Org Source

Line one\\
Line two\\
Line three

Headings

Org headlines become Lexical headings. The post title is H1, so content starts at H2.

Org Stars Lexical Tag Typical Use
* H2 Major sections
** H3 Subsections
*** H4 Deep structure
**** H5 Rarely needed
***** H6 Almost never

Org Source

โ–ผ H2 - Major Section (one star)
*โ–ฝ H3 - Subsection (two stars)
**โฏ† H4 - Sub-subsection (three stars)
***โ–ฟ H5 - Rarely needed (four stars)
****โ–พ H6 - Avoid this deep (five stars)
โš ๏ธ
Deep nesting (H5, H6) often signals your content structure needs rethinking. Flat is usually better.

Lists

Unordered Lists

  • First item
  • Second item with bold
  • Third item with link

Org Source

โ€“ First item
โ€“ Second item with bold
โ€“ Third item with link

Ordered Lists

  1. First step
  2. Second step
  3. Third step

Org Source

1. First step
2. Second step
3. Third step

Nested Lists

  • Parent item
    • Child item
    • Another child
      • Grandchild
  • Back to parent
  • Numbered parent
    1. Numbered child
    2. Another child
  • Back to parent

Org Source

โ€“ Parent item
  โ€“ Child item
  โ€“ Another child
    โ€“ Grandchild
โ€“ Back to parent

1. Numbered parent
   1. Numbered child
   2. Another child
2. Back to parent

Checkbox Lists

  • Unchecked task
  • Completed task
  • In progress

Org Source

โ€“ โ–ก Unchecked task
โ€“ โ–กx Completed task
โ€“ โ–กโ€“ In progress

Blockquotes

The best way to predict the future is to invent it. โ€” Alan Kay

Org Source

QUOTE
The best way to predict the future is to invent it.
โ€” Alan Kay
QUOTE

Horizontal Rules

Content above.


Content below.

Org Source

Content above.

-----

Content below.

Code Blocks

Code blocks support syntax highlighting via Prism.js.

def hello(name):
    return f"Hello, {name}!"

print(hello("Ghost"))
None

Org Source

SRC python
def hello(name):
    return f"Hello, {name}!"

print(hello("Ghost"))
SRC

More Languages

// JavaScript
const greet = (name) => `Hello, ${name}!`;
console.log(greet("World"));
Hello, World!
undefined
#!/bin/bash
echo "Hello from $(hostname)"
Hello from nextral.sharing.io
;; Emacs Lisp
(defun greet (name)
  (message "Hello, %s!" name))
greet

Callout Blocks

Callouts highlight important information with color-coded backgrounds.

๐Ÿ’ก
Blue (:color blue) โ€” Tips, information, general highlights. Default color if not specified.

Org Source

CALLOUT :emoji "๐Ÿ’ก" :color blue
Your message here. Supports formatting.
CALLOUT

All Seven Colors

โœ…
Green (:color green) โ€” Success, best practices, "do this".
โš ๏ธ
Yellow (:color yellow) โ€” Warnings, caution, pay attention.
โŒ
Red (:color red) โ€” Errors, danger, "don't do this".
โœจ
Purple (:color purple) โ€” Special features, highlights.
๐ŸŽจ
Pink (:color pink) โ€” Creative, playful content.
๐Ÿ“
Grey (:color grey) โ€” Neutral notes, supplementary info.

Common Emoji Names

Emoji Name Use Case
๐Ÿ’ก bulb Tips, ideas
โœ… white_check_mark Success, do this
โš ๏ธ warning Caution
โŒ x Error, don’t
๐Ÿš€ rocket Launch, deploy
๐Ÿ“ memo Notes
โœจ sparkles Special

Toggle Blocks

Toggles hide content behind a clickable heading. They support rich HTML content!

Click to expand

Hidden content here. Supports formatting, lists, and code:

print("Code inside a toggle!")
None

Org Source

TOGGLE :heading "Click to expand"
Hidden content here. Supports formatting, lists, and code:

SRC python
print("Code inside a toggle!")
SRC
TOGGLE

Toggle with a list

Toggles are great for:

  • FAQs
  • Technical details
  • Optional deep-dives
  • Spoiler warnings

Aside Blocks

Asides provide tangential information with distinct styling.

Tangential content here. Supports formatting and links.

Org Source

ASIDE
Tangential content here. Supports formatting and links.
ASIDE

Button Blocks

Buttons create prominent call-to-action links.

Org Source

BUTTON :url "https://example.com" :alignment center
Button Text
BUTTON

Header Cards

Full-width banners with text overlay.

Small Header

Medium Header

Large Header

Org Source

HEADER :size small
Header Text
HEADER

Signup Forms

Capture email subscribers.

Regular layout:

Wide layout:

Split layout:

Org Source

SIGNUP :layout regular :buttonText "Subscribe"
SIGNUP

Email-Only Content

Content that only appears in newsletter emails, not on the web post.

๐Ÿ“ง
The EMAIL block below will only be visible to newsletter subscribers. It won't appear on the website version of this post.

Org Source

EMAIL
<p>Thanks for being a subscriber!</p>
<p>This only appears in the <strong>email version</strong>.</p>
EMAIL
๐Ÿ’ก
Use EMAIL blocks for subscriber-exclusive content, special offers, or personalized messages that don't belong on the public web version.

Call to Action (CTA)

Prominent sections to drive reader action.

Simple and clean. Great for subtle prompts.
Learn More
Bold and attention-grabbing. For important conversions.
Get Started
Branded styling. Shows site identity.
Join Us

Org Source

CTA :layout minimal :buttonText "Learn More" :url "https://example.com"
Compelling message here.
CTA

Bookmark Cards

Rich link previews with metadata.

Ghost: The Creator Economy Platform
The world's most popular modern publishing platform for creating a new media platform.
TryGhost/Ghost
Independent technology for modern publishing, memberships, subscriptions and newsletters.

Org Source

BOOKMARK :url "URL" :title "Title" :description "Desc" :thumbnail "IMG" :icon "ICO"
Fallback text
BOOKMARK

Product Cards

Showcase products with optional buy buttons.

Premium Widget Pro

Buy Now - $49

Advanced Course (no button)

Org Source

PRODUCT :url "https://shop.example.com/item" :buttonText "Buy Now"
Product Title
PRODUCT

Images

Width Attribute Use Case
Regular :cardWidth regular Inline with text
Wide :cardWidth wide Break out of column
Full :cardWidth full Edge to edge

Regular width (default):

Laptop with code

Wide width:

Programming workspace

Full width:

Panoramic setup

Org Source

ATTR_LEXICAL: :cardWidth wide
Alt text description

Video Blocks

Attribute Description Example
:src Video URL (required) https://.../v.mp4
:width Width in pixels 1920
:height Height in pixels 1080
:duration Duration in seconds 30
:mimeType MIME type video/mp4
:thumbnailSrc Poster image URL https://.../t.jpg

Org Source

VIDEO :src "URL" :width 1920 :height 1080 :duration 30 :mimeType "video/mp4"
Caption text
VIDEO
๐Ÿ“
Video attributes can be auto-populated using ghost-publish-enrich-buffer which probes uploaded files for metadata.

Audio Blocks

Attribute Description Example
:src Audio URL (required) https://...
:duration Duration in seconds 120
:mimeType MIME type audio/mpeg

Org Source

AUDIO :src "URL" :duration 120 :mimeType "audio/mpeg"
Track title
AUDIO

File Downloads

Org Source

FILE :src "URL" :fileName "document.pdf"
Download description
FILE

Org Source

GALLERY
Alt 1
Alt 2
Alt 3
GALLERY

Embed Blocks

Embed external content (YouTube, Twitter, etc.).

โš ๏ธ
The :html attribute contains the embed code. Ghost renders this when the :url matches a supported oEmbed provider.

Org Source

EMBED :url "https://youtube.com/watch?v=..." :html "<iframe>...</iframe>"
Fallback title
EMBED

Asciinema Player

Embed terminal recordings with the asciinema player. Perfect for demos, tutorials, and documentation.

Star Wars Demo

The classic ASCII Star Wars animation via telnet:

Star Wars Episode IV (ASCII)

Org Source

ASCIINEMA :src https://asciinema.org/a/8.cast :speed 1 :theme monokai :title "Star Wars Episode IV (ASCII)" :idle-time-limit 2
ASCIINEMA

Player Options

Attribute Description Example
:src Cast file URL or path https://.../a.cast
:speed Playback speed 1.5
:theme Player theme solarized-dark
:poster Poster frame npt:0:30
:cols / :rows Terminal size 80 / 24
:autoplay Auto-play on load true
:loop Loop playback true
:start-at Start time (seconds) 10
:idle-time-limit Max idle between frames 2
:fit Fit mode width
:controls Show controls true
:title Title above player Demo Recording

Org Source

ASCIINEMA :src https://asciinema.org/a/8.cast :speed 1.5 :theme solarized-dark :poster "npt:0:10" :autoplay true :loop true :start-at 5 :idle-time-limit 2 :fit width :controls true :title "Full Options Example"
ASCIINEMA

Available Themes

๐ŸŽจ
Themes: asciinema, tango, solarized-dark, solarized-light, monokai, dracula, nord, github-dark, github-light

With Custom Settings

Org Source

ASCIINEMA :src https://asciinema.org/a/8.cast :speed 2 :theme dracula :autoplay true :loop true :start-at 5 :fit width
ASCIINEMA

Local Cast Files

When using local files, they're tracked for upload:

Org Source for Local Files

ASCIINEMA :src ./recordings/demo.cast :speed 1.5 :theme github-dark
ASCIINEMA

This adds to metadata.json:

{
  "media_files": [
    {
      "local": "/full/path/to/recordings/demo.cast",
      "dest": "/content/media/casts/demo.cast"
    }
  ]
}

Tables

Tables export as HTML blocks (Lexical lacks native table support).

Feature Status Notes
Headings Done H2-H6 supported
Lists Done Nested too
Callouts Done 7 colors
Tables Done Via HTML export

Org Source

| Column A | Column B | Column C |
|----------+----------+----------|
| Value 1  | Value 2  | Value 3  |
| Value 4  | Value 5  | Value 6  |

REPL Blocks

REPL blocks combine code with output in styled presentations.

Simple (default)

2 + 2
4

Labeled

for i in range(3):
    print(f"Item {i}")

Output:

Item 0
Item 1
Item 2

Callout

echo "Build succeeded!"
โœ…
Build succeeded!

Org Source

REPL :style callout :emoji "โœ…" :color green
SRC python
print("hello")
SRC

RESULTS:
: hello
REPL

Toggle

Show implementation

def fibonacci(n): a, b = 0, 1 for _ in range(n): yield a a, b = b, a + b list(fibonacci(8))
[0, 1, 1, 2, 3, 5, 8, 13]

Aside

Raw HTML

When Lexical nodes aren't enough, embed raw HTML.

Custom HTML Block

Any HTML, CSS, or embedded widgets.

Org Source

EXPORT html
<div style="background: #667eea; padding: 2rem; color: white;">
  Custom HTML content
</div>
EXPORT

Raw Lexical JSON

Insert raw Lexical JSON directly (advanced).

This is useful for nodes ox-ghost doesn't yet support.

Org Source

EXPORT lexical
{"type":"paragraph","version":1,"children":[...]}
EXPORT

The Export Pipeline

Step 1: Write Your Org File

Create your content using the patterns shown above.

Step 2: Export to Lexical JSON

cd /path/to/ox-ghost
./org-to-lexical.sh input.org output.json

Step 3: Validate the Output

node validate-lexical.js output.json
# With HTML preview:
node validate-lexical.js output.json --html preview.html

Step 4: Create Ghost Post

cd /srv/ii.coop
node ghost.js post create "Post Title" output.json --format lexical

Step 5: Upload Media (Optional)

For video/audio/files, upload first then update the org with URLs:

# Upload media file
node ghost.js upload /path/to/video.mp4

# Returns: https://coop.ghost.io/content/media/2026/01/video.mp4
# Add this URL to your :src attribute

Step 6: Enrich Media Metadata

Auto-populate width/height/duration from uploaded files:

;; In Emacs, with ghost-publish.el loaded:
M-x ghost-publish-enrich-buffer

This probes each media URL and adds the metadata attributes.

Membership Paywall

The PAYWALL block marks where free content ends and members-only content begins.

๐Ÿ”’
Everything below this paywall is only visible to paying members. Free readers will see a signup prompt instead.

๐ŸŽ‰ Secret Members-Only Content

Congratulations! You've unlocked the exclusive members-only section.

๐Ÿฆ„
You found the unicorn! This content is hidden behind the paywall. Only paying members can see it. Feel special.

Here's what free readers are missing:

  • The meaning of life: 42
  • The best programming language: the one that pays your bills
  • The secret to happiness: good coffee and clean code

Org Source

PAYWALL
PAYWALL

Content after the paywall is members-only.

Download This Document

This post is self-documenting. Download the source files:

โœ…
These are the actual files! Download the org, modify it, re-export, and create your own posts using the same pipeline.

Summary: All Node Types

Category Nodes
Text Paragraph, Heading (H2-H6), Line Break
Format Bold, Italic, Strikethrough, Underline, Code, Link
Structure Blockquote, Horizontal Rule, Table (as HTML)
Lists Ordered, Unordered, Nested, Checkbox
Code Code Block (syntax highlighted)
Cards Callout (7 colors), Toggle, Aside, Button, Bookmark
Media Image (3 widths), Video, Audio, Gallery, File, Embed
Terminal Asciinema (9 themes, full player options)
Ghost Header (3 sizes), Signup (3 layouts), CTA (3 layouts)
Product Product Card
Newsletter Email (email-only content), Paywall (members-only)
Special REPL (5 styles), Raw HTML, Raw Lexical
ox-ghost is open source. Contributions welcome!
View on GitHub