@svg-jar/codemod
v0.0.1
Published
A codemod to help users migrate away from ember-svg-jar
Maintainers
Readme
@svg-jar/codemod
A codemod that migrates Ember projects from ember-svg-jar to direct SVG component imports.
What it does
The codemod finds all {{svgJar "..."}} mustache calls in your .gjs and .gts files and replaces them with angle-bracket component invocations backed by direct SVG imports.
Before:
import svgJar from 'ember-svg-jar/helpers/svg-jar';
<template>
{{svgJar "arrow-right" class="icon"}}
{{svgJar "#star" class="star-icon"}}
</template>After:
import ArrowRight from '../../public/icons/arrow-right.svg?unsafe-inline';
import Star from '../../public/icons/star.svg';
<template>
<ArrowRight class="icon" />
<Star class="star-icon" />
</template>How it works
- Reads your
ember-cli-build.js(or.mjs/.cjs) to find configuredsvgJar.sourceDirs - Discovers all
.gjs/.gtstemplate files in the project - For each
{{svgJar "icon-name"}}call, locates the SVG file on disk - Replaces the mustache with a
<ComponentName />invocation, preserving all attributes - Adds an import statement with the correct relative path to the SVG file
- Removes the
ember-svg-jarimport when all icons in a file are resolved
Import path resolution
The codemod generates import paths relative to the file being transformed:
app/components/navbar.gjs → ../../public/icons/menu.svg?unsafe-inline
app/templates/settings/index.gts → ../../../public/icons/settings.svg?unsafe-inlineIf your package.json defines subpath imports that match a source directory, the codemod uses those instead:
{
"imports": {
"#icons/*": "./public/icons/*"
}
}// Uses alias instead of relative path
import Menu from '#icons/menu.svg?unsafe-inline';Inline vs sprite icons
- Inline icons (
{{svgJar "icon"}}) get the?unsafe-inlinequery suffix - Sprite icons (
{{svgJar "#icon"}}) use a plain import path (no suffix) - When the same slug appears as both inline and sprite, the sprite keeps the plain name (
Icon) and the inline variant gets anInlinesuffix (IconInline)
Usage
Run on a whole project
pnpm dlx @svg-jar/codemodRuns the codemod on the current directory. In interactive mode, you'll be prompted before writing changes.
Run on a specific directory
pnpm dlx @svg-jar/codemod app/componentsOnly processes files under app/components/. The project root is inferred from the app/ segment in the path.
Run on a single file
pnpm dlx @svg-jar/codemod app/components/navbar.gjsTransforms only the specified file. The project root is inferred and you'll be prompted to confirm it.
Pass a project root explicitly
pnpm dlx @svg-jar/codemod /path/to/my-ember-appOptions
| Flag | Description |
| --------------- | ----------------------------------------- |
| -d, --dry-run | Preview changes without writing to disk |
| -c, --confirm | Pause after each file and ask to continue |
| -V, --version | Print the version number |
| -h, --help | Show help |
Dry run
pnpm dlx @svg-jar/codemod --dry-runShows which files would be changed and reports any issues without modifying anything.
Step-through mode
pnpm dlx @svg-jar/codemod --confirmPauses after each file is processed and asks "Continue to next file?". Useful for reviewing changes one at a time.
Report output
After the run completes, the codemod prints an ESLint-style report for any issues found:
app/components/broken-component.gjs
5 warning Icon "nonexistent-icon" not found in any source directory
app/components/ambiguous.gjs
8 warning Icon "arrow" found in multiple source directories
- public/icons/arrow.svg
- vendor/icons/arrow.svg
2 warnings (1 unresolved, 1 ambiguous)
8 files changed out of 10 scanned- Unresolved icons - the SVG file was not found in any source directory. The
{{svgJar ...}}call is left unchanged and theember-svg-jarimport is kept. - Ambiguous icons - the SVG file exists in multiple source directories. The first match is used, but you should verify the correct one was chosen.
Programmatic API
The codemod can also be used as a library:
import { run } from '@svg-jar/codemod';
const { output, unresolvedIcons, ambiguousIcons } = run(source, filePath, {
projectRoot: '/path/to/project',
});For more control, use transform() directly with pre-computed configuration:
import { transform } from '@svg-jar/codemod';
const result = transform(source, filePath, {
projectRoot: '/path/to/project',
sourceDirs: ['public/icons'],
importAliases: [],
});Requirements
- Node.js >= 20
- Ember projects using
.gjsor.gtstemplate files - Icons must exist as
.svgfiles in the configured source directories
Configuration
The codemod reads configuration from your existing project files:
ember-cli-build.js(or.mjs/.cjs) --svgJar.sourceDirsdetermines where to look for SVG files. Defaults to['public']if not configured.package.json--importsfield entries matching source directories are used as import aliases.
