I published crier to PyPI. It’s a command-line tool for cross-posting content to multiple platforms at once.
The problem is simple: I write blog posts in Markdown with YAML front matter. I want them on dev.to, Hashnode, Bluesky, Mastodon, and wherever else, without manually copy-pasting into a dozen different editors. Crier handles this from the terminal.
Quick Start
pip install crier
cd your-blog
crier init
The init command walks you through setup: detecting content directories, configuring platforms with API keys.
The Workflow
- Your markdown posts with YAML front matter are the source of truth
.crier/registry.yamltracks what’s published wherecrier auditshows what’s missing or changedcrier publishpushes content out
# See what needs publishing
crier audit
# Publish to multiple platforms
crier publish post.md --to devto --to bluesky --to mastodon
# Bulk publish everything missing
crier audit --publish --yes
LLM-Powered Auto-Rewrite
This is the feature I’m most pleased with. Short-form platforms like Bluesky (300 chars) and Mastodon (500 chars) need summaries, not full articles. Crier generates these automatically using any OpenAI-compatible LLM:
# Auto-generate short-form content
crier publish post.md --to bluesky --to mastodon --auto-rewrite
# Bulk publish with auto-rewrite
crier audit --publish --auto-rewrite --yes
Simplest setup: If you have OPENAI_API_KEY set, it just works (defaults to gpt-4o-mini).
Or use local models:
# ~/.config/crier/config.yaml
llm:
base_url: http://localhost:11434/v1 # Ollama
model: llama3
The LLM generates platform-appropriate summaries that fit within character limits, with automatic retry if the output is too long.
Supported Platforms
| Platform | Type | Notes |
|---|---|---|
| dev.to | Blog | Full article support |
| Hashnode | Blog | Full article support |
| Medium | Blog | Publish/import mode |
| Ghost | Blog | Full article support |
| WordPress | Blog | Self-hosted or .com |
| Buttondown | Newsletter | Email subscribers |
| Bluesky | Social | Posts with link cards |
| Mastodon | Social | Toots with hashtags |
| Threads | Social | Short posts |
| Social | Professional network | |
| Twitter/X | Social | Copy-paste mode |
| Telegram | Channel | Bot posts |
| Discord | Channel | Webhook embeds |
Bulk Operations with Filters
The audit command supports filtering for targeted bulk operations:
# API platforms only (skip manual/import)
crier audit --publish --yes --only-api
# Long-form only (skip short-form social)
crier audit --publish --yes --long-form
# Random sample of 5 articles
crier audit --publish --yes --sample 5
# Filter by path and date
crier audit content/post --since 1m --only-api --publish --yes
# Combine filters
crier audit content/post --since 1w --only-api --long-form --sample 10 --publish --yes
| Filter | Description |
|---|---|
[PATH] | Only scan specific directory |
--since | Only content from this date (1d, 1w, 1m, or YYYY-MM-DD) |
--only-api | Skip manual/import platforms |
--long-form | Skip short-form social platforms |
--sample N | Random sample of N items |
--auto-rewrite | Generate short-form content with LLM |
Profiles
Group platforms into reusable profiles:
# ~/.config/crier/config.yaml
profiles:
blogs: [devto, hashnode, medium]
social: [bluesky, mastodon]
everything: [blogs, social] # Profiles can reference other profiles
Then: crier publish post.md --profile everything
Claude Code Integration
Crier works with Claude Code. Install the skill:
crier skill install
Then ask naturally:
- “Cross-post my latest article to all platforms”
- “What articles haven’t been published to Bluesky?”
- “Publish this post to Mastodon with a good announcement”
Claude follows the workflow automatically: audit, select, publish (with rewrites for short-form platforms).
Configuration
Global config (~/.config/crier/config.yaml): API keys, profiles, LLM settings
platforms:
devto:
api_key: your_key_here
bluesky:
api_key: "handle.bsky.social:app-password"
twitter:
api_key: manual # Copy-paste mode
llm:
api_key: sk-... # Or set OPENAI_API_KEY env var
Local config (.crier/config.yaml): Project settings
content_paths:
- content
site_base_url: https://yoursite.com
default_profile: everything
CLI Reference
# Setup
crier init # Interactive setup
crier config show # View configuration
crier doctor # Verify API keys
# Publishing
crier publish FILE --to PLATFORM # Publish to platform(s)
crier publish FILE --auto-rewrite # With LLM-generated short-form
crier audit # See what needs publishing
crier audit --publish --yes # Bulk publish all missing
crier audit --publish --auto-rewrite # Bulk publish with LLM rewrites
# Management
crier list PLATFORM # List your articles
crier status [FILE] # Show publication status
# Claude Code
crier skill install # Install the skill
Links
- PyPI: pypi.org/project/crier
- GitHub: github.com/queelius/crier
Discussion