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 inindex.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
import heroImg from "./assets/hero.png"; // processed and hashedexport function Header() { return <img src={heroImg} alt="Hero" />;}<!-- 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:
<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
loaderoption inangular.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.png | public/ → /file.png |
import img from './assets/x.png' | Not default; reference by path |
<img src={img} /> | <img ngSrc="/x.png" ... /> |