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/postweb 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 |  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
- The default X output must be plain text with Markdown syntax removed.
- Weighted counting is a required core feature, including URLs, emoji, CJK and Unicode normalization.
- Standard mode should target 280 weighted characters per post. A separately labeled Premium long-post mode may follow only after live testing.
- Thread splitting must prefer semantic boundaries: headings, paragraphs, complete list groups and sentences.
- Every generated segment needs an independent count and copy control; optional
1/Nnumbering must be included in that count. - Markdown links should become visible destinations; Markdown images should become a media/alt-text checklist, not raw syntax.
- Unicode mathematical alphabets should be off by default because visual styling is not equivalent to semantic bold and can reduce accessibility and searchability.
- 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.


