A remark plugin compatible with the Obsidian image size syntax, operating solely on the alt text of images.
It parses Obsidian's  notation into standard mdast image node modifications, so that the dimensions flow correctly onto the rendered <img> through the default remark-rehype → rehype-stringify pipeline — no custom rehype step required.
Size directives are placed at the end of the image alt, separated by |:
| Syntax | Result |
|---|---|
![alt|100] |
Width 100px (height auto) |
![alt|100x200] |
Width 100px / Height 200px |
![alt|x200] |
Height 200px only (width auto) |
![alt|caption] |
Non-numeric suffix, treated as normal alt |
![alt|] |
Empty suffix, treated as normal alt |
- Sizes are non-negative integers (unit: px).
- Missing dimensions remain auto (e.g.
|100sets only width). - Non-numeric suffixes (e.g. a real caption like
|A nice figure) are not treated as size directives — they are preserved as-is and won't break your document. - Only the last
|segment is considered a size directive; earlier|segments are preserved as part of the caption.
npm install remark-image-resize --save-devimport { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import { remarkImageResize } from '@show-docs/remark-image-resize';
const html = await unified()
.use(remarkParse)
.use(remarkImageResize)
.use(remarkRehype)
.use(rehypeStringify)
.process('');
// <img src="img.png" alt="big" width="300" height="400">remarkImageResize({
// 'attribute' (default): outputs <img width="300" height="400">
// 'style': outputs <img style="width:300px;height:400px">
property: 'attribute',
// 'remark' (default): only handles Markdown images 
// 'mdx': also handles MDX <img> JSX elements (see below)
syntax: 'remark'
});By default the plugin only handles Markdown  images. To also
resize MDX <img> JSX elements (<img alt="big|300x400" />), set
syntax: 'mdx':
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkMdx from 'remark-mdx';
import { remarkImageResize } from 'remark-image-resize';
const tree = await unified()
.use(remarkParse)
.use(remarkMdx)
.use(remarkImageResize, { syntax: 'mdx' })
.process('<img src="img.png" alt="big|300x400" />');In 'mdx' mode the plugin walks all <img> JSX elements, parses the
|WxH suffix from the end of the alt attribute, writes the dimensions
onto width / height (or style) attributes, and strips the |WxH
suffix from alt. Markdown  images keep using
hProperties — the plugin does not convert them to JSX elements so
that toolchain plugins (e.g. Docusaurus's transformImage) can still
process them normally.
Note: MDX is typically compiled to JSX (e.g. via
@mdx-js/mdx) rather than rendered directly to HTML, so the plugin modifiesmdxJsx*nodes on the mdast tree. Final serialization depends on your MDX toolchain.
Docusaurus has a built-in transformImage remark plugin that converts
Markdown  images into MDX JSX <img> elements and wraps the
src with a webpack require() call so images get bundled. This plugin
runs before custom remarkPlugins.
When using syntax: 'mdx', simply place the plugin in remarkPlugins
(the default position). Docusaurus's transformImage will run first,
converting  into an <img> JSX element (with
require-wrapped src), and then this plugin will overwrite the
width/height attributes with your resize instruction:
// docusaurus.config.js
import { remarkImageResize } from 'remark-image-resize';
export default {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
remarkPlugins: [[remarkImageResize, { syntax: 'mdx' }]]
},
blog: {
remarkPlugins: [[remarkImageResize, { syntax: 'mdx' }]]
}
}
]
]
};Then use the Obsidian resize syntax normally in your .md / .mdx files:

<img alt="Another caption|300" src="./photo.png" />Both Markdown images and MDX <img> JSX elements will be resized, and
local images will still be bundled by webpack.