ShowMe turns a single markdown file into a polished, shareable document with an optional presentation mode. No accounts, no build step, no deploy pipeline. Write markdown, publish with one command, share the URL.
This guide is itself a ShowMe document. Everything you see here — the table of contents, the reading time, the interactive widgets, and the Present button in the top-right corner — is generated from a single markdown file.
Quick Start
Publishing your first document takes three steps:
- Write a markdown file with optional YAML frontmatter
- Publish via the CLI or the HTTP API
- Share the returned URL
Using the CLI
The fastest way to publish is with npx:
npx showme publish document.md
The CLI reads your file, sends it to the ShowMe API, and prints a shareable URL:
Published: https://showme.dev/a1b2c3d4
You can also pipe from stdin:
cat notes.md | npx showme publish -
Using the API
For programmatic publishing, call the API directly:
const res = await fetch("https://showme.dev/api/v1/publish", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
markdown: "# Hello\n\nThis is my document.",
title: "Hello World",
theme: "minimal",
}),
});
const { slug, url } = await res.json();
// url → "https://showme.dev/a1b2c3d4"
import requests
resp = requests.post(
"https://showme.dev/api/v1/publish",
json={"markdown": "# Hello\n\nMy document.", "title": "Hello World"},
)
print(resp.json()["url"])
Frontmatter
YAML frontmatter at the top of your file controls document metadata and behavior:
---
title: My Document
description: A brief summary displayed below the title
toc: true
css: |
.highlight { color: #2563eb; font-weight: 600; }
slides:
theme: dark
---
| Field | Type | Description |
|---|---|---|
title |
string | Document title, shown in the header and browser tab |
description |
string | Subtitle displayed below the title |
toc |
boolean | Show or hide the table of contents sidebar |
css |
string | Custom CSS injected into the document |
slides.theme |
"dark" or "light" |
Color theme for presentation mode |
If your markdown starts with an # H1 heading that matches the frontmatter title, it is automatically deduplicated so the title does not appear twice.
Document Features
Text and Typography
ShowMe renders standard markdown with Tailwind Typography for clean, readable output:
- Italic for emphasis
- Bold for strong emphasis
- Bold italic for both
Strikethroughfor deletionsinline codefor technical terms
“The best way to predict the future is to invent it.” — Alan Kay
Ordered lists, nested bullets, blockquotes, and horizontal rules all render with proper spacing.
Links and Images
Standard markdown links render as clickable anchors. Bare URLs are automatically converted to links thanks to the linkify option.
Images use standard syntax: . They are responsive in document mode and constrained to 60vh max height in slides.
Code Blocks
Fenced code blocks render with monospace styling. Add a language tag for clarity:
```js
console.log("Hello from ShowMe");
```
Tables
Pipe-delimited tables render with proper alignment and styling:
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/publish |
Publish markdown, returns { slug, url } |
GET |
/api/v1/content/:slug |
Retrieve stored markdown and metadata |
GET |
/health |
Health check |
All API errors follow a consistent format:
{ "error": { "code": "VALIDATION_ERROR", "message": "...", "details": {} } }
Error codes: VALIDATION_ERROR (400), NOT_FOUND (404), INTERNAL_ERROR (500).
Interactive Components
ShowMe supports interactive content via <!-- component --> HTML comment blocks. Each component runs in a sandboxed iframe with browser import maps resolving modules from CDN:
- React 19 — available via
importfrom"react"and"react-dom/client" - Observable Plot — grammar-of-graphics charting via
import * as Plot from "@observablehq/plot"
React Components
Write standard JSX with ES module imports. Mount your content on #root. Here is a feature explorer that demonstrates what ShowMe can do:
Observable Plot Charts
Data visualizations use Observable Plot. Here is a chart showing ShowMe feature usage across document types:
Plot supports barY, line, dot, areaY, cell, and many more mark types, with built-in transforms like binX, groupX, and stackY. Add tip: true to any mark for hover tooltips.
Presentation Mode
Any ShowMe document can double as a slide deck. Slide blocks are embedded as HTML comments that are invisible in document mode but rendered as full-screen slides when you click Present.
Slide Syntax
Slides use HTML comment syntax with a newline after slide:
<!-- slide
## Slide Title
Markdown content for this slide.
-->
Content outside of slide blocks is document-only. This means you can write a comprehensive article and embed a condensed slide deck in the same file — the document is the long-form version, the slides are the highlights.
Layout Components
Four components control slide structure:
| Component | Props | Purpose |
|---|---|---|
<Slide> |
background, transition, notes |
Slide-level configuration (optional wrapper) |
<Center> |
— | Vertical and horizontal centering |
<Cols> |
ratio (default "1:1") |
Side-by-side columns |
<Pane> |
— | Column slot inside <Cols> |
Example: Title Slide
<!-- slide
<Slide background="#0F0A1E">
<Center>
# Welcome to ShowMe
Turn markdown into shareable documents and presentations
</Center>
</Slide>
-->
Example: Two-Column Layout
<!-- slide
## Comparison
<Cols ratio="60:40">
<Pane>
### Before
- Open Google Slides
- Copy-paste content
- Format manually
- Export and upload
</Pane>
<Pane>
### After
- Write markdown
- `npx showme publish`
- Done
</Pane>
</Cols>
-->
Speaker Notes
Use the notes prop on <Slide> to add speaker notes that are not visible to the audience:
<!-- slide
<Slide notes="Mention that this works on mobile too.">
## Cross-Platform
ShowMe documents work everywhere a browser does.
</Slide>
-->
API Reference
Publish
POST /api/v1/publish
Content-Type: application/json
Request body:
{
"markdown": "# Hello\n\nDocument content here.",
"title": "Optional title override",
"theme": "minimal"
}
Response (201):
{
"slug": "a1b2c3d4",
"url": "https://showme.dev/a1b2c3d4"
}
Retrieve Content
GET /api/v1/content/:slug
Response (200):
{
"markdown": "# Hello\n\nDocument content here.",
"title": "Optional title override",
"theme": "minimal"
}
Health Check
GET /health
Returns { "status": "ok" }.
Tips and Best Practices
- Start with frontmatter. Even a simple
titleandtoc: truedramatically improves the reading experience. - Keep slides focused. One heading plus a few bullets or one component per slide. Dense slides lose the audience.
- Use
<Center>for title slides and quote slides. It handles vertical and horizontal alignment automatically. - Test in both modes. Your document should read well as prose. Your slides should stand alone as a presentation.
- Add
tip: trueto Observable Plot marks for hover interactivity. - Combine React state and Plot for interactive charts with controls —
useStatemanages state, Plot renders the visualization. - Custom CSS via frontmatter lets you brand documents without touching the rendering engine.
The Rendering Pipeline
When you publish a document, the ShowMe viewer processes it through a server-side pipeline:
Markdown → Frontmatter extraction
→ Slide block extraction (<!-- slide --> and <!-- component --> blocks)
→ Component blocks → base64-encoded placeholder divs
→ markdown-it rendering (headings, code, tables, links)
→ Reading time estimation
→ HTML response
→ Client: esm.sh/tsx compiles JSX in sandboxed iframes
Headings are assigned unique IDs for anchor linking. The table of contents is generated from all heading levels automatically. Component blocks are isolated in sandboxed iframes so they cannot affect the parent page.
This document was written in ShowMe and published with npx showme publish. Everything you see here — the layout, the interactive widgets, the presentation slides — comes from a single markdown file.