Skip to main content
Back to Insights
Engineering & ReliabilityArchitecture

Slack Block Kit vs Microsoft Adaptive Cards: The Cross-Platform Formatting Problem

When messages move between Slack and Teams, their rich formatting must be translated between two fundamentally different JSON schemas. This is the technical guide to Block Kit and Adaptive Cards translation.

9 min read
Alex Morgan

Alex Morgan is a principal engineer at SyncRivo, focused on platform architecture, reliability engineering, and the infrastructure powering real-time messaging interoperability.

Slack Block Kit vs Microsoft Adaptive Cards: The Cross-Platform Formatting Problem

Why Message Formatting Matters for Interoperability

A basic bidirectional message bridge that passes plain text between Slack and Teams is technically achievable in a weekend project. The real engineering challenge is rich formatting: bold text, code blocks, bullet lists, file attachments, @mentions, hyperlinks, and interactive elements.

Each enterprise messaging platform has a different JSON schema for representing formatted content. Slack uses Block Kit. Microsoft Teams uses Adaptive Cards. Google Chat uses Cards V2. Zoom Team Chat uses its own markdown-adjacent format.

When a Slack message with a code block, a bullet list, and an @mention to a user arrives at the bridge and needs to be delivered to a Teams channel, the bridge must translate from Block Kit JSON to Adaptive Card JSON while preserving the semantic meaning of each formatting element. This translation is where low-quality integration tools fail — they either drop all formatting (producing unreadable plain text) or fail silently on edge cases.

Slack Block Kit Architecture

Block Kit is Slack's structured message layout system, introduced in 2019. A Block Kit message is a JSON array of "blocks," each of which represents a layout component.

Core block types

Section block — the primary text content block:

{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "This is *bold* text with a `code span`"
  }
}

Divider block — a horizontal rule:

{ "type": "divider" }

Context block — smaller, secondary text (author attribution, timestamps):

{
  "type": "context",
  "elements": [
    { "type": "mrkdwn", "text": "Posted by *Jordan Hayes* at 2:30 PM" }
  ]
}

File block — represents a shared file:

{
  "type": "file",
  "external_id": "ABCD1234",
  "source": "remote"
}

Slack mrkdwn vs standard markdown

Slack uses a proprietary markdown variant called mrkdwn that differs from CommonMark in important ways:

FormatSlack mrkdwnCommonMark
Bold*bold***bold**
Italic_italic_*italic* or _italic_
Code spancodecode (same)
Strikethrough~strikethrough~~~strikethrough~~
@mention<@U01234567>N/A
Channel link`<#C01234567channel-name>`
Hyperlink`<link text>`

The @mention and hyperlink formats are particularly important for cross-platform translation — they contain user IDs and channel IDs that must be resolved to the destination platform's equivalent.

Microsoft Adaptive Cards Architecture

Adaptive Cards is Microsoft's cross-platform card specification, used in Teams, Outlook, and other Microsoft 365 products. Like Block Kit, it represents formatted content as a JSON structure — but with a different schema and different design philosophy.

Core element types

TextBlock — the primary text element:

{
  "type": "TextBlock",
  "text": "This is **bold** text in Adaptive Cards markdown",
  "wrap": true
}

Adaptive Cards TextBlock uses CommonMark-compatible markdown (double asterisks for bold), not Slack's mrkdwn format.

ColumnSet and Column — for multi-column layouts (used for sender attribution):

{
  "type": "ColumnSet",
  "columns": [
    {
      "type": "Column",
      "width": "auto",
      "items": [
        { "type": "TextBlock", "text": "Jordan Hayes", "weight": "bolder" }
      ]
    },
    {
      "type": "Column",
      "width": "stretch",
      "items": [
        { "type": "TextBlock", "text": "via Slack", "color": "accent", "size": "small" }
      ]
    }
  ]
}

Image — for inline images and thumbnails:

{
  "type": "Image",
  "url": "https://example.com/image.png",
  "size": "medium"
}

The Translation Matrix

Every formatting element that exists in Slack must have a corresponding representation in Adaptive Cards, and vice versa. The translation matrix for a production-grade bridge:

Slack (mrkdwn)Adaptive Cards equivalent
*bold***bold**
_italic__italic_ (same)
~strike~~~strike~~
codecode
Fenced code blockWrap in <pre> via HTML passthrough (limited support)
<@U01234567><at>Display Name</at> with mentions array
Bullet listSeparate TextBlock per item, prefixed with "• "
Numbered listSeparate TextBlock per item, prefixed with ordinal
BlockquoteTextBlock with left-border styling via Container

The @mention translation problem

@mention translation is the most complex element to handle correctly. In Slack, a mention is encoded as <@U01234567>, where U01234567 is the Slack user ID. To translate this to a Teams @mention:

  1. Resolve the Slack user ID to an email address via the Slack Users API
  2. Resolve the email address to a Teams AAD object ID via the Microsoft Graph Users API
  3. Construct the Teams mention in the Adaptive Card:
{
  "body": [
    {
      "type": "TextBlock",
      "text": "Hello <at>Jordan Hayes</at>, the build is complete."
    }
  ],
  "msteams": {
    "entities": [
      {
        "type": "mention",
        "text": "<at>Jordan Hayes</at>",
        "mentioned": {
          "id": "29:aad-object-id-here",
          "name": "Jordan Hayes"
        }
      }
    ]
  }
}

The mention entity must appear both in the text content (as <at>Name</at>) and in the msteams.entities array. If either is missing, Teams will not render the mention with a notification — it will appear as plain text.

What Gets Lost in Translation

Some formatting elements have no equivalent on the other platform:

  • Slack's Action blocks (interactive buttons) — Teams can render Action Sets, but the interaction model is different. Action blocks in bridged messages are typically rendered as plain text links.
  • Teams' Adaptive Card Facts — key/value pairs with no Block Kit equivalent; best translated as a bullet list
  • Slack's App surfaces (Home tab, modals) — these are not message content and are not bridged
  • Custom emoji — platform-specific emoji (:slack-emoji:) have no cross-platform equivalent; substitute with nearest Unicode emoji or strip

The Rendering Fidelity Tradeoff

A production messaging bridge must make an explicit architectural decision about rendering fidelity: how much formatting complexity to preserve vs. how much to simplify for reliability.

SyncRivo's translation layer makes the following tradeoffs:

  • Plain text, bold, italic, code spans, and hyperlinks: full fidelity
  • @mentions: full fidelity (with identity resolution)
  • File attachments: full fidelity (with file transfer)
  • Complex multi-column layouts: simplified to linear format
  • Interactive elements (buttons, selects): stripped to link text

This tradeoff ensures that the bridge never fails on a message it cannot render perfectly — it degrades gracefully to simpler formatting rather than silently dropping the message.

Read the Teams Graph API deep dive → | See Slack ↔ Teams integration →

Bridge your messaging platforms in 15 minutes

Connect Slack, Teams, Google Chat, Webex, and Zoom with any-to-any routing. No guest accounts. No migration. SOC 2 & HIPAA ready.