# Importing and Displaying a React PNG Image: The Most Efficient Methods

> Discover the most efficient method for importing and displaying React PNG images. Learn how Webpack asset modules optimize small images and cache larger ones.

- Repository: [Meta/react](https://github.com/facebook/react)
- Tags: how-to-guide
- Published: 2026-02-16

---

**The most efficient way to import and display a PNG image in React is to use the Webpack asset module system, which automatically inlines small images as data URLs and emits larger files with hashed filenames for optimal caching.**

When working with the `facebook/react` repository, understanding how the build system handles static assets is crucial for optimizing your application's performance. The repository's Webpack configuration provides a sophisticated mechanism for **importing and displaying a react png image** that balances bundle size, network requests, and browser caching strategies.

## How React Handles PNG Assets Under the Hood

The React repository defines a specific Webpack rule in [`fixtures/flight/config/webpack.config.js`](https://github.com/facebook/react/blob/main/fixtures/flight/config/webpack.config.js) that processes PNG files during the build. This configuration treats `*.png` files as **asset modules**, applying intelligent optimization based on file size:

```javascript
// fixtures/flight/config/webpack.config.js
{
  test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
  type: 'asset',
  parser: {
    dataUrlCondition: { maxSize: imageInlineSizeLimit },
  },
}

```

The `imageInlineSizeLimit` parameter determines whether a PNG gets inlined as a base64 data URL (for files under the limit) or emitted as a separate file with a content hash (for larger files). This automatic optimization eliminates unnecessary HTTP requests for small icons while ensuring large images benefit from long-term caching via hashed filenames.

## Method 1: Import PNG as a Module (Recommended)

For most component-local images, **importing the PNG as a JavaScript module** provides the best developer experience and runtime performance. This approach leverages Webpack's tree-shaking capabilities and automatic asset optimization.

### Automatic Inlining and Hashing

When you import a PNG file, Webpack processes it through the asset module pipeline:

```tsx
// src/components/Avatar.tsx
import React from 'react';
import avatarImg from './avatar.png';

export default function Avatar() {
  return <img src={avatarImg} alt="User avatar" width={64} height={64} />;
}

```

If `avatar.png` is smaller than `imageInlineSizeLimit` (typically 10,000 bytes), Webpack converts it to a base64 data URL embedded directly in your JavaScript bundle. If larger, Webpack emits the file to `static/media/avatar.[hash].png` and `avatarImg` becomes the hashed URL string, enabling aggressive browser caching.

## Method 2: Reference PNG from the Public Folder

For assets that must remain outside the module system—such as favicons, splash screens, or large background images that change infrequently—use the **public folder** approach.

### When to Use the Public Directory

Files placed in the `public` directory are copied verbatim to the build output root without processing through Webpack. This is useful when you need a predictable URL or when the asset is large enough that you want to avoid including it in the JavaScript bundle.

The React repository demonstrates this pattern in [`fixtures/dom/src/components/Header.js`](https://github.com/facebook/react/blob/main/fixtures/dom/src/components/Header.js):

```javascript
// fixtures/dom/src/components/Header.js
<img
  src={process.env.PUBLIC_URL + '/react-logo.svg'}
  alt="React"
  width="20"
  height="20"
/>

```

For PNG files, the same approach applies:

```tsx
// src/components/Logo.tsx
export default function Logo() {
  return (
    <img
      src={process.env.PUBLIC_URL + '/img/logo.png'}
      alt="Company logo"
      width={120}
      height={40}
    />
  );
}

```

Place `logo.png` in `public/img/logo.png`. The `process.env.PUBLIC_URL` variable ensures the path resolves correctly in both development and production environments.

## Performance Comparison: Module Import vs Public URL

Understanding the trade-offs between these two methods helps optimize your application's loading performance:

- **Module imports** provide automatic optimization, tree-shaking, and cache-busting via content hashing. They are ideal for UI elements, icons, and images that are tightly coupled to specific components.
- **Public folder references** skip Webpack processing entirely, reducing build time for massive assets. They are best for files that must be available at a specific URL or for large images that would bloat the JavaScript bundle if imported as modules.

Both methods leverage the underlying Webpack configuration found in [`fixtures/flight/config/webpack.config.js`](https://github.com/facebook/react/blob/main/fixtures/flight/config/webpack.config.js), ensuring consistent behavior across the React ecosystem.

## Summary

- **Import PNGs as modules** when you want automatic optimization, inlining for small files, and content-hashed filenames for caching.
- **Use the public folder** for large static assets or files that require a predictable URL path, referencing them via `process.env.PUBLIC_URL`.
- The React repository's Webpack configuration in [`fixtures/flight/config/webpack.config.js`](https://github.com/facebook/react/blob/main/fixtures/flight/config/webpack.config.js) handles both approaches efficiently through the `asset` module type.
- Small PNGs (under the `imageInlineSizeLimit`) are automatically converted to base64 data URLs, eliminating HTTP requests.

## Frequently Asked Questions

### What is the imageInlineSizeLimit in React's Webpack configuration?

The `imageInlineSizeLimit` is a configuration parameter that determines the maximum file size (in bytes) for inlining images as base64 data URLs. According to the source code in [`fixtures/flight/config/webpack.config.js`](https://github.com/facebook/react/blob/main/fixtures/flight/config/webpack.config.js), files smaller than this limit are converted to data URLs and embedded directly in the JavaScript bundle, while larger files are emitted to the `static/media` directory with hashed filenames for optimal caching.

### Should I import PNG images or put them in the public folder?

You should **import PNG images as modules** for most component-specific assets that benefit from build-time optimization, automatic inlining, and cache-busting through content hashing. Use the **public folder** only for files that must remain outside the module system, such as favicons, splash screens, or very large images that you want to exclude from the JavaScript bundle. The [`fixtures/dom/src/components/Header.js`](https://github.com/facebook/react/blob/main/fixtures/dom/src/components/Header.js) file demonstrates the public folder approach using `process.env.PUBLIC_URL`.

### How does React handle caching for imported PNG images?

React relies on the underlying Webpack configuration to handle caching through **content hashing**. When you import a PNG file that exceeds the `imageInlineSizeLimit`, Webpack emits the file to `static/media/[name].[hash].[ext]`, where the hash is derived from the file's content. This ensures that browsers can cache the file indefinitely, and the cache is automatically invalidated only when the image content actually changes, as the filename will differ.

### Can small PNG images be inlined automatically in React applications?

Yes, small PNG images are automatically inlined as base64 data URLs when they fall below the `imageInlineSizeLimit` threshold defined in the Webpack configuration. As shown in [`fixtures/flight/config/webpack.config.js`](https://github.com/facebook/react/blob/main/fixtures/flight/config/webpack.config.js), the `asset` module type with the `dataUrlCondition` parser setting handles this optimization automatically. This eliminates the need for an additional HTTP request for small icons or decorative images, improving initial page load performance.