After writing and publishing a new post, I always share to social media because that is how a lot of folks receive updates (also, POSSE). Because I hate using social media, I have automated this process with a lightweight CLI written in Swift called Mariposa.

The goal of Mariposa is to replace services like IFTTT or Zapier to automatically post to Bluesky and Mastodon whenever I publish a new blog post. Currently, IFTTT has integrations for posting RSS feeds to Twitter and (with some extra work) Mastodon, but it does not provide an option for automating RSS to Bluesky. Zapier offers equivalent functionality, and maybe supports Bluesky, but I’m not sure. But enough about third-party services — we don’t need them anymore!

Motivation

I wanted to stop using IFTTT, in general. I also wanted a solution for Bluesky automation which IFTTT does not support. And Twitter is dead. But more importantly, using IFTTT was always an awkward, roundabout solution anyway. I only used it because I was being lazy.

My blog is built with Jekyll (which I’ve written about before), and I publish using git. Thus, it was always a bit strange to git push and publish a new post, visit my website to verify it updated, and then wait for a random service to listen for changes to my RSS feed so it could post to social media for me. If I’m running git push to publish, I might as well run another command right then that will post to social media. So that’s what I did!

How it works

The only prerequisite is that you have a JSON feed for your blog. As mentioned, I use Jekyll for my blog, which easily accommodates generating a JSON feed. But it does not matter how you generate your site, as long as you have a feed.

If you are only generating a traditional XML RSS feed, you can borrow and adapt my JSON feed template for your needs. (And if you do not publish a feed at all, well… you should!) While I publish both RSS and JSON feeds, Mariposa only supports JSON, which comes free with Swift. And I would rather not ruin something fun by dealing with XML.

Mariposa reads a JSON feed locally from disk, and then posts the most recent entry to Bluesky and Mastodon. The content of the social media posts includes the blog post title and url. For credentials for Bluesky and Mastodon, you pass in a yaml config file. (I chose yaml for this config because it’s nicer to read and write for this type of data.)

The great thing about Jekyll (or any static site generator) is its simplicity. The generated site is output to _site/, which I can preview easily locally. The output includes my full generated JSON feed. That is all the information I need to send out a post to Bluesky or Mastodon — there is no need for services like IFTTT to listen for changes. Much simpler!

You can find more details and documentation on GitHub.

Workflow

This tool is very much something I built for myself. It is centered around my workflow and my needs. But, I think other folks with similar setups could find it useful. After finishing a blog post, here’s my workflow:

  1. Publish via git
  2. Make sure the locally generated site is up-to-date (jekyll build)
  3. Run mariposa to share it via Bluesky and Mastodon

Because I use a Makefile with phony targets as shortcuts for scripts and commands, the above simplifies to:

  1. make build (build the site locally)
  2. make pub (publish changes to web server)
  3. make social (share post on social media)

Example usage

In this example, I’ve cloned the repo to ~/Developer/mariposa/. The config file with my credentials is stored in my home directory at ~/.mariposa_config.yml. The command is run from the root directory of my website and my generated feed is stored in _site/feed.json.

Below is the output for sharing this very blog post!

swift run --package-path ~/Developer/mariposa/ mariposa -c ~/.mariposa_config.yml -f _site/feed.json

👀 Preview:
    Mariposa: a lightweight Swift CLI to automate sharing blog posts to social media
    https://www.jessesquires.com/blog/2025/11/07/mariposa/

➡️  Continue? (y/N): y

Posting to Bluesky... success ✅
https://bsky.app/profile/jessesquires.com

Posting to Mastodon... success ✅
https://mastodon.social/@jsq/115509326819194206

🎉 Finished

Developer notes

I had a lot of fun building this over the course of an afternoon. The Mastodon API and Bluesky API were both pretty easy to work with. Many thanks to Manton Reece for writing this blog post, which helped me get started even more quickly with the Bluesky API, which was a bit trickier.

Mariposa is published as a Swift Package. It depends on JP’s Yams library for parsing the yaml config, and the swift-argument-parser for the CLI. This was my first time using swift-argument-parser — and wow, that library is fucking awesome. I barely had to write any code and everything just worked. Other than these two libraries, it’s just Foundation and the Standard Library.

Again, this is very much a tool I wrote for myself. It supports a very small subset of the Mastodon API and Bluesky API — only the parts I needed. I wrote my own lightweight clients because using a third-party API client library felt like overkill. I made the package very modular, so it should be easy to add features or modify it however you like.

You probably noticed this is actually partially automated. I have to manually run mariposa after publishing a post. I could have run this on the web server via a git hook, tracked what entries have already been shared, etc. — but that would have required a lot of additional complexity that was not worth the time or effort to me. You could surely automate fully if desired.

All the code is on GitHub. Check it out, and feel free to send me a pull request!