diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1eb99c6..4148966 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- [#40](https://github.com/green-code-initiative/creedengo-javascript/pull/40) Add rule `@creedengo/avoid-autoplay` (GCI36)
+- [#46](https://github.com/green-code-initiative/creedengo-javascript/pull/46) Add rule `@creedengo/prefer-lighter-formats-for-image-files` (GCI31)
## [2.0.0] - 2025-01-22
diff --git a/eslint-plugin/README.md b/eslint-plugin/README.md
index 0285cea..35086e1 100644
--- a/eslint-plugin/README.md
+++ b/eslint-plugin/README.md
@@ -74,21 +74,22 @@ Add `@creedengo` to the `plugins` section of your `.eslintrc`, followed by rules
⚠️ Configurations set to warn in.\
✅ Set in the `recommended` configuration.
-| Name | Description | ⚠️ |
-| :------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :- |
-| [avoid-autoplay](docs/rules/avoid-autoplay.md) | Avoid autoplay for videos and audio content | ✅ |
-| [avoid-brightness-override](docs/rules/avoid-brightness-override.md) | Should avoid to override brightness | ✅ |
-| [avoid-css-animations](docs/rules/avoid-css-animations.md) | Avoid usage of CSS animations | ✅ |
-| [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications | ✅ |
-| [limit-db-query-results](docs/rules/limit-db-query-results.md) | Should limit the number of returns for a SQL query | ✅ |
-| [no-empty-image-src-attribute](docs/rules/no-empty-image-src-attribute.md) | Disallow usage of image with empty source attribute | ✅ |
-| [no-import-all-from-library](docs/rules/no-import-all-from-library.md) | Should not import all from library | ✅ |
-| [no-multiple-access-dom-element](docs/rules/no-multiple-access-dom-element.md) | Disallow multiple access of same DOM element | ✅ |
-| [no-multiple-style-changes](docs/rules/no-multiple-style-changes.md) | Disallow multiple style changes at once | ✅ |
-| [no-torch](docs/rules/no-torch.md) | Should not programmatically enable torch mode | ✅ |
-| [prefer-collections-with-pagination](docs/rules/prefer-collections-with-pagination.md) | Prefer API collections with pagination | ✅ |
-| [prefer-shorthand-css-notations](docs/rules/prefer-shorthand-css-notations.md) | Encourage usage of shorthand CSS notations | ✅ |
-| [provide-print-css](docs/rules/provide-print-css.md) | Enforce providing a print stylesheet | ✅ |
+| Name | Description | ⚠️ |
+| :--------------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :- |
+| [avoid-autoplay](docs/rules/avoid-autoplay.md) | Avoid autoplay for videos and audio content | ✅ |
+| [avoid-brightness-override](docs/rules/avoid-brightness-override.md) | Should avoid to override brightness | ✅ |
+| [avoid-css-animations](docs/rules/avoid-css-animations.md) | Avoid usage of CSS animations | ✅ |
+| [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications | ✅ |
+| [limit-db-query-results](docs/rules/limit-db-query-results.md) | Should limit the number of returns for a SQL query | ✅ |
+| [no-empty-image-src-attribute](docs/rules/no-empty-image-src-attribute.md) | Disallow usage of image with empty source attribute | ✅ |
+| [no-import-all-from-library](docs/rules/no-import-all-from-library.md) | Should not import all from library | ✅ |
+| [no-multiple-access-dom-element](docs/rules/no-multiple-access-dom-element.md) | Disallow multiple access of same DOM element | ✅ |
+| [no-multiple-style-changes](docs/rules/no-multiple-style-changes.md) | Disallow multiple style changes at once | ✅ |
+| [no-torch](docs/rules/no-torch.md) | Should not programmatically enable torch mode | ✅ |
+| [prefer-collections-with-pagination](docs/rules/prefer-collections-with-pagination.md) | Prefer API collections with pagination | ✅ |
+| [prefer-lighter-formats-for-image-files](docs/rules/prefer-lighter-formats-for-image-files.md) | Prefer lighter formats for image files | ✅ |
+| [prefer-shorthand-css-notations](docs/rules/prefer-shorthand-css-notations.md) | Encourage usage of shorthand CSS notations | ✅ |
+| [provide-print-css](docs/rules/provide-print-css.md) | Enforce providing a print stylesheet | ✅ |
diff --git a/eslint-plugin/docs/rules/prefer-lighter-formats-for-image-files.md b/eslint-plugin/docs/rules/prefer-lighter-formats-for-image-files.md
new file mode 100644
index 0000000..d8e3e29
--- /dev/null
+++ b/eslint-plugin/docs/rules/prefer-lighter-formats-for-image-files.md
@@ -0,0 +1,88 @@
+# Prefer lighter formats for image files (`@creedengo/prefer-lighter-formats-for-image-files`)
+
+⚠️ This rule _warns_ in the ✅ `recommended` config.
+
+
+
+## Why is this an issue?
+
+Using appropriate image formats and optimizing image sizes is essential for improving website performance, user experience, and overall environmental impact.
+Larger image file sizes consume more bandwidth, increasing the data transfer required to load a web page.
+Some image formats are generally considered better for eco-friendly web design and should be used in most cases.
+
+We recommend using the following formats:
+
+- **WebP**, developed by Google, is a modern image format that provides high compression efficiency without significant loss of quality.
+- **AVIF** (AV1 Image File Format) is a relatively new and highly efficient image format that is based on the AV1 video codec.
+- **SVG** (Scalable Vector Graphics) is a vector image format that is based on XML.
+ Files are lightweight and can be scaled without loss of quality.
+
+```html
+
//
+Non-compliant
+
+
//
+Compliant
+```
+
+Remember that the best image format may vary depending on the specific use case, content, and requirements of your website.
+Always test and evaluate the performance of different formats to find the optimal balance between image quality and file size.
+
+### Picture
+
+Images often represent most of the downloaded bytes, right after videos and just before CSS and JavaScript libraries.
+Optimizing images is important to reduce used bandwidth. The first step is to choose the ideal format for your
+display needs.
+
+Raster images should be reserved for photos and interface elements that cannot be displayed with icons or CSS styles.
+
+The appropriate format depends on the image properties : black & white or color, color palette, need for transparency...
+Among these properties, the possibility to irremediably alter images quality (lossy compression) tends to favor formats such as JPEG, JPEG XL,
+AVIF, or WebP, while needing transparency and/or the impossibility to alter the image quality (lossless compression) will tend to favor
+PNG or WebP lossless formats (which supports transparency).
+
+Format importantly impacts images size: on average, .webp images will be 30% lighter than .jpeg
+images or .png images. .avif images can be up to 20% lighter than .webp image and 50% lighter than .jepg images.
+
+Don't forget to pay attention to browser support. .webp images will not be recognized by
+old browsers and will not be displayed. It is possible to provide several formats for the same image
+to overcome this issue. Some server-side modules (such as Google's modPageSpeed, also available for Apache
+and Nginx) even allow you to provide the appropriate image for the browser that is calling the server.
+
+Many tools will help you minimize images size:
+
+- SQUOOSH
+- CLOUDINARY
+- ImageMagick
+- PngCrush
+- JpegTran
+
+### Example
+
+In this example, the DOM element informs the browser that there are two images: a .webp image and a
+.jpg image, which is used by default. The browser will decide which image will be downloaded. If the .webp format
+is supported, the image.webp image will be downloaded; otherwise, image.jpg image will be downloaded.
+
+```html
+
+
+
+
+```
+
+Also remember to consider browser compatibility.
+Older browsers may not recognize .webp/.avif images and fail to display them.
+To address this issue, you can supply multiple formats for the same image.
+
+## Resources
+
+### Documentation
+
+- [CNUMR best practices](https://github.com/cnumr/best-practices/blob/main/chapters/BP_080_en.md) - Optimize images
+- [WSG UX15-2](https://w3c.github.io/sustyweb/star.html#UX15-2) - Optimizing All Image Assets for a Variety of Different Resolutions
+- [RGESN 5.1](https://ecoresponsable.numerique.gouv.fr/publications/referentiel-general-ecoconception/critere/5.1/) - Référentiel général d'écoconception de services numériques 🇫🇷
+
+### Articles & blog posts
+
+- [greenspector.com - Which image format choose to reduce energy consumption and environmental impact?](https://greenspector.com/en/which-image-format-to-choose-to-reduce-its-energy-consumption-and-its-environmental-impact/)
+- [dodonut.com - The Most Efficient Web Image Formats. Use Cases For Different Types Of Images.](https://dodonut.com/blog/use-cases-of-web-image-formats/)
diff --git a/eslint-plugin/lib/rules/prefer-lighter-formats-for-image-files.js b/eslint-plugin/lib/rules/prefer-lighter-formats-for-image-files.js
new file mode 100644
index 0000000..f3c9c85
--- /dev/null
+++ b/eslint-plugin/lib/rules/prefer-lighter-formats-for-image-files.js
@@ -0,0 +1,72 @@
+/*
+ * creedengo JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
+ * Copyright © 2023 Green Code Initiative (https://green-code-initiative.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+"use strict";
+
+/** @type {import('eslint').Rule.RuleModule} */
+module.exports = {
+ meta: {
+ type: "suggestion",
+ docs: {
+ description: "Prefer lighter formats for image files",
+ category: "eco-design",
+ recommended: "warn",
+ },
+ messages: {
+ PreferLighterFormatsForImageFiles:
+ "You should use lighter formats for image files such as {{ eligibleExtensions }}",
+ },
+ schema: [],
+ },
+ create(context) {
+ const eligibleExtensions = ["webp", "avif", "svg", "jxl"];
+
+ return {
+ JSXOpeningElement(node) {
+ const tagName = node.name.name;
+ if (tagName?.toLowerCase() !== "img") return;
+
+ const parentTagName = node.parent?.parent?.openingElement?.name?.name;
+ if (parentTagName?.toLowerCase() === "picture") return;
+
+ const srcAttribut = node.attributes.find(
+ (attr) => attr.name.name === "src",
+ );
+
+ let srcValue = srcAttribut?.value?.value;
+
+ if (!srcValue) return;
+
+ srcValue = srcValue.substring(srcValue.lastIndexOf("/") + 1);
+ const dotIndex = srcValue.lastIndexOf(".");
+
+ if (dotIndex === -1) return;
+
+ const imgExtension = srcValue.substring(dotIndex + 1);
+
+ if (eligibleExtensions.includes(imgExtension.toLowerCase())) return;
+
+ context.report({
+ node,
+ messageId: "PreferLighterFormatsForImageFiles",
+ data: { eligibleExtensions: eligibleExtensions.join(", ") },
+ });
+ },
+ };
+ },
+};
diff --git a/eslint-plugin/tests/lib/rules/prefer-lighter-formats-for-image-files.js b/eslint-plugin/tests/lib/rules/prefer-lighter-formats-for-image-files.js
new file mode 100644
index 0000000..979fe9d
--- /dev/null
+++ b/eslint-plugin/tests/lib/rules/prefer-lighter-formats-for-image-files.js
@@ -0,0 +1,86 @@
+/*
+ * creedengo JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
+ * Copyright © 2023 Green Code Initiative (https://green-code-initiative.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const rule = require("../../../lib/rules/prefer-lighter-formats-for-image-files");
+const RuleTester = require("eslint").RuleTester;
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({
+ parserOptions: {
+ ecmaVersion: 2021,
+ sourceType: "module",
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+});
+
+const preferLighterFormatsForImageFilesError = {
+ messageId: "PreferLighterFormatsForImageFiles",
+ type: "JSXOpeningElement",
+};
+
+ruleTester.run("prefer-lighter-formats-for-image-files", rule, {
+ valid: [
+ `
+
+ `,
+ `
+
+ `,
+ `
+
+ `,
+ `
+
+
+
+
+ `,
+ `
+
+ `,
+ `
+
+ `,
+ ],
+
+ invalid: [
+ {
+ code: `
+
+ `,
+ errors: [preferLighterFormatsForImageFilesError],
+ },
+ {
+ code: `
+
+ `,
+ errors: [preferLighterFormatsForImageFilesError],
+ },
+ ],
+});
diff --git a/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/CheckList.java b/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/CheckList.java
index b6a6bcd..6fb8973 100644
--- a/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/CheckList.java
+++ b/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/CheckList.java
@@ -45,6 +45,7 @@ public static List> getAllChecks() {
NoMultipleStyleChanges.class,
NoTorch.class,
PreferCollectionsWithPagination.class,
+ PreferLighterFormatsForImageFiles.class,
PreferShorthandCSSNotations.class,
ProvidePrintCSS.class
);
diff --git a/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/checks/PreferLighterFormatsForImageFiles.java b/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/checks/PreferLighterFormatsForImageFiles.java
new file mode 100644
index 0000000..58dd4b8
--- /dev/null
+++ b/sonar-plugin/src/main/java/org/greencodeinitiative/creedengo/javascript/checks/PreferLighterFormatsForImageFiles.java
@@ -0,0 +1,37 @@
+/*
+ * Creedengo JavaScript plugin - Provides rules to reduce the environmental footprint of your JavaScript programs
+ * Copyright © 2023 Green Code Initiative (https://green-code-initiative.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.greencodeinitiative.creedengo.javascript.checks;
+
+import org.sonar.check.Rule;
+import org.sonar.plugins.javascript.api.EslintBasedCheck;
+import org.sonar.plugins.javascript.api.JavaScriptRule;
+import org.sonar.plugins.javascript.api.TypeScriptRule;
+
+@JavaScriptRule
+@TypeScriptRule
+@Rule(key = PreferLighterFormatsForImageFiles.RULE_KEY)
+public class PreferLighterFormatsForImageFiles implements EslintBasedCheck {
+
+ public static final String RULE_KEY = "GCI31";
+
+ @Override
+ public String eslintKey() {
+ return "@creedengo/prefer-lighter-formats-for-image-files";
+ }
+
+}
diff --git a/sonar-plugin/src/main/resources/org/greencodeinitiative/creedengo/profiles/javascript_profile.json b/sonar-plugin/src/main/resources/org/greencodeinitiative/creedengo/profiles/javascript_profile.json
index e20d8f5..8be08f9 100644
--- a/sonar-plugin/src/main/resources/org/greencodeinitiative/creedengo/profiles/javascript_profile.json
+++ b/sonar-plugin/src/main/resources/org/greencodeinitiative/creedengo/profiles/javascript_profile.json
@@ -9,6 +9,7 @@
"GCI26",
"GCI29",
"GCI30",
+ "GCI31",
"GCI36",
"GCI523",
"GCI530"