esbuild "No loader is configured for ... files" - Fix in CI
esbuild bundles plain JS/TS and a known set of extensions out of the box. When it meets an extension it has no loader for - a .svg, .png, a custom file type, or JSX in an unexpected extension - it stops because it does not know how to turn that file into a module.
What this error means
A direct esbuild build (or a tool using its API) fails with No loader is configured for ".<ext>" files, naming the importing file. It is deterministic - a configuration gap, not flake.
✘ [ERROR] No loader is configured for ".svg" files: src/icons/logo.svg
src/App.tsx:2:17:
2 │ import logo from './icons/logo.svg'
╵ ~~~~~~~~~~~~~~~~~~~Common causes
Asset extension with no loader
Importing .svg, .png, .woff2, or another asset without mapping that extension in loader makes esbuild unable to represent the file as a module.
Code extension esbuild does not default-handle
JSX in a .js file (esbuild does not enable JSX for .js unless told), or a custom code extension, needs an explicit loader like jsx/tsx.
How to fix it
Map each extension to a loader
Set the loader option so esbuild knows how to handle every imported extension.
// build.mjs
import { build } from 'esbuild'
await build({
entryPoints: ['src/App.tsx'],
bundle: true,
loader: { '.svg': 'file', '.png': 'dataurl', '.js': 'jsx' },
outdir: 'dist',
})Enable JSX for the right extensions
- If JSX lives in
.jsfiles, add'.js': 'jsx'(or move JSX into.jsx). - For TS+JSX use the
tsxloader on.tsx. - Confirm every extension you
importappears in theloadermap.
How to prevent it
- Map every imported asset/code extension in esbuild's
loaderoption. - Keep JSX in
.jsx/.tsxso the default loaders apply. - Run the esbuild build in CI so unconfigured loaders fail before deploy.