https://github.com/jarred-sumner/svgj
Convert svg to jsx. Its fast.
https://github.com/jarred-sumner/svgj
Last synced: 2 months ago
JSON representation
Convert svg to jsx. Its fast.
- Host: GitHub
- URL: https://github.com/jarred-sumner/svgj
- Owner: Jarred-Sumner
- License: mit
- Created: 2021-03-13T03:37:31.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2022-07-07T10:56:44.000Z (almost 3 years ago)
- Last Synced: 2025-04-06T12:12:18.739Z (2 months ago)
- Language: HTML
- Size: 40 KB
- Stars: 57
- Watchers: 4
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# svgj
`svgj` quickly converts `.svg` files into `jsx`. `svgj` is about 40x faster than `svgr`, depending on how you measure (benchmarks at bottom).
Input:
```html
```
Output:
```jsx
import * as React from "React";export const ReactComponent = ({ ...props }) => (
);
```Compared to `svgr`, `svgj` is buggier, has a worse API, fewer features, only returns JSX as strings that need to be transpiled, and prints ugly looking JSX.
But its much faster, thanks to using `htmlparser2` and serialization logic from `dom-serializer` (with modifications to support JSX and passing in custom props based on element). Consequently, this will often work with html.
You probably only want to use this inside of a bundler when importing SVG files as JSX.
## Usage
You probably want to use the esbuild plugin instead of the underlying library.
### Installation
yarn:
```bash
yarn add esbuild-plugin-svgj
```npm:
```bash
npm install esbuild-plugin-svgj
```### esbuild-plugin-svgj usage
```js
import { plugin } from "esbuild-plugin-svgj";
import { readFile } from "fs/promises";
import esbuild from "esbuild";esbuild.build({
// ...rest of esbuild config
plugins: [
plugin({
readFile: (path) => readFile(path, "utf8"),
}),
],
});
```### Library usage
```ts
export function render(
content: string,
displayName: string = "ReactComponent",
jsxImports: string = "* as React",
jsxFrom: string = "react",
exportName = displayName,
props = defaultProps,
opts = defaultOpts,
useMemo = false
): string;export const defaultOpts: Options = {
removeAttrs: {
xmlns: true,
},
addProps: {
svg: {
props: "...",
},
},
};export const defaultProps: { [key: string]: string } = {
props: "...",
};
```## Benchmarks
These svgs are from bootstrap.
To download the test icons:
```bash
git submodule update --init --recursive
```Then, run `node bench.mjs`.
The first group renders 10 svgs. The second group renders a single svg. The svg files are read from disk as strings before the benchmark starts.
```bash
❯ node bench.mjssvgj x 10,271 ops/sec ±1.06% (90 runs sampled)
svgr sync x 105 ops/sec ±4.86% (74 runs sampled)
Fastest is svgj
Slowest is svgr sync
svgj x 89,124 ops/sec ±1.45% (90 runs sampled)
svgr sync x 1,199 ops/sec ±2.01% (81 runs sampled)
Fastest is svgj
Slowest is svgr sync
```Then, run `node bench-async.mjs`
`benchmark.js` is a little tough to get working right with async code, so this one just uses `console.time`, but with a warmup beforehand. The files in both benchmarks are the same.
```bash
❯ node bench-async.mjssvgj (1 file): 0.128ms
svgr (1 file): 1.675ms
svgj (10 files): 0.376ms
svgr (10 files): 20.193ms
svgj (258 files): 9.493ms
svgr (258 files): 330.877ms
```### TypeScript
This doesn't generate type definitions.
But, you can google `typescript import svg react`. [Here's the first result](https://duncanleung.com/typescript-module-declearation-svg-img-assets/).
To save you a click, add this `.d.ts` and it should work:
```ts
declare module "*.svg" {
import React = require("react");
export const ReactComponent: React.SFC>;
const src: string;
export default src;
}
```Keep in mind that this currently won't `React.forwardRef`. Per `create-react-app`'s defaults, `src` is the source string and `ReactComponent` is the JSX source.