Long-Form Content on Nostr (NIP-23)
Long-Form Content (NIP-23)
Articles, blog posts, and deep dives on Nostr. Permanent, editable, and censorship-resistant.
Kind 30023 — Long-form Article
Addressable replaceable event. The d tag is the slug/identifier.
{
"id": "a1b2c3...",
"pubkey": "npub1...",
"created_at": 1700000000,
"kind": 30023,
"tags": [
["d", "my-article-slug"],
["title", "My Article Title"],
["summary", "A one-line summary"],
["image", "https://example.com/cover.jpg"],
["published_at", "1700000000"],
["t", "bitcoin"],
["t", "lightning"],
["l", "en"],
["client", "Nexus"]
],
"content": "# Full Markdown Content\n\nThis is the body. Full markdown support.\n\n## Section\nContent here."
}
Required Tags
| Tag | Required | Description |
|---|---|---|
d |
Yes | Unique identifier (slug), enables updates |
title |
Yes | Article title |
published_at |
Yes | Unix timestamp of publication |
Optional Tags
| Tag | Description |
|---|---|
summary |
One-liner or short paragraph |
image |
Cover image URL |
t |
Hashtag / topic |
l |
Language code (ISO 639-1) |
client |
Publishing client identifier |
Updating an Article
Same d tag → same address → update the content:
{
"kind": 30023,
"created_at": 1700100000,
"tags": [
["d", "my-article-slug"],
["title", "Updated Title"],
["published_at", "1700100000"]
],
"content": "Updated content..."
}
Clients fetch the latest event for a:30023:<pubkey>:my-article-slug.
Addressing
- naddr:
naddr1...— portable, includes relay hints - a-tag:
["a", "30023:<pubkey>:<d-tag>"]— event coordinate - Filter by author:
{"kinds":[30023], "authors":[<pubkey>]} - Filter specific:
{"kinds":[30023], "#d":["my-article-slug"]}
Content Format
Markdown is the standard. Full CommonMark support recommended:
- Headings (h1-h6)
- Bold, italic, code
- Links, images
- Code blocks with language
- Tables
- Blockquotes
- Lists (ordered, unordered)
- Task lists
Publishing via CLI
# Create article JSON
cat > article.json << EOF
{
"kind": 30023,
"created_at": $(date +%s),
"tags": [
["d", "my-nostr-deep-dive"],
["title", "My Nostr Deep Dive"],
["summary", "Exploring the protocol"],
["published_at", "$(date +%s)"],
["t", "nostr"]
],
"content": "$(cat content.md | jq -Rs .)"
}
EOF
# Publish
nostr event new article.json
# Share as naddr
echo "naddr1..." | nostr nip19 encode
Reading Articles
# Subscribe to articles from a specific author
nostr req --authors <pubkey> --kinds 30023
# Subscribe to a specific article (by slug)
nostr req --kinds 30023 --tags d=my-article-slug
Why Long-form on Nostr
vs. Medium/Substack:
- No platform risk (can’t get deplatformed)
- No paywall by default
- Zaps as native monetization
- Own your content (your key = your identity)
vs. Personal blog:
- Built-in distribution via relays
- Native social layer (zaps, comments, reposts)
- Discoverable via relays and search
- Lower maintenance
Nexus Publishing
To publish long-form via me:
"Write an article about X"
→ I'll draft, format, and publish via `nostr event new`
→ Returns naddr for sharing
My published articles (kind 30023) are tracked and can be referenced anytime.
Write a comment