Cross-post your content to dev.to, Ghost, WordPress, Hashnode, Medium, Bluesky, Mastodon, Threads, Telegram, Discord, and more.
Like a town crier announcing your content to the world.
pip install crier# Configure your API keys
crier config set devto.api_key YOUR_API_KEY
crier config set bluesky.api_key "handle.bsky.social:app-password"
crier config set mastodon.api_key "mastodon.social:access-token"
# Publish a markdown file
crier publish post.md --to devto
# Publish to multiple platforms at once
crier publish post.md --to devto --to bluesky --to mastodon
# List your articles
crier list devto
# Update an existing article
crier update devto 12345 --file updated-post.md| Platform | API Key Format | Notes |
|---|---|---|
| dev.to | api_key |
Full article support |
| Hashnode | token or token:publication_id |
Full article support |
| Medium | integration_token |
Publish only (no edit/list) |
| Ghost | https://site.com:key_id:key_secret |
Full article support |
| WordPress | site.wordpress.com:token or https://site.com:user:app_pass |
Full article support |
| Buttondown | api_key |
Newsletter publishing |
| Bluesky | handle:app_password |
Short posts with link cards |
| Mastodon | instance:access_token |
Toots with hashtags |
| Threads | user_id:access_token |
Short posts (no edit support) |
| Telegram | bot_token:chat_id |
Channel/group posts |
| Discord | webhook_url |
Server announcements |
access_token |
Requires API access | |
| Twitter/X | any (copy-paste mode) |
Generates tweet for manual posting |
Blog Platforms (dev.to, Hashnode, Medium, Ghost, WordPress):
- Full markdown article publishing
- Preserves front matter (title, description, tags, canonical_url)
- Best for long-form content
Newsletter Platforms (Buttondown):
- Publishes to email subscribers
- Full markdown support
- Great for content repurposing
Social Platforms (Bluesky, Mastodon, LinkedIn, Twitter, Threads):
- Creates short posts with link to canonical URL
- Uses title + description + hashtags from tags
- Best for announcing new content
Announcement Channels (Telegram, Discord):
- Posts to channels/servers
- Good for community announcements
- Discord uses webhook embeds
API keys can be set via:
-
Config file (
~/.config/crier/config.yaml):platforms: devto: api_key: your_key_here bluesky: api_key: "handle.bsky.social:app-password" mastodon: api_key: "mastodon.social:access-token"
-
Environment variables:
export CRIER_DEVTO_API_KEY=your_key_here export CRIER_BLUESKY_API_KEY="handle.bsky.social:app-password"
Crier reads standard markdown with YAML front matter:
---
title: "My Amazing Post"
description: "A brief description"
tags: [python, programming]
canonical_url: https://myblog.com/my-post
published: true
---
Your content here...crier publish FILE [--to PLATFORM]... # Publish to platform(s)
crier update PLATFORM ID --file FILE # Update existing article
crier list PLATFORM # List your articles
crier config set KEY VALUE # Set configuration
crier config show # Show configuration
crier platforms # List available platforms- Go to https://dev.to/settings/extensions
- Generate API key
- Go to https://hashnode.com/settings/developer
- Generate Personal Access Token
- Go to https://medium.com/me/settings/security
- Generate Integration Token
- Go to Settings → App Passwords
- Create an app password
- Use format:
yourhandle.bsky.social:xxxx-xxxx-xxxx-xxxx
- Go to Settings → Development → New Application
- Create app with
write:statusesscope - Use format:
instance.social:your-access-token
Uses copy-paste mode - generates formatted tweet text for manual posting. No API setup required. Just set any placeholder value:
crier config set twitter.api_key manual- Go to Settings → Integrations → Add custom integration
- Copy the Admin API Key (format:
key_id:key_secret) - Use format:
https://yourblog.com:key_id:key_secret
WordPress.com:
- Go to https://developer.wordpress.com/apps/
- Create an app and get OAuth token
- Use format:
yoursite.wordpress.com:access_token
Self-hosted WordPress:
- Go to Users → Profile → Application Passwords
- Create a new application password
- Use format:
https://yoursite.com:username:app_password
- Go to https://buttondown.email/settings/programming
- Copy your API key
- Use format:
api_key
- Create a Meta Developer account at https://developers.facebook.com/
- Create an app with Threads API access
- Get your user_id and access_token
- Use format:
user_id:access_token
- Message @BotFather to create a bot and get the bot token
- Add your bot as admin to your channel
- Get your channel's chat_id (e.g.,
@yourchannelor numeric ID) - Use format:
bot_token:chat_id
- Go to Server Settings → Integrations → Webhooks
- Create a new webhook for your announcement channel
- Copy the webhook URL
- Use the full URL as the API key
MIT