Markdown Preflight

Research / Evidence

X test record

Tested surface
X web post and thread composer
Test date
Tested 2026-08-24.
Fixture
markdown-portability-test-v1
Confidence
verified

This page reproduces the dated record exactly as it was written on 2026-08-24. A record is never edited to match later behavior. When a platform changes, a new dated record is added and this one is kept.

X Test Record — 2026-08-24

Verdict

X is a plain-text destination, not a Markdown renderer. Raw Markdown punctuation remains visible: heading markers, emphasis markers, inline-code backticks, quote markers, table pipes and Markdown image syntax are not converted. Paragraph and line-break structure survives, and URLs are detected even when embedded inside otherwise-literal Markdown link or image syntax.

The correct first-version X handoff is therefore cleaned plain text, not rich HTML and not raw Markdown. Longer Markdown drafts should be transformed into a sequence of independently valid posts, with weighted character counting, readable split points, visible link destinations and a final media checklist.

Environment and safety boundary

  • Authenticated account: existing free X account; the composer displayed a Premium upsell rather than Premium long-post capability.
  • Surface: https://x.com/compose/post web composer.
  • No post, reply, quote, poll or scheduled item was submitted.
  • No media file was uploaded.
  • Test content was removed and the empty composer was closed at the end.
  • The toolbar exposed media, GIF, generated image, poll, emoji, scheduling, location and disclosure controls; it exposed no heading, bold, italic, code or table formatting controls.

Mode-level result

Mode Result Measured evidence
Raw Markdown Fail for formatting; pass for readable source text Markdown punctuation remained literal; paragraphs remained separated; the URL substring was detected
Cleaned plain text Preferred Plain heading, bullets, paragraphs, code label, quote label and URL remained readable without Markdown residue
Standard character limit Verified 280 ASCII characters enabled Post; 281 disabled it and displayed -1 with a Premium upsell
URL weighting Verified 256 ASCII characters + one space + a long URL was accepted; adding one ASCII character disabled posting, confirming the URL's 23-character weight
Emoji weighting Verified 140 emoji were accepted; 141 disabled posting, confirming a weight of 2 per emoji
Native thread composer Verified Add post created a second independent editor and changed the final action to Post all
Premium longer post Documented, not live-tested X Help says Premium longer posts can contain up to 25,000 characters; the tested account was free

Raw Markdown and fragile syntax

The focused raw fixture contained a heading, emphasis, list markers, a Markdown link, inline code and a quote. A second focused fixture contained a GFM table and Markdown image syntax.

Construct Observed behavior Required output rule
Heading # Markdown Test remained literal Remove heading markers; keep a standalone opening line
Bold/italic **Bold** and _italic_ remained literal Strip markers by default; do not rely on Unicode font substitution
Lists Hyphen markers remained ordinary characters Normalize to readable bullets or numbering
Markdown link Brackets and parentheses remained; the URL substring was detected and produced a link preview Emit label: URL or a bare URL
Inline/fenced code Backticks remain literal; there is no native code-block control Remove fences and preserve short code with spacing/indentation; summarize long code
Quote/divider Markdown markers remain literal Replace with a Quote: label or readable separator
GFM table Pipes and separator row remain literal Convert compact tables to labeled rows or bullets; reject wide tables as text
Markdown image ![alt](URL) remains literal; no image is uploaded Remove syntax, retain alt/caption and place the source image in a separate upload checklist
Footnotes/math/Mermaid/Obsidian/raw HTML No corresponding native text-formatting controls exist Resolve links, flatten semantic blocks, render diagrams/math to media when useful, and remove unsupported syntax

Evidence: raw Markdown composer.

Paragraphs, links and clean output

Blank lines and ordinary line breaks remained in the editor state. A cleaned version using a plain title, spaced paragraphs, bullets, visible URL, Code: label and Quote: label was readable and enabled for posting.

The detected URL generated X's normal link preview card without publishing. This is useful but must not be described as an image upload or guaranteed preview: preview generation depends on the destination URL and X's crawler.

Evidence: clean plain-text composer.

Character counting

The free-account composer used a 280-weighted-character limit:

Input Effective result Composer state
280 ASCII characters 280 Posting enabled
281 ASCII characters 281 Posting disabled; -1 displayed
256 ASCII + one space + 115-character URL 280 Posting enabled
257 ASCII + one space + same URL 281 Posting disabled
140 emoji 280 weighted characters Posting enabled
141 emoji 282 weighted characters Posting disabled

The live URL and emoji results match X's current character-counting documentation: ordinary Latin characters usually weigh 1, emoji and CJK characters weigh 2, and detected URLs weigh 23 regardless of original length. The product should use the official open-source twitter-text rules or a rigorously equivalent implementation rather than JavaScript string length.

Evidence: 281-character rejection, https://docs.x.com/fundamentals/counting-characters.

Thread behavior

Once the first post contained text, the composer exposed Add post. Selecting it created a second editor with its own content state and changed the submit action to Post all. Two short numbered segments were accepted together.

This verifies the destination handoff model but does not authorize automatic publishing. Version one should generate separately copyable thread segments and show each segment's weighted count. It should not assume that splitting every 280 weighted characters is readable.

Documented but not live-tested

X Help currently states that Premium accounts can create longer posts up to 25,000 characters. It also states that longer posts cannot currently be saved as drafts or scheduled on the web. Because the tested account was free, those behaviors remain documentation-only.

Source: https://help.x.com/en/using-x/types-of-posts.

Product implications

  1. The default X output must be plain text with Markdown syntax removed.
  2. Weighted counting is a required core feature, including URLs, emoji, CJK and Unicode normalization.
  3. Standard mode should target 280 weighted characters per post. A separately labeled Premium long-post mode may follow only after live testing.
  4. Thread splitting must prefer semantic boundaries: headings, paragraphs, complete list groups and sentences.
  5. Every generated segment needs an independent count and copy control; optional 1/N numbering must be included in that count.
  6. Markdown links should become visible destinations; Markdown images should become a media/alt-text checklist, not raw syntax.
  7. Unicode mathematical alphabets should be off by default because visual styling is not equivalent to semantic bold and can reduce accessibility and searchability.
  8. The product should not compete with Buffer or Typefully on scheduling. It should prepare verified X-safe content that can then be pasted directly or handed to those tools.

Cleanup

All test text was removed from the composer. The empty composer was closed, returning the authenticated tab to X Home. No post, draft, reply, scheduled item or uploaded media was created.

Screenshots from this test

What this record does not cover

A live result proves the tested surface on the tested date. It does not prove every account tier, editor version, theme, plugin, browser, email client, or API path. The limitations section inside the record above lists what was left untested.

Source record: docs/research/platform-tests/2026-08-24-x-test-record.md. Back to the five-platform comparisonor the checker.