Markdown Previewer
Write Markdown on the left, see rendered HTML instantly on the right. Side-by-side live preview.
Text
100% Free
Runs in Browser
Preview
Hello World
This is a Markdown Previewer. Try editing the text on the left!
Features
Inline codeBlockquotes are supported too!
Code Block
const greeting = "Hello, World!";
console.log(greeting);
Source Code
markdown-preview.tsx
import { useState } from "react";
import { Textarea } from "@/components/ui/textarea";
export default function MarkdownPreview() {
const [md, setMd] = useState(`# Hello World
This is a **Markdown Previewer**. Try editing the text on the left!
## Features
- **Bold** and *italic* text
- Lists (ordered and unordered)
- \`Inline code\`
- [Links](https://example.com)
- Horizontal rules
---
> Blockquotes are supported too!
### Code Block
\`\`\`
const greeting = "Hello, World!";
console.log(greeting);
\`\`\`
1. First item
2. Second item
3. Third item
`);
// Simple markdown → HTML converter (no dependencies)
const toHtml = (text: string): string => {
let html = text
// Code blocks
.replace(/```([\s\S]*?)```/g, '<pre class="rounded-lg border bg-muted/50 p-3 my-2 overflow-x-auto"><code>$1</code></pre>')
// Inline code
.replace(/`([^`]+)`/g, '<code class="rounded bg-muted px-1.5 py-0.5 text-sm font-mono">$1</code>')
// Headlines
.replace(/^### (.+)$/gm, '<h3 class="text-lg font-semibold mt-4 mb-2">$1</h3>')
.replace(/^## (.+)$/gm, '<h2 class="text-xl font-semibold mt-5 mb-2">$1</h2>')
.replace(/^# (.+)$/gm, '<h1 class="text-2xl font-bold mt-6 mb-3">$1</h1>')
// Bold + Italic
.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>")
.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>")
.replace(/\*(.+?)\*/g, "<em>$1</em>")
// Links
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" class="text-primary underline underline-offset-2" target="_blank" rel="noopener">$1</a>')
// Images
.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" class="rounded-lg max-w-full" />')
// Blockquotes
.replace(/^> (.+)$/gm, '<blockquote class="border-l-4 border-primary/30 pl-4 my-2 italic text-muted-foreground">$1</blockquote>')
// Horizontal rules
.replace(/^---$/gm, '<hr class="my-4 border-border" />')
// Unordered lists
.replace(/^- (.+)$/gm, '<li class="ml-4 list-disc">$1</li>')
// Ordered lists
.replace(/^\d+\. (.+)$/gm, '<li class="ml-4 list-decimal">$1</li>')
// Paragraphs
.replace(/^(?!<[a-z])((?!<).+)$/gm, '<p class="my-1">$1</p>');
return html;
};
return (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 min-h-[400px]">
<Textarea
value={md}
onChange={(e) => setMd(e.target.value)}
className="min-h-[400px] resize-y font-mono text-sm"
placeholder="Write some markdown..."
/>
<div
className="rounded-lg border p-4 overflow-y-auto text-sm leading-relaxed"
dangerouslySetInnerHTML={{ __html: toHtml(md) }}
/>
</div>
);
} import { useState } from "react";
import { Textarea } from "@/components/ui/textarea";
export default function MarkdownPreview() {
const [md, setMd] = useState(`# Hello World
This is a **Markdown Previewer**. Try editing the text on the left!
## Features
- **Bold** and *italic* text
- Lists (ordered and unordered)
- \`Inline code\`
- [Links](https://example.com)
- Horizontal rules
---
> Blockquotes are supported too!
### Code Block
\`\`\`
const greeting = "Hello, World!";
console.log(greeting);
\`\`\`
1. First item
2. Second item
3. Third item
`);
// Simple markdown → HTML converter (no dependencies)
const toHtml = (text: string): string => {
let html = text
// Code blocks
.replace(/```([\s\S]*?)```/g, '<pre class="rounded-lg border bg-muted/50 p-3 my-2 overflow-x-auto"><code>$1</code></pre>')
// Inline code
.replace(/`([^`]+)`/g, '<code class="rounded bg-muted px-1.5 py-0.5 text-sm font-mono">$1</code>')
// Headlines
.replace(/^### (.+)$/gm, '<h3 class="text-lg font-semibold mt-4 mb-2">$1</h3>')
.replace(/^## (.+)$/gm, '<h2 class="text-xl font-semibold mt-5 mb-2">$1</h2>')
.replace(/^# (.+)$/gm, '<h1 class="text-2xl font-bold mt-6 mb-3">$1</h1>')
// Bold + Italic
.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>")
.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>")
.replace(/\*(.+?)\*/g, "<em>$1</em>")
// Links
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" class="text-primary underline underline-offset-2" target="_blank" rel="noopener">$1</a>')
// Images
.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" class="rounded-lg max-w-full" />')
// Blockquotes
.replace(/^> (.+)$/gm, '<blockquote class="border-l-4 border-primary/30 pl-4 my-2 italic text-muted-foreground">$1</blockquote>')
// Horizontal rules
.replace(/^---$/gm, '<hr class="my-4 border-border" />')
// Unordered lists
.replace(/^- (.+)$/gm, '<li class="ml-4 list-disc">$1</li>')
// Ordered lists
.replace(/^\d+\. (.+)$/gm, '<li class="ml-4 list-decimal">$1</li>')
// Paragraphs
.replace(/^(?!<[a-z])((?!<).+)$/gm, '<p class="my-1">$1</p>');
return html;
};
return (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 min-h-[400px]">
<Textarea
value={md}
onChange={(e) => setMd(e.target.value)}
className="min-h-[400px] resize-y font-mono text-sm"
placeholder="Write some markdown..."
/>
<div
className="rounded-lg border p-4 overflow-y-auto text-sm leading-relaxed"
dangerouslySetInnerHTML={{ __html: toHtml(md) }}
/>
</div>
);
} Required Libraries
Install the external dependencies used by this tool.
bun add react
Shadcn UI Setup
Add the required Shadcn UI primitives to your project.
bun x --bun shadcn@latest add textarea
Shadcn UI Components
The following primitives are required in your
@/components/ui
directory.
| Component | Import Path |
|---|---|
| textarea | @/components/ui/textarea |
Imports
All import statements used in this tool.
| Source | Exports |
|---|---|
| react | useState |
| @/components/ui/textarea | Textarea |
State Management
React state variables managed within this tool.
| Variable | Initial Value |
|---|---|
| md | `# Hello World
This is a **Markdown Previewer**. Try editing the text on the left!
## Features
- **Bold** and *italic* text
- Lists (ordered and unordered |
Variables & Constants
Constants and computed values defined in this tool.
| Name | Value |
|---|---|
| greeting | "Hello, World!" |
Functional Logic
Internal functions that handle the tool's core logic.
| Function | Parameters | Async |
|---|---|---|
| toHtml() | text: string | No |
External Resources
Documentation, tutorials, and package details for libraries used in this tool.