eleventy-video-bro
v0.8.0
Published
Eleventy plugin to optimize all the videos, bro
Maintainers
Readme
An eleventy plugin to optimize videos, bro. Bro helps you stick with best practices like:
- Providing a valid video source, bro.
- Preventing layout shifts by populating the
widthandheightattributes correctly, bro. - Lazy loading videos by adding
loading="lazy", bro.
This plugin was made by a human called Rob OLeary, you can support his work bro.
Installation
Published as eleventy-video-bro on npm. Requires Eleventy version 3 or newer.
npm install --save-dev eleventy-video-broUsage
In your eleventy config file, do the following:
import videoPlugin from "eleventy-video-bro";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(videoPlugin);
};All <video> elements will be processed now, bro. You will see an log item summarising the result of the plugin when you run eleventy in the terminal, like the screenshot below.

The default behaviour is:
- If an invalid
srcis provided or the attribute is omitted or the value is a remote URL, it will result in an error. - The values for the
widthandheightattributes are always provided by the plugin. The attributes are added if they are not present. - Every
<video>element will haveloading="lazy"added. You can override this value in the template, read the Attribute Overrides section for more info. You should review your templates to ensure that videos in the initial viewport are not lazy loaded.
It will run the HTML transformation before any other plugins regardless of where it is located in your eleventy configuration. You can provide Configuration Options to change some behaviours.
Configuration options
You can provide configuration options to change the behaviour of the plugin, bro.
import videoPlugin from "eleventy-video-bro";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(videoPlugin, {
lazyLoading: false,
devMode: false,
failOnError: true
});
};The configuration options are:
lazyLoading: Should lazy loading be set on allvideoelements?- type: boolean
- values:
true(default)false
devMode: Should the markup transformation happen in dev mode (when eleventy is run with either the--serveor--watchflag)?- type: boolean
- values:
true(default)false
failOnError: Will the build fail when an error is encountered when processing a video?- type: boolean
- values:
true: The build will fail.false(default): Logged as an error. You will see the error in the output when eleventy runs.
Attribute overrides
In some cases, you will want to provide your own value and "override" the default provided by the plugin. For example, you do not want every video to be lazy loaded. Videos that are in the initial viewport should be loaded immediately. To load a video immediately, add loading="eager" to the video element in your template as below.
---
title: My cool website
---
<section>
<p>This the home page that has a video in the hero section.</p>
<video loading="eager" src="./screencast.webm"></video>
</section>The plugin will not change the value of the loading attribute in the template example above.
The values of width and height attributes are always provided by the plugin and cannot be overridden.
Supported formats
This plugin uses the MediaInfo library which supports a wide range of containers and formats. Here is an overview of the formats that I have tested:
- AVI (.avi)
- Matroska (.mkv)
- MPEG-2 Video (.mpeg)
- MPEG-4 (.mp4)
- OGG (.ogv)
- Quicktime (.mov)
- WebM (.webm)
- Windows Media video (.wmv)
Implementation overview
This is based on Eleventy's image plugin. At its core is a PostHTML plugin. It operates along a similar line to posthtml-img-autosize.
The MediaInfo library is used to get the metadata for videos. The reading of the video files is cached in memory to reduce the calls to the file system when running in dev mode.
There are no security vurnerabilities when checked with pnpm audit (2026-07-02).
Tests
# run unit tests
npm run testThe Node test runner is used for testing.
Contributions
I am open to contributions. Please raise an issue to discuss first. My time is limited to work on side projects. I want align our expectations. If you have a strong desire for something to be completed, you can offer to pay me for my time and I will treat it as part of my consulting work!
You can read the roadmap section below to see what I intend to work on next, and things that I am considering.
Roadmap
The tasks I will do next are:
- Resolve image sources - Relative image sources (
<img src="./possum.png">) will be co-located to your output directory with the template they are used in. If the same source image is used in multiple templates, it will be written to two different output locations! - Resolve image sources - Absolute image sources (
<img src="/possum.png">) will be normalized relative to your input/content directory and written to your output directory with the default directory (e.g. _site/img/). - Refactor
build-logger.js. It is too gnarly!
Tasks under consideration are:
- Support remote images.
- Perf improvement - Add ability to skip copying files in dev mode like
eleventy-imagedoes. Instead, they are processed when requested by the browser using a middleware built-in to the Eleventy Dev Server. This is enabled or disabled using thetransformOnRequestoption. - Add a
defaultAttributesconfiguration option to allow the user to add any attribute to all videos. - Add an integration test suite that writes a website to disk for a more realistic evaluation?
- Could logged error messages be friendlier? Remove the cruft that comes with system errors e.g. cannot open file
ENONET. - A feature set to transcode video similar to how the
eleventy-imageplugin transcodes images. I am not sure if it is practical to transcode videos in the build step! Transcoding video can be a long running task and could make builds too long. In any case, a mature library for the transcoding would be required,ffmpegis by far and away the best one out there. A static binary offfmpegmust be installed to work with the library in Node. While there are projects likenode-ffmpeg-installerthat look to make this a smooth process, from what I understand there are challenges to finding a reliable cross-platform process that just works! This would be uncharted territory for me.
The bro provides
