A complete block-based markdown solution with zero dependencies. Parse, create, serialize, and render markdown with full TypeScript support.
| Package | Version | Description |
|---|---|---|
| @create-markdown/core | 0.1.0 | Zero-dependency parsing and serialization |
| @create-markdown/react | 0.1.0 | React components and hooks |
| @create-markdown/preview | 0.1.0 | HTML rendering with Shiki and Mermaid |
| create-markdown | 0.1.0 | Convenience bundle |
- Block-based architecture - Work with structured blocks instead of raw strings
- Bidirectional conversion - Parse markdown to blocks, serialize blocks to markdown
- Rich inline styles - Bold, italic, code, links, strikethrough, highlights
- React components - Optional React bindings for rendering and editing
- HTML preview - Framework-agnostic HTML rendering with themes
- Syntax highlighting - Shiki plugin for code blocks
- Diagrams - Mermaid plugin for flowcharts, sequence diagrams, etc.
- Web Component -
<markdown-preview>custom element - Zero dependencies - Core package has no runtime dependencies
- Full TypeScript - Complete type definitions with generics
# Install individual packages (recommended)
bun add @create-markdown/core
bun add @create-markdown/react
bun add @create-markdown/preview
# Or install the convenience bundle
bun add create-markdownimport { parse, stringify, h1, paragraph } from '@create-markdown/core';
// Parse markdown to blocks
const blocks = parse('# Hello\n\nWorld');
// Create blocks programmatically
const doc = [
h1('Hello'),
paragraph('World'),
];
// Serialize back to markdown
const markdown = stringify(doc);import { BlockRenderer, useDocument, paragraph } from '@create-markdown/react';
function Editor() {
const doc = useDocument([paragraph('Start typing...')]);
return (
<div>
<BlockRenderer blocks={doc.blocks} />
<button onClick={() => doc.appendBlock(paragraph('New paragraph'))}>
Add Paragraph
</button>
</div>
);
}import { renderAsync, shikiPlugin, mermaidPlugin } from '@create-markdown/preview';
import { parse } from '@create-markdown/core';
const blocks = parse(`
# Code Example
\`\`\`typescript
const x = 42;
\`\`\`
\`\`\`mermaid
flowchart LR
A --> B --> C
\`\`\`
`);
const html = await renderAsync(blocks, {
plugins: [shikiPlugin(), mermaidPlugin()],
});<script type="module">
import { registerPreviewElement } from '@create-markdown/preview';
registerPreviewElement();
</script>
<markdown-preview theme="github-dark">
# Hello World
This renders automatically!
</markdown-preview>| Document | Description |
|---|---|
| packages/core/README.md | Core API reference |
| packages/react/README.md | React components guide |
| packages/preview/README.md | Preview and plugins guide |
| ROADMAP.md | Feature roadmap |
| CONTRIBUTING.md | Contribution guidelines |
| INTEGRATION.md | Framework integrations |
# Install dependencies
bun install
# Build all packages
bun run build
# Run tests
bun run test
# Type check
bun run typecheck
# Run the playground
bun run playgroundcreate-markdown/
├── packages/
│ ├── core/ # @create-markdown/core
│ ├── react/ # @create-markdown/react
│ ├── preview/ # @create-markdown/preview
│ └── create-markdown/ # Convenience bundle
├── playground/ # Demo application
└── .github/ # CI/CD workflows
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
MIT