Catalog npm
PACKAGE EXPLORERView in registry

2faguide-rehype-image-dimensions

npm

rehype plugin that adds real width/height, loading and decoding to local markdown & MDX images at build time — zero dependencies, zero runtime JS. Extracted from the 2faguide.com build pipeline.

astroclscore-web-vitalsdimensionshastheightimagelazy-loadingmarkdownmdxrehyperehype-pluginunifiedwidth
Versions collected2
Direct dependencies0From release 0.1.1
Last observed20 Oct, 19:13 UTC

README

Current package documentation

2faguide-rehype-image-dimensions

npm version license dependencies node

A rehype plugin that adds real width / height / loading / decoding attributes to local markdown and MDX images at build time — by reading the image headers off disk. Zero dependencies, zero network calls, and zero JavaScript shipped to the browser.

Extracted from the build pipeline of 2faguide.com, where it removed the layout shift caused by dozens of inline screenshots.

Why

Images without dimensions make the page jump while they load. That is CLS, one of the three Core Web Vitals. The fix is boring but easy to forget:

<img src="/img/a.png" width="640" height="480" loading="lazy" decoding="async" />

This plugin writes those attributes for you, using the real pixel size read from the file — not a guess, and not a runtime measurement.

Install

npm install 2faguide-rehype-image-dimensions

Or from git:

npm install github:notbtc/2faguide-rehype-image-dimensions

Usage

Astro (astro.config.mjs) — this is how 2faguide.com uses it:

import { defineConfig } from 'astro/config';
import rehypeImageDimensions from '2faguide-rehype-image-dimensions';

export default defineConfig({
  markdown: {
    rehypePlugins: [rehypeImageDimensions],
  },
});

With options:

rehypePlugins: [[rehypeImageDimensions, { publicDir: 'public', eagerCount: 2 }]];

Anywhere else in the unified pipeline:

import { unified } from 'unified';
import rehypeParse from 'rehype-parse';
import rehypeStringify from 'rehype-stringify';
import rehypeImageDimensions from '2faguide-rehype-image-dimensions';

const html = await unified()
  .use(rehypeParse, { fragment: true })
  .use(rehypeImageDimensions)
  .use(rehypeStringify)
  .process('<img src="/img/a.png">');

Options

OptionDefaultDescription
publicDir'public'Directory that maps to / on the site. Relative paths resolve against process.cwd().
eagerCount1How many leading images get loading="eager". Everything after is lazy.
overwritefalseReplace existing width / height instead of only filling gaps.
onWarnnull(message) => void — called once per local image whose size could not be read.

Behaviour

  • Only local, absolute-path images are touched (/img/a.png). Remote URLs, data: URIs and relative paths are left exactly as they are.
  • Attributes you already wrote are respected; decoding and loading are only added when missing.
  • Unreadable or missing files are skipped silently (or reported via onWarn) and never break the build.
  • Results are cached per path, so a build with thousands of images stays fast.

Supported formats

Dimensions are sniffed from the file header — no decoder, no image library:

FormatSource of truth
PNGIHDR
JPEGSOF marker
GIFlogical screen descriptor
WebPVP8 / VP8L / VP8X chunk
SVGwidth/height, falling back to viewBox (percentage sizes use viewBox)

About 2faguide

2faguide.com is the documentation site for Free2FA, a free two-factor authenticator for WeChat users with encrypted cloud backup and a recycle bin. This plugin is one of the small build-time tools we pulled out of it.

License

MIT © Free2FA

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 2

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.1Registry latest17 Sept 20260
0.1.017 Sept 20260

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
notbtc/2faguide-rehype-image-dimensions

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 19:13 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:e95bde69f7987a04b1581411bb93aacb18d93cf5ffdf3ae0fb83f5a31817894a