Last time I explained how I cross-post my blog to Medium. This time I’ll write a similar node.js script to cross-post articles to the steem blockchain.

Steem is a blockchain-based rewards platform for publishers to monetize content and grow

Why cross-post to Steem?

  1. While Steem is not as big as Medium yet, especially the dev community, you will still reach people that previously would never have found your blog. As a platform, I’m sure it will only grow in the next years because it has some nice innovative features.
  2. Your posts are stored on the blockchain. This means your posts cannot be deleted or censored by anyone — they’ll always be there. If your blog (or Medium) is offline for some reason, or gets hacked and the content deleted, nobody can find your content anymore and you better have a backup of your old posts. The blockchain is decentralized. If steemit is down, you just use any of the other interfaces to the steem blockchain.
    However, unlike in Medium, you cannot set a canonical link that points to your original blog post, meaning the duplicated content on all of these sites might potentially hurt your SEO ranking. Though the effects of this have yet to be seen.
  3. You don’t just get more visibility when people upvote your posts, you can actually earn money in doing so.
  4. You can write Markdown in your familiar environment — for me, it’s VS Code + gatsbyjs for live reloading. Posting it to steem is then no effort with the script.

If this convinced you, here’s how to setup cross-posting to Steem.


All you need is nodejs version 8 or higher, and a post written in Markdown. The Markdown post should have a frontmatter containing the title, slug, and steem tags. For instance, this post looks like this:

Creating credentials for the scripts

You will need a steem account and your account’s posting key.

On steemit, click on your profile, go to Wallet, then Permissions, click on Show Private Key and take note of your Posting Private Key.

Steem Posting Key
Steem Posting Key

Cross-post Script

A lot of the ideas and code from the medium crosspost script also apply when posting to Steem. Let’s take a look at the outline of what our script needs to do:

  1. Read the Markdown file, parse it into a markdown abstract syntax tree (MAST)
  2. Get the title, slug, and steem tags from the frontmatter.
  3. Rewrite all relative image and link URLs to absolute URLs prefixing our website
  4. Inject custom footer backlinking to our original post
  5. Gather additional data that needs to be saved in the blockchain
  6. Use Steem API to create the post with the modified markdown post’s content, the additional data, and tags.

The first four steps are exactly the same as in my medium crosspost script, so I suggest first reading that post if you haven’t yet.

Here’s a quick reminder of our main function that transforms the markdown post given by a path to the modified markdown. We’re using remark and its plugin system.

As always, the fully functional code can be seen on GitHub.

Gathering additional data from the post

It’s not officially documented anywhere what fields a post must contain. For that, I found it to be easiest to just look at the steem blockchain data of a post I made through steemit and replicate its fields. There are several block explorers, for instance steemdb lists all fields for the post. The interesting one for us is json_metadata where additional metadata is stored by steemit.

As we can see, the format (markdown) is saved along with its tags and the app that was used for creating the posts. The more interesting fields are links and image. Besides the inconsistent naming, both fields save an array of all link/image URLs that are in the post.

I haven’t done any deeper digging on what these fields are used for in the steemit frontend, but they are probably there for a reason. 🤷 So let’s just write a remark plugin that creates the same json_metadata structure and appends our footer.

We then insert the plugin into our plugins chain:

The function now returns all necessary data for publishing the post to steem.

Using steem-api to publish the transformed post

Now we just need to call the transformPostFromPath function which sequentially executes all of our remark plugins, and returns the data.

The steem client implementation looks like this:

You need to set the correct credentials mentioned in the setup section in a .env file.

We use the steem.broadcast.commentAsync function of steem to publish our post. The name says comment, but it's actually a really generic function used for all sorts of text interaction. That's also why we need to use the indescriptive fields parent_author, parent_permlink, and perm_link for the main category and slug.

Checking if a post already exists on Steem

We cannot delete (but always update) existing posts from the blockchain, so a sanity check if the post already exists would be nice. For my posts, the slugs are the unique identifier and we use the same slugs from my blog also for the steem blockchain (stored in permlink). This way we can write a simple function that checks if a specific slug already exists for an account. It works by first retrieving all posts and then searching for the slug:

Again, the complete working code can be seen on GitHub.

You should now be able to cross-post your blog articles to the steem blockchain by simply running a script. 🎉


Sadly, syntax-highlighting for Markdown code does not work on steemit. You could write another remark-plugin that automatically replaces code nodes with a screenshot / Codepen / GitHub gist.

Originally published at

Medium Clap

Full Stack Software Engineer #javascript #EOS. Into Recreational Math / CS 🤯 Just message me about anything, my mind is open.