ByteMD is a Markdown editor component built with Svelte. It could also be used in other libraries/frameworks such as React, Vue and Angular.
- Lightweight and framework agnostic: ByteMD is built with Svelte. It compiles to vanilla JS DOM manipulation without importing any UI Framework runtime bundle, which makes it lightweight, and easily adapted to other libraries/frameworks.
- Easy to extend: ByteMD has a plugin system to extend the basic Markdown syntax, which makes it easy to add additional features such as code syntax highlight, math equation and Mermaid flowcharts. You can also write your own plugin if these ones don't meet your needs.
- Secure by default: Cross-site scripting(XSS) attack such as
<script>and<img onerror>have been correctly handled by ByteMD. No need to introduce extra DOM sanitize steps. - SSR compatiable: ByteMD could be used in the Server-side rendering(SSR) environment without extra config. SSR is widely used in some cases due to its better SEO and fast time-to-content in slow network connection.
| Package | Status | Description |
|---|---|---|
| bytemd | Svelte/Vanilla JS component | |
| @bytemd/react | React component | |
| @bytemd/vue | Vue component |
The default entry of NPM package only supports modern browsers. For legacy browsers (IE9+), There is also a ES5 bundle(dist/index.es5.js) to get it work. Notice that polyfills are not included in these bundles and should be imported manually, see the legacy browser example.
There are two components: Editor and Viewer. Editor is the Markdown editor, as the name suggests; Viewer is commonly used to display rendered Markdown results without editing.
Before using the component, remember to import CSS file to make styles correct:
import 'bytemd/dist/index.min.css';<script>
import { Editor, Viewer } from 'bytemd';
import gfm from '@bytemd/plugin-gfm';
let value;
const plugins = [
gfm(),
// Add more plugins here
];
function handleChange(e) {
value = e.detail.value;
}
</script>
<template>
<Editor {value} {plugins} on:change={handleChange} />
</template>import { Editor, Viewer } from '@bytemd/react';
import gfm from '@bytemd/plugin-gfm';
const plugins = [
gfm(),
// Add more plugins here
];
const App = () => {
const [value, setValue] = useState('');
return (
<Editor
value={value}
plugins={plugins}
onChange={(v) => {
setValue(v);
}}
/>
);
};<template>
<Editor :value="value" :plugins="plugins" @change="handleChange" />
</template>
<script>
import { Editor, Viewer } from '@bytemd/vue';
import gfm from '@bytemd/plugin-gfm';
const plugins = [
gfm(),
// Add more plugins here
];
export default {
components: { Editor },
data() {
return { value: '', plugins };
},
methods: {
handleChange(v) {
value = v;
},
},
};
</script>import { Editor, Viewer } from 'bytemd';
import gfm from '@bytemd/plugin-gfm';
const plugins = [
gfm(),
// Add more plugins here
];
const editor = new Editor({
target: document.body, // DOM to render
props: {
value: '',
plugins,
},
});
editor.on('change', (e) => {
editor.$set({ value: e.detail.value });
});| Key | Type | Description |
|---|---|---|
value |
string (required) |
Markdown text |
plugins |
BytemdPlugin[] |
ByteMD plugin list |
sanitize |
(schema: Schema) => Schema |
Sanitize strategy |
Editor component also accepts the options of Viewer. Besides that, there are some other options:
| Key | Type | Description |
|---|---|---|
mode |
`'split' | 'tab'` |
previewDebounce |
number |
Debounce time (ms) for preview |
editorConfig |
documentation | CodeMirror editor config |
The default height of ByteMD's body area (.bytemd-body) is 300px. It could be overrided by CSS:
.bytemd-body {
height: calc(100vh - 200px);
}or by JavaScript (via plugin) if you want more control:
const stylePlugin = {
editorEffect({ $el }) {
const $body = $el.querySelector('.bytemd-body');
$body.style.height = 'calc(100vh - 200px)';
},
};
// Then apply this plugin:
new Editor({
value: '',
plugins: [
stylePlugin,
//...
],
});The other styles could also be overrided, see the default style.
ByteMD uses remark and rehype ecosystem to process Markdown. The complete process is as follows:
- The markdown text is parsed to an AST
- The Markdown AST could be manipulated by several remark plugins
- The Markdown AST is transformed to a HTML AST
- The HTML AST is sanitized for security reason
- The HTML AST could be manipulated by several rehype plugins
- The HTML AST is stringified to HTML
- Some extra DOM manipulation after the HTML being rendered
It could also be described as a flowchart:
The 2,5,7 steps are designed for user customization via ByteMD plugin API.
| Package | Status | Description |
|---|---|---|
| @bytemd/plugin-breaks | Support breaks | |
| @bytemd/plugin-external-links | Open external links in new window | |
| @bytemd/plugin-footnotes | Support footnotes | |
| @bytemd/plugin-frontmatter | Parse frontmatter | |
| @bytemd/plugin-gemoji | Support Gemoji shortcodes | |
| @bytemd/plugin-gfm | Support GFM (autolink literals, strikethrough, tables, tasklists) | |
| @bytemd/plugin-highlight | Highlight code blocks | |
| @bytemd/plugin-highlight-ssr | Highlight code blocks (SSR compatible) | |
| @bytemd/plugin-import-html | Import HTML by pasting or dropping | |
| @bytemd/plugin-import-image | Import image by pasting or dropping | |
| @bytemd/plugin-inject-style | Inject style to markdown body | |
| @bytemd/plugin-math | Support math equation | |
| @bytemd/plugin-math-ssr | Support math equation (SSR compatible) | |
| @bytemd/plugin-medium-zoom | Zoom images like Medium | |
| @bytemd/plugin-mermaid | Support Mermaid diagram and flowchart | |
| @bytemd/plugin-vega | Support vega charts |
TODO
MIT