Optimal Strategies for Storing Images in React Applications: Best Practices and Examples

Yug JadvaniYug Jadvani
5 min read

Introduction

Storing and handling images in React applications is a fundamental yet often overlooked aspect of development. There are multiple ways to include and manage images, and the approach you choose can impact the performance, scalability, and maintainability of your project. In this post, we'll explore where to store images in React, the different methods available, and analyze whether using the public folder is considered best practice. We'll also look at the pros and cons of each method, backed with practical examples.


Common Ways to Store Images in React

  1. src folder – Importing images in components.

  2. public folder – Direct file referencing.

  3. External URLs – Hosting images on CDNs or cloud storage.

  4. Base64 encoding – Embedding images directly into your code.

Each method has its specific use cases, and choosing the right one depends on the nature of your application and its performance requirements.


1. Importing Images in the src Folder

When storing images in the src folder, you import them directly into your React components. This approach allows you to bundle images using Webpack or any other module bundler.

Example:

import React from 'react';
import logo from './assets/logo.png';

const Header: React.FC = () => {
  return (
    <header>
      <img src={logo} alt="Logo" />
    </header>
  );
};

export default Header;

Advantages:

  • Bundling: Webpack handles image optimization and bundling automatically, which can lead to better performance and smaller bundle sizes.

  • Version control: Images are part of your source code and are tracked by Git, ensuring no missing files across environments.

Disadvantages:

  • Size limitations: Large numbers of images can bloat the bundle size, affecting the initial load time.

  • Dynamic images: You cannot easily reference images dynamically unless you use a specific require statement.

When to use:

  • Ideal for smaller projects where the number of images is limited.

  • Best suited for images that are part of the UI (e.g., logos, icons).


2. Storing Images in the public Folder

The public folder in React is accessible directly by URL and bypasses the Webpack bundling process. You can reference images via a relative or absolute URL.

Example:

const HomePage: React.FC = () => {
  return (
    <div>
      <img src={`${process.env.PUBLIC_URL}/images/hero-banner.png`} alt="Hero Banner" />
    </div>
  );
};

export default HomePage;

Here, the PUBLIC_URL environment variable is used to point to the correct path, making the code more dynamic and portable.

Advantages:

  • Direct URL access: Images are accessible by direct URL (e.g., http://localhost:3000/images/hero-banner.png), making it ideal for serving static assets.

  • Avoid bundling: Bypasses Webpack bundling, so large files won't bloat your JavaScript bundles.

  • Flexibility: You can easily reference images dynamically since they are accessible via a URL.

Disadvantages:

  • No optimization: Webpack doesn’t optimize these images. You'll need to handle image compression and caching strategies separately.

  • No version control: If not included in your Git repo, these assets can be lost or out of sync between environments (especially if you’re using a CI/CD pipeline).

  • Browser caching: Public assets are typically cached by the browser, so updates to images might not reflect immediately without proper cache busting.

Best Practice:

  • Use the public folder for assets that are not part of your React component lifecycle (e.g., large background images, favicons, and static assets).

  • Avoid storing all images here if you want Webpack to handle optimization.


3. Using External URLs

Hosting images on an external server, CDN, or cloud storage like AWS S3 or Cloudflare is another effective strategy. This decouples image storage from your application code, offering more flexibility.

Example:

const Profile: React.FC = () => {
  return (
    <div>
      <img src="https://cdn.example.com/profiles/user123.jpg" alt="User Profile" />
    </div>
  );
};

export default Profile;

Advantages:

  • Performance: CDNs (Content Delivery Networks) optimize image delivery by caching files closer to the user.

  • Scalability: You don’t need to worry about local storage limits or performance degradation as the number of images grows.

  • Efficient caching: CDNs handle caching and content delivery efficiently.

Disadvantages:

  • External dependency: If the CDN or external service is down, images won’t load.

  • Complexity: Managing multiple external resources can introduce complexity in terms of integration, permissions, and monitoring.

When to use:

  • Best for large-scale applications where performance and scalability are critical, and when you have a lot of media assets.

4. Base64 Encoding Images

In certain situations, it’s useful to convert images to Base64 format and embed them directly in the code.

Example:

const Avatar: React.FC = () => {
  const base64Image = 'data:image/png;base64,...'; // truncated

  return (
    <img src={base64Image} alt="Avatar" />
  );
};

export default Avatar;

Advantages:

  • No network request: The image is embedded directly in the HTML/CSS, eliminating the need for an HTTP request.

  • Great for small images: Works well for small icons and logos, especially in emails or situations where reducing HTTP requests is crucial.

Disadvantages:

  • File size: Base64 encoded images can significantly increase the size of your HTML/CSS.

  • Harder to maintain: Large Base64 strings are difficult to manage and read.

When to use:

  • Best for small images like icons or thumbnails that are reused frequently within your application.

Conclusion: Which Approach is Best?

The best method depends on your application's requirements.

  • Small projects: Storing images in the src folder and importing them is a simple and effective approach.

  • Larger applications: For better performance, you might want to consider using the public folder for static assets, or even better, host your images on a CDN for optimized delivery.

  • Base64 encoding is only practical for small, frequently-used images where HTTP requests should be minimized.

Using the public folder can be advantageous in scenarios where you want more flexibility and to avoid bundling. However, for more dynamic or scalable applications, offloading images to external storage solutions, or using optimized CDN services, will provide the most benefits in terms of performance and maintainability.


Final Thoughts

Choosing the right image storage strategy is crucial for building performant React applications. By understanding the trade-offs between the various methods available, you can optimize your app’s load time, maintainability, and user experience.

What approach do you use to store images in your React apps? Share your thoughts in the comments below!


Enjoyed the read? If you found this article insightful or helpful, consider supporting my work by buying me a coffee. Your contribution helps fuel more content like this. [Click here](https://buymeacoffee.com/yugjadvani9) to treat me to a virtual coffee. Cheers!

0
Subscribe to my newsletter

Read articles from Yug Jadvani directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Yug Jadvani
Yug Jadvani

Senior Frontend Engineer | Expert in React, Next.js, Tailwind | Passionate About Web & Mobile App Development | Tech Writer