Remix CLI
rmx-cli is a command-line interface tool designed specifically for Remix applications, providing utility functions to enhance development workflows. The current stable version, as of the provided information, is 0.4.16. Its primary feature highlighted is the `svg-sprite` command, which automates the generation of SVG sprite files along with corresponding, fully-typed React components. This command can create either a single default `Icon` component that accepts an `icon` prop, or individual named components for each SVG, based on command-line flags. It also exports the `href` to the sprite file, facilitating its use in Remix's `links` export for preloading. The project appears to be actively maintained, with new features like `svg-sprite` recently introduced, though a fixed release cadence is not explicitly stated. A key differentiator is its tight integration with the Remix ecosystem, including type generation for icon names and components optimized for Remix's server-side rendering and asset linking.
Common errors
-
Error: Unknown command 'svg-sprite'
cause `rmx-cli` is not installed or `npx` cannot locate it in your project's `node_modules`.fixEnsure `rmx-cli` is installed as a development dependency: `npm install -D rmx-cli` or `yarn add -D rmx-cli`. Then, execute commands using `npx rmx-cli ...`. -
Cannot find module '~/components/icons/icons' or its corresponding type declarations.
cause The generated icon component file path is incorrect, or the file was not generated as expected.fixVerify the `OUTPUT_PATH` argument used with `rmx-cli svg-sprite`. Ensure the path in your `import` statement exactly matches the generated file's location (e.g., `app/components/icons/icons.tsx`). Also, check for typos in the path or filename. -
Type error: Property 'icon' does not exist on type 'SVGProps<SVGSVGElement>'
cause You are attempting to use the default `Icon` component's `icon` prop on a named icon component (e.g., `BookmarkIcon`), or vice-versa.fixIf using the default `Icon` component, ensure it's imported (e.g., `import Icon from '...'`) and you pass `icon="name"`. If using named components (e.g., `import { BookmarkIcon } from '...'`), use them directly as `<BookmarkIcon />` without an `icon` prop.
Warnings
- gotcha The behavior of `OUTPUT_PATH` differs based on whether it's a folder or a filename. If it's a folder, `rmx-cli` will generate `icons.tsx` and `icons.svg` (by default) within it. If it's a filename (e.g., `app/components/icons/my-icons.tsx`), that filename will be used as the base for both the TypeScript component and the SVG sprite.
- gotcha The `svg-sprite` command's `--components` flag significantly alters how you import and use icons. Without it, you import a single default `Icon` component and pass an `icon` prop. With it, you import specific named components for each SVG, which are then used directly as JSX elements.
- gotcha By default, `rmx-cli`'s `svg-sprite` command sets `fill` and `stroke` attributes to `currentColor`, which allows icons to inherit text color via CSS. If your SVGs have specific embedded colors that you wish to preserve, you must use `--fill=keep` and/or `--stroke=keep` arguments.
- gotcha The package is in a 0.x version series, meaning its API is not yet stable and breaking changes may occur in minor or patch releases without following strict semantic versioning practices. Always check the changelog when updating.
Install
-
npm install rmx-cli -
yarn add rmx-cli -
pnpm add rmx-cli
Imports
- RadixIcon
const RadixIcon = require('~/components/radixicons')import { default as RadixIcon } from '~/components/radixicons' - href
import spriteHref from '~/components/radixicons/sprite.svg'
import { href as spriteHref } from '~/components/radixicons' - ArchiveBoxIcon
import ArchiveBoxIcon from '~/components/heroicons/24/outline'
import { ArchiveBoxIcon } from '~/components/heroicons/24/outline' - IconName
import { type IconName } from '~/components/radixicons'
Quickstart
import { json, type LinksFunction } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
import tailwindCss from '~/styles/tailwind.css'; // Assuming you have tailwind CSS
// Install the CLI:
// npm install -D rmx-cli
// Create a directory for your SVG assets, e.g., 'assets/svg'
// Add some SVG files inside 'assets/svg'
// Run the SVG sprite generation command:
// npx rmx-cli svg-sprite assets/svg app/components/icons
// The command above generates files like `app/components/icons/icons.tsx` and `app/components/icons/icons.svg`
// Import the generated default Icon component and its sprite href
import Icon, { href as iconsSpriteHref } from '~/components/icons/icons';
// If you used the --components flag, you would import specific icons like this:
// import { BookmarkIcon, EnvelopeOpenIcon } from '~/components/icons/icons';
export const links: LinksFunction = () => [
{ rel: 'preload', href: iconsSpriteHref, as: 'image' },
{ rel: 'stylesheet', href: tailwindCss }
];
export const loader = async () => {
return json({ message: 'Welcome to Remix!' });
};
export default function Index() {
const { message } = useLoaderData<typeof loader>();
return (
<div className="font-sans p-4">
<h1 className="text-3xl font-bold mb-4">{message}</h1>
<div className="flex items-center space-x-2">
<p>Using generated SVG icons:</p>
{/* Example of using the default Icon component */}
<Icon icon="bookmark" size="lg" className="text-blue-500" />
<Icon icon="envelope-open" size="lg" className="text-green-500" />
{/* If using --components, you would use:
<BookmarkIcon className="text-blue-500 w-6 h-6" />
<EnvelopeOpenIcon className="text-green-500 w-6 h-6" />
*/}
</div>
</div>
);
}