Crier: Cross-Post Your Content Everywhere
Source: Dev.to
Overview
crier is a command‑line tool for cross‑posting content to multiple platforms simultaneously.
It lets you write a post once and publish it to dev.to, Ghost, WordPress, Hashnode, Medium, Bluesky, Mastodon, Threads, Telegram, Discord, and more.
pip install crier
The Problem
Maintaining a blog and reaching audiences on several platforms usually involves tedious manual steps:
- Copying content to dev.to
- Creating a Bluesky post with a link
- Tooting on Mastodon
- Posting an announcement to Discord, etc.
Each platform has its own interface, API, and quirks.
Solution: Publish Everywhere with One Command
crier publish post.md --to devto --to bluesky --to mastodon --to discord
The command:
- Publishes the full article to dev.to
- Creates a Bluesky post with title, description, and link
- Toots on Mastodon with hashtags derived from your tags
- Sends an embed announcement to your Discord server
Supported Platforms
| Platform | Type | Notes |
|---|---|---|
| dev.to | Blog | Full article support |
| Hashnode | Blog | Full article support |
| Medium | Blog | Publish only |
| 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 |
Markdown Input Format
crier reads standard Markdown files with optional YAML front matter:
---
title: "My Post Title"
description: "A brief description"
tags: [python, cli, automation]
canonical_url: https://myblog.com/my-post
---
- For blog platforms – the full article is published.
- For social platforms – a short announcement with a link back to
canonical_urlis created.
GitHub Actions Integration
Combine crier with GitHub Actions to automate cross‑posting on every push.
Initialize the Action
crier init-action
This creates a workflow file and sets up API keys as GitHub secrets.
Example Workflow (.github/workflows/crosspost.yml)
name: Cross-Post Content
on:
push:
branches: [main]
paths:
- 'posts/**/*.md'
jobs:
crosspost:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install crier
- name: Cross-post to platforms
env:
CRIER_DEVTO_API_KEY: ${{ secrets.CRIER_DEVTO_API_KEY }}
CRIER_BLUESKY_API_KEY: ${{ secrets.CRIER_BLUESKY_API_KEY }}
run: |
crier backfill ./posts --yes
- name: Save publication state
run: |
git config user.name "github-actions[bot]"
git add .crier/
git diff --staged --quiet || git commit -m "Update publication registry"
git push
Publication Registry
crier maintains a registry (.crier/registry.yaml) that tracks what has been published:
posts:
"posts/my-article.md":
title: "My Article"
publications:
devto:
id: "12345"
url: https://dev.to/user/my-article
bluesky:
id: "abc123"
Adding a new platform later will automatically backfill existing content.
CLI Reference
| Command | Description |
|---|---|
crier publish FILE [--to PLATFORM]... | Publish to one or more platforms |
crier backfill PATH [--profile NAME] | Publish missing content |
crier audit PATH | Show what needs publishing |
crier list PLATFORM | List your articles on a platform |
crier update PLATFORM ID --file FILE | Update an existing publication |
crier platforms | Show available platforms |
crier config set KEY VALUE | Configure API keys |
crier init-action | Set up GitHub Actions workflow |
Setting API Keys
crier config set devto.api_key YOUR_DEV_TO_KEY
crier config set bluesky.api_key "handle.bsky.social:app-password"
crier config set mastodon.api_key "mastodon.social:access-token"
Defining Profiles
Create ~/.config/crier/config.yaml:
profiles:
blogs: [devto, hashnode]
social: [bluesky, mastodon]
all: [blogs, social]
Use a profile:
crier publish post.md --profile all
Links
- PyPI:
- GitHub:
- Documentation: