Crier: Cross-Post Your Content Everywhere

Published: (December 16, 2025 at 10:28 PM EST)
3 min read
Source: Dev.to

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

PlatformTypeNotes
dev.toBlogFull article support
HashnodeBlogFull article support
MediumBlogPublish only
GhostBlogFull article support
WordPressBlogSelf‑hosted or .com
ButtondownNewsletterEmail subscribers
BlueskySocialPosts with link cards
MastodonSocialToots with hashtags
ThreadsSocialShort posts
LinkedInSocialProfessional network
Twitter/XSocialCopy‑paste mode
TelegramChannelBot posts
DiscordChannelWebhook 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_url is 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

CommandDescription
crier publish FILE [--to PLATFORM]...Publish to one or more platforms
crier backfill PATH [--profile NAME]Publish missing content
crier audit PATHShow what needs publishing
crier list PLATFORMList your articles on a platform
crier update PLATFORM ID --file FILEUpdate an existing publication
crier platformsShow available platforms
crier config set KEY VALUEConfigure API keys
crier init-actionSet 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
  • PyPI:
  • GitHub:
  • Documentation:
Back to Blog

Related posts

Read more »