A PostHTML plugin that finds and adds adjacent dark and light mode sources for images.
  • TypeScript 100%
Find a file
2026-07-07 15:39:46 -05:00
src fix: ensureFileExistence=false no longer causes an infinite loop 2026-07-07 10:31:53 -05:00
test test: ensure skipping the check for file existence works 2026-07-07 10:37:52 -05:00
.gitignore chore: update .gitignore 2026-06-25 16:10:15 -05:00
CHANGELOG.md chore(release): 1.0.0 2026-07-07 15:39:46 -05:00
eslint.config.ts style: minor change to linting preferences 2026-07-06 19:42:41 -05:00
LICENSE Initial commit 2026-06-23 16:23:28 +00:00
package.json chore: add release script 2026-07-07 15:39:40 -05:00
pnpm-lock.yaml chore: add release script 2026-07-07 15:39:40 -05:00
README.md docs: add shields to readme 2026-07-07 12:18:39 -05:00
tsconfig.build.json chore: update build scripts 2026-07-06 19:44:31 -05:00
tsconfig.json chore: update build scripts 2026-07-06 19:44:31 -05:00

posthtml-auto-picture-prefers-color-scheme

NPM Version License

A PostHTML plugin that finds and adds adjacent dark and light mode sources for images.

Input:

<img src="photo.jpg" />

Output:

<picture>
  <source srcset="photo.light.jpg" media="(prefers-color-scheme: light)" />
  <source srcset="photo.dark.jpg" media="(prefers-color-scheme: dark)" />
  <img src="photo.jpg" alt="" />
</picture>

Install

npm add posthtml posthtml-auto-picture-prefers-color-scheme
pnpm add posthtml posthtml-auto-picture-prefers-color-scheme
yarn add posthtml posthtml-auto-picture-prefers-color-scheme

Usage

import posthtml from "posthtml";
import autoPicturePrefersColorScheme from "posthtml-auto-picture-prefers-color-scheme";

posthtml([
  autoPicturePrefersColorScheme()
])
  .process("<img src='photo.jpg' />")
  .then(result => console.log(result.html));

Result:

<picture>
  <source srcset="photo.light.jpg" media="(prefers-color-scheme: light)" />
  <source srcset="photo.dark.jpg" media="(prefers-color-scheme: dark)" />
  <img src="photo.jpg" alt="" />
</picture>

Options

separator

Type: string
Default: .

When looking for alternatives, text between the final instance of the separator and the file extension is considered.

import posthtml from "posthtml";
import autoPicturePrefersColorScheme from "posthtml-auto-picture-prefers-color-scheme";

posthtml([
  autoPicturePrefersColorScheme({
    "separator": "-",
  })
])
  .process("<img src='photo.jpg' />")
  .then(result => console.log(result.html));

Result:

<picture>
  <source srcset="photo-light.jpg" media="(prefers-color-scheme: light)" />
  <source srcset="photo-dark.jpg" media="(prefers-color-scheme: dark)" />
  <img src="photo.jpg" alt="" />
</picture>

light, dark

Type: string
Default: light, dark

When looking for alternatives, these values are the text to search for between the separator and the extension.

import posthtml from "posthtml";
import autoPicturePrefersColorScheme from "posthtml-auto-picture-prefers-color-scheme";

posthtml([
  autoPicturePrefersColorScheme({
    "light": "day",
    "dark": "night",
  })
])
  .process("<img src='photo.jpg' />")
  .then(result => console.log(result.html));

Result:

<picture>
  <source srcset="photo.day.jpg" media="(prefers-color-scheme: light)" />
  <source srcset="photo.night.jpg" media="(prefers-color-scheme: dark)" />
  <img src="photo.jpg" alt="" />
</picture>

ensureFileExistence

Type: boolean
Default: true

By default, this plugin checks to ensure the files actually exist, because you may have a mix of images that do and dont have alternatives. If set to false, this will update the HTML without performing that check. This could result in 404 errors if you aren't enforcing their existince some other way.

inputPath

Type: string
Default: ./

When ensuring the files exist, the input path is used as the root path to search for those files.