React Essentials — Components, JSX, Props, State & MoreEntry 11 of 11

Static Assets: public/ vs src/assets/

Where to store images and files, and how the build tool treats each location.

Notes

This is build-tool behavior (Vite, in most modern React projects), not React itself.

  • public/ is copied as-is to the site root, not processed or hashed. Reference files by absolute path (/favicon.ico). Use it for favicons, files referenced in index.html, robots.txt, and assets that need a stable URL.
  • src/assets/ files are imported in code, so the bundler processes them, adds a cache-busting hash to the filename, and fails the build if a file is missing. Use it for images used inside components.

Code compare

React (Vite)
import heroImg from "./assets/hero.png"; // processed and hashed​export function Header() {  return <img src={heroImg} alt="Hero" />;}
React (Vite)
<!-- index.html: served from public/ --><link rel="icon" href="/favicon.ico" />

Since v17, new projects use a public/ folder configured under assets in angular.json. Files are referenced by path, not imported:

Angular
<img ngSrc="/hero.png" width="800" height="400" alt="Hero" />

Use NgOptimizedImage (ngSrc) for lazy loading, priority hints, and required dimensions.

Differences and gotchas

  • Angular doesn't import images into TypeScript by default. The esbuild builder can enable it through the loader option in angular.json, but path references are the norm.
  • Files in public/ are never hashed, so browsers may cache stale versions after a deploy. Rename the file or add a version query when it changes.

Quick reference

React (Vite)Angular
public/ → /file.pngpublic/ → /file.png
import img from './assets/x.png'Not default; reference by path
<img src={img} /><img ngSrc="/x.png" ... />