pure-glyf 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,265 @@
1
+ # pure-glyf
2
+
3
+ **Vite plugin and runtime to compile SVG icons into tree-shakeable CSS masks for modern web applications.**
4
+
5
+ `pure-glyf` takes a different approach to icon management. Instead of inlining SVGs (bloating your DOM) or using sprites (complexity), it converts your SVGs into CSS classes that inject their styles on demand. The result? Zero runtime overhead for unused icons, perfect tree-shaking, and a developer experience that feels like magic.
6
+
7
+ ---
8
+
9
+ ## Features
10
+
11
+ - 🌳 **True Tree-Shaking**: Only the icons you actually import end up in your final bundle.
12
+ - 🚀 **Zero Runtime Overhead**: Icons are just strings (CSS class names). No heavy JS objects or runtime parsers.
13
+ - ⚡ **On-Demand Injection**: CSS for an icon is only injected into the page when you import it.
14
+ - 🧩 **Vite Integration**: A dedicated Vite plugin automates the entire process.
15
+ - 🎨 **Themable**: Icons automatically inherit `currentColor`.
16
+ - 🖥️ **SSR Ready**: Built-in support for server-side rendering (critical CSS extraction).
17
+ - 🏷️ **Type-Safe**: Generated TypeScript definitions for your specific icon set.
18
+
19
+ ## Why pure-glyf?
20
+
21
+ | Method | JS Bundle Size | DOM Size | Tree Shaking | Developer Experience |
22
+ | :--- | :--- | :--- | :--- | :--- |
23
+ | **Inline SVGs** | ❌ Heavy | ❌ Bloated | ✅ Good | 😐 Verbose JSX |
24
+ | **SVG Sprites** | ✅ Light | ✅ Light | ❌ Hard | 😫 Manual Management |
25
+ | **Icon Fonts** | ✅ Light | ✅ Light | ❌ None | 😐 FOUT / Accessibility |
26
+ | **pure-glyf** | ✅ **Minimal** | ✅ **Minimal** | ✅ **Perfect** | 😍 **Auto-generated** |
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ npm install pure-glyf
32
+ # or
33
+ pnpm add pure-glyf
34
+ # or
35
+ yarn add pure-glyf
36
+ ```
37
+
38
+ ## Usage
39
+
40
+ ### 1. Structure Your Icons
41
+
42
+ Place your SVG files in a directory. You can have multiple directories (e.g., for different icon sets).
43
+
44
+ ```
45
+ src/
46
+ assets/
47
+ icons/
48
+ home.svg
49
+ user.svg
50
+ settings.svg
51
+ ```
52
+
53
+ #### Using Icons from npm
54
+ You can also source icons directly from installed packages (e.g., `@tabler/icons`, `@mdi/svg`, `heroicons`). Just install them as dev dependencies!
55
+
56
+ ### 2. Configure Vite
57
+
58
+ Add `pureGlyfPlugin` to your `vite.config.ts`.
59
+
60
+ ```typescript
61
+ // vite.config.ts
62
+ import { defineConfig } from 'vite';
63
+ import { pureGlyfPlugin } from 'pure-glyf/plugin';
64
+
65
+ export default defineConfig({
66
+ plugins: [
67
+ pureGlyfPlugin({
68
+ icons: {
69
+ // 1. Local icons
70
+ // Usage: 'custom' + 'Home' -> customHome
71
+ custom: './src/assets/icons',
72
+
73
+ // 2. Common Icon Libraries (examples)
74
+
75
+ // Tabler Icons (Install: pnpm add -D @tabler/icons) - outline
76
+ // Usage: tablerHome, tablerUser
77
+ tabler: './node_modules/@tabler/icons/icons/outline',
78
+
79
+ // -- or --
80
+
81
+ // Tabler Icons (Install: pnpm add -D @tabler/icons) - all icons
82
+ // Usage: tablerOutlineHome, tablerFilledUser
83
+ tabler: './node_modules/@tabler/icons/icons',
84
+
85
+ // Material Design Icons (Install: pnpm add -D @mdi/svg)
86
+ // Usage: mdiAccount, mdiHome
87
+ mdi: './node_modules/@mdi/svg/svg',
88
+
89
+ // Heroicons (Install: pnpm add -D heroicons)
90
+ // Usage: heroHome, heroUser
91
+ hero: './node_modules/heroicons/24/outline',
92
+
93
+ // Lucide (Install: pnpm add -D lucide-static)
94
+ // Usage: lucHome, lucUser
95
+ luc: './node_modules/lucide-static/icons',
96
+ },
97
+ dts: 'src/pure-glyf-icons.d.ts'
98
+ })
99
+ ]
100
+ });
101
+ ```
102
+
103
+ ### 3. Configure Rollup (Alternative)
104
+
105
+ If you are using Rollup without Vite, use the plugin directly.
106
+
107
+ > **Note**: You must use `@rollup/plugin-node-resolve` so Rollup can resolve the `pure-glyf` runtime.
108
+
109
+ ```javascript
110
+ // rollup.config.js
111
+ import resolve from '@rollup/plugin-node-resolve';
112
+ import { pureGlyfPlugin } from 'pure-glyf/plugin';
113
+
114
+ export default {
115
+ // ...
116
+ plugins: [
117
+ resolve(), // Required to resolve 'pure-glyf' runtime
118
+ pureGlyfPlugin({
119
+ icons: {
120
+ // ... same configuration as Vite
121
+ myIcon: './src/assets/icons'
122
+ }
123
+ })
124
+ ]
125
+ };
126
+ ```
127
+
128
+ ### 3. Mount Styles
129
+
130
+ In your application's entry point (e.g., `main.tsx` or `index.ts`), call `mount()` to set up the style injection system.
131
+
132
+ ```typescript
133
+ // You can import 'mount' from the main package OR the virtual module
134
+ import { mount } from 'pure-glyf';
135
+ // import { mount } from 'pure-glyf/icons'; // Also works!
136
+
137
+ mount(); // Injects the base styles and prepares the style tag
138
+ ```
139
+
140
+ ### 4. Use Icons
141
+
142
+ Import icons from the virtual module `pure-glyf/icons`. The export name is `[Prefix][PascalCaseFilename]`.
143
+
144
+ ```tsx
145
+ import { customHome, customUser } from 'pure-glyf/icons';
146
+
147
+ function App() {
148
+ // 'customHome' is just a string: "pure-glyf-icon glyf-custom-home"
149
+
150
+ return (
151
+ <nav>
152
+ {/* Use it as a class name on any element (usually <span> or <i>) */}
153
+ <span className={customHome} />
154
+
155
+ <button>
156
+ <i className={customUser} /> Profile
157
+ </button>
158
+ </nav>
159
+ );
160
+ }
161
+ ```
162
+
163
+ ## Configuration
164
+
165
+ The `pureGlyfPlugin` accepts the following options:
166
+
167
+ ### `icons` (Required)
168
+ A record mapping prefixes to directory paths.
169
+ - **Key**: The prefix for the generated variable names (e.g., `tabler` -> `tablerHome`).
170
+ - **Value**: The relative path to the directory containing `.svg` files.
171
+
172
+ ### `dts` (Optional)
173
+ Path to generate the TypeScript declaration file.
174
+ - **Default**: `pure-glyf.d.ts` in the project root.
175
+ - **Recommendation**: Set this to a path included in your `tsconfig.json` (e.g., `src/pure-glyf-icons.d.ts`).
176
+
177
+ ## styling
178
+
179
+ Icons are rendered as CSS masks. They inherit the text color (`currentColor`) by default.
180
+
181
+ ### Default Styles
182
+ Every icon comes with the `.pure-glyf-icon` class:
183
+
184
+ ```css
185
+ .pure-glyf-icon {
186
+ display: inline-block;
187
+ width: 1em;
188
+ height: 1em;
189
+ background-color: currentColor; /* Matches text color */
190
+ mask-size: contain;
191
+ mask-repeat: no-repeat;
192
+ mask-position: center;
193
+ }
194
+ ```
195
+
196
+ ### Custom Sizing & Coloring
197
+ Since they are just elements with a background color, you style them with standard CSS:
198
+
199
+ ```css
200
+ .my-huge-icon {
201
+ font-size: 3rem; /* 3x normal text size */
202
+ color: #ff0000; /* Red icon */
203
+ }
204
+ ```
205
+
206
+ ## Server-Side Rendering (SSR)
207
+
208
+ `pure-glyf` supports SSR by allowing you to extract the CSS required for the rendered page.
209
+
210
+ ```typescript
211
+ import { sheet } from 'pure-glyf';
212
+ import { renderToString } from 'react-dom/server';
213
+
214
+ // 1. Render your app
215
+ const html = renderToString(<App />);
216
+
217
+ // 2. Extract the accumulated CSS
218
+ // 'sheet' contains the base styles + styles for all icons used during render
219
+ const css = sheet;
220
+
221
+ // 3. Inject into your HTML template
222
+ const fullHtml = `
223
+ <!DOCTYPE html>
224
+ <html>
225
+ <head>
226
+ <style>${css}</style>
227
+ </head>
228
+ <body>
229
+ <div id="root">${html}</div>
230
+ </body>
231
+ </ul>
232
+ `;
233
+ ```
234
+
235
+ ## Architecture & Performance
236
+
237
+ `pure-glyf` uses a hybrid strategy to deliver the best developer experience without compiling performance costs.
238
+
239
+ ### Development Mode: Parallel Parsing
240
+ In development, decoding thousands of Data URIs in JavaScript can be slow (blocking the main thread).
241
+ - **Mechanism**: The plugin moves all icon CSS into a separate virtual CSS module (`pure-glyf/icons.css`).
242
+ - **Benefit**: This offloads parsing to the browser's native CSS engine, which runs in parallel. The main JavaScript module remains tiny and instant to load.
243
+ - **Result**: Near-instant HMR and page reloads, even with huge icon sets like Material Design or Tabler.
244
+
245
+ ### Production Mode: Perfect Tree-Shaking
246
+ In production, we prioritize bundle size.
247
+ - **Mechanism**: Icons are compiled into side-effect-free IIFEs (Immediately Invoked Function Expressions) annotated with `/*#__PURE__*/`.
248
+ - **Logic**:
249
+ ```javascript
250
+ export const myIcon = /*#__PURE__*/ (() => {
251
+ injectCSS("..."); // Only runs if 'myIcon' is actually used
252
+ return "pure-glyf-icon glyf-my-icon";
253
+ })();
254
+ ```
255
+ - **Benefit**: If you don't import `myIcon`, your bundler (Vite/Rollup/Esbuild) completely removes the code *and* the associated CSS string.
256
+
257
+ ### The Virtual Module `pure-glyf/icons`
258
+ The plugin orchestrates everything by creating a virtual module `pure-glyf/icons`. This module re-exports the core runtime functions for convenience:
259
+ - `mount()`: Injects the styles.
260
+ - `sheet`: Access the accumulated CSS string.
261
+ - `onInject()`: Subscribe to new style injections.
262
+
263
+ ## License
264
+
265
+ MIT
@@ -0,0 +1,10 @@
1
+ export interface IconDef {
2
+ name: string;
3
+ css: string;
4
+ }
5
+ export interface GeneratorResult {
6
+ code: string;
7
+ css: string;
8
+ dts: string;
9
+ }
10
+ export declare function generateIconsCode(config: Record<string, string>, isDev?: boolean): GeneratorResult;
@@ -0,0 +1,2 @@
1
+ export declare const home_icon: string;
2
+ export declare const star_icon: string;
package/dist/index.cjs ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=new Set;exports.sheet=`
2
+ .pure-glyf-icon {
3
+ display: inline-block;
4
+ width: 1em;
5
+ height: 1em;
6
+ background-color: currentColor;
7
+ mask-repeat: no-repeat;
8
+ mask-position: center;
9
+ mask-size: contain;
10
+ -webkit-mask-repeat: no-repeat;
11
+ -webkit-mask-position: center;
12
+ -webkit-mask-size: contain;
13
+ }`;let t=null;function r(){typeof document>"u"||t||(t=document.createElement("style"),t.textContent=exports.sheet,document.head.appendChild(t))}const o=new Set;function c(e){o.add(e)}function a(e){n.has(e)||(n.add(e),exports.sheet+=e,t&&(t.textContent=exports.sheet),o.forEach(i=>i(e)))}exports.injectCSS=a;exports.mount=r;exports.onInject=c;
@@ -0,0 +1 @@
1
+ export { injectCSS, sheet, mount, onInject } from './inject';
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ const o = /* @__PURE__ */ new Set();
2
+ let n = `
3
+ .pure-glyf-icon {
4
+ display: inline-block;
5
+ width: 1em;
6
+ height: 1em;
7
+ background-color: currentColor;
8
+ mask-repeat: no-repeat;
9
+ mask-position: center;
10
+ mask-size: contain;
11
+ -webkit-mask-repeat: no-repeat;
12
+ -webkit-mask-position: center;
13
+ -webkit-mask-size: contain;
14
+ }`, t = null;
15
+ function a() {
16
+ typeof document > "u" || t || (t = document.createElement("style"), t.textContent = n, document.head.appendChild(t));
17
+ }
18
+ const i = /* @__PURE__ */ new Set();
19
+ function c(e) {
20
+ i.add(e);
21
+ }
22
+ function d(e) {
23
+ o.has(e) || (o.add(e), n += e, t && (t.textContent = n), i.forEach((r) => r(e)));
24
+ }
25
+ export {
26
+ d as injectCSS,
27
+ a as mount,
28
+ c as onInject,
29
+ n as sheet
30
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * CSS injection utility for pure-glyf icons.
3
+ *
4
+ * Uses a deduplication set to ensure each CSS rule is only injected once.
5
+ * Exports `sheet` for SSR usage.
6
+ * styles are NOT injected automatically. You must call `mount()` to inject them into the DOM.
7
+ */
8
+ /**
9
+ * Accumulated CSS string for Server-Side Rendering (SSR).
10
+ * Reset it if needed between requests in a server environment.
11
+ */
12
+ export declare let sheet: string;
13
+ /**
14
+ * Mounts the styles to the DOM.
15
+ * If the style tag already exists, it does nothing.
16
+ * If not, it creates it and populates it with the current accumulated CSS.
17
+ */
18
+ export declare function mount(): void;
19
+ export declare function onInject(callback: (css: string) => void): void;
20
+ export declare function injectCSS(css: string): void;
@@ -0,0 +1,6 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("node:fs"),p=require("node:path");function C(c){return c.replace(/[-_./\\]+(.)/g,(r,s)=>s.toUpperCase()).replace(/^./,r=>r.toUpperCase())}function I(c){return`data:image/svg+xml,${c.replace(/"/g,"'").replace(/%/g,"%25").replace(/#/g,"%23").replace(/{/g,"%7B").replace(/}/g,"%7D").replace(/</g,"%3C").replace(/>/g,"%3E").replace(/\s+/g," ")}`}function y(c,r){let s=[];return d.existsSync(c)&&d.readdirSync(c).forEach(i=>{const a=p.join(c,i),l=d.statSync(a);l&&l.isDirectory()?s=s.concat(y(a,r)):i.endsWith(".svg")&&s.push(p.relative(r,a))}),s}function P(c,r=!1){const s=[];for(const[n,e]of Object.entries(c)){const o=p.resolve(process.cwd(),e);if(!d.existsSync(o)){console.warn(`[pure-glyf] Warning: Icon directory not found: ${o}`);continue}y(o,o).forEach(g=>{const S=p.join(o,g),v=d.readFileSync(S,"utf-8"),m=g.replace(/\.svg$/,""),$=C(m),j=n+$,x=`glyf-${n.toLowerCase()}-${m.replace(/[^a-zA-Z0-9-]/g,"-")}`,h=I(v),w=`.${x}{mask-image:url("${h}");-webkit-mask-image:url("${h}");}`;s.push({name:j,css:w})})}const u=["import { injectCSS, mount, sheet, onInject } from 'pure-glyf';","export { mount, sheet, onInject };",""];let i="",a;r?(u.unshift("import 'pure-glyf/icons.css';"),i=s.map(n=>n.css).join(""),a=s.map(n=>{const e=n.css.match(/^\s*\.(\S+)\{/),o=e?e[1]:"error-class";return`export const ${n.name} = "pure-glyf-icon ${o}";`})):a=s.map(n=>{const e=n.css.match(/^\s*\.(\S+)\{/),o=e?e[1]:"error-class";return`export const ${n.name} = /*#__PURE__*/ (() => {
2
+ injectCSS(\`${n.css}\`);
3
+ return "pure-glyf-icon ${o}";
4
+ })();`});const l=u.concat(a).join(`
5
+ `),t=["declare module 'pure-glyf/icons' {"," export function mount(): void;"," export const sheet: string;"," export function onInject(callback: (css: string) => void): void;"];s.forEach(n=>{t.push(` export const ${n.name}: string;`)}),t.push("}");const f=t.join(`
6
+ `);return{code:l,css:i,dts:f}}function b(c){const r="pure-glyf/icons",s="\0"+r,u="pure-glyf/icons.css",i="\0"+u,a=c.dts||"pure-glyf.d.ts";let l=null,t=null,f=!1;function n(){try{if(l=P(c.icons,f),d.writeFileSync(p.resolve(process.cwd(),a),l.dts),t){const e=t.moduleGraph.getModuleById(s);e&&(t.moduleGraph.invalidateModule(e),t.ws.send({type:"full-reload",path:"*"}))}}catch(e){console.error("[pure-glyf] Generation failed:",e)}}return{name:"vite-plugin-pure-glyf",enforce:"pre",configResolved(e){f=e.command==="serve"},configureServer(e){t=e,Object.values(c.icons).forEach(o=>{t==null||t.watcher.add(p.resolve(o))}),t==null||t.watcher.on("change",o=>{o.endsWith(".svg")&&n()}),t==null||t.watcher.on("add",o=>{o.endsWith(".svg")&&n()}),t==null||t.watcher.on("unlink",o=>{o.endsWith(".svg")&&n()})},buildStart(){n()},resolveId(e){if(e===r)return s;if(e===u)return i},load(e){if(e===s)return l.code;if(e===i)return l.css}}}exports.pureGlyfPlugin=b;
@@ -0,0 +1,14 @@
1
+ import type { Plugin } from 'vite';
2
+ export interface PureGlyfConfig {
3
+ /**
4
+ * Map of Prefix -> Directory Path
5
+ * Example: { 'Tabler': './icons/tabler', 'MyIcon': './src/assets' }
6
+ */
7
+ icons: Record<string, string>;
8
+ /**
9
+ * Path to write the d.ts file to.
10
+ * Defaults to 'pure-glyf.d.ts' in the project root.
11
+ */
12
+ dts?: string;
13
+ }
14
+ export declare function pureGlyfPlugin(config: PureGlyfConfig): Plugin;
package/dist/plugin.js ADDED
@@ -0,0 +1,111 @@
1
+ import p from "node:fs";
2
+ import d from "node:path";
3
+ function C(c) {
4
+ return c.replace(/[-_./\\]+(.)/g, (r, n) => n.toUpperCase()).replace(/^./, (r) => r.toUpperCase());
5
+ }
6
+ function I(c) {
7
+ return `data:image/svg+xml,${c.replace(/"/g, "'").replace(/%/g, "%25").replace(/#/g, "%23").replace(/{/g, "%7B").replace(/}/g, "%7D").replace(/</g, "%3C").replace(/>/g, "%3E").replace(/\s+/g, " ")}`;
8
+ }
9
+ function y(c, r) {
10
+ let n = [];
11
+ return p.existsSync(c) && p.readdirSync(c).forEach((i) => {
12
+ const a = d.join(c, i), l = p.statSync(a);
13
+ l && l.isDirectory() ? n = n.concat(y(a, r)) : i.endsWith(".svg") && n.push(d.relative(r, a));
14
+ }), n;
15
+ }
16
+ function P(c, r = !1) {
17
+ const n = [];
18
+ for (const [s, e] of Object.entries(c)) {
19
+ const o = d.resolve(process.cwd(), e);
20
+ if (!p.existsSync(o)) {
21
+ console.warn(`[pure-glyf] Warning: Icon directory not found: ${o}`);
22
+ continue;
23
+ }
24
+ y(o, o).forEach((g) => {
25
+ const S = d.join(o, g), v = p.readFileSync(S, "utf-8"), m = g.replace(/\.svg$/, ""), $ = C(m), x = s + $, j = `glyf-${s.toLowerCase()}-${m.replace(/[^a-zA-Z0-9-]/g, "-")}`, h = I(v), w = `.${j}{mask-image:url("${h}");-webkit-mask-image:url("${h}");}`;
26
+ n.push({ name: x, css: w });
27
+ });
28
+ }
29
+ const u = [
30
+ "import { injectCSS, mount, sheet, onInject } from 'pure-glyf';",
31
+ "export { mount, sheet, onInject };",
32
+ ""
33
+ ];
34
+ let i = "", a;
35
+ r ? (u.unshift("import 'pure-glyf/icons.css';"), i = n.map((s) => s.css).join(""), a = n.map((s) => {
36
+ const e = s.css.match(/^\s*\.(\S+)\{/), o = e ? e[1] : "error-class";
37
+ return `export const ${s.name} = "pure-glyf-icon ${o}";`;
38
+ })) : a = n.map((s) => {
39
+ const e = s.css.match(/^\s*\.(\S+)\{/), o = e ? e[1] : "error-class";
40
+ return `export const ${s.name} = /*#__PURE__*/ (() => {
41
+ injectCSS(\`${s.css}\`);
42
+ return "pure-glyf-icon ${o}";
43
+ })();`;
44
+ });
45
+ const l = u.concat(a).join(`
46
+ `), t = [
47
+ "declare module 'pure-glyf/icons' {",
48
+ " export function mount(): void;",
49
+ " export const sheet: string;",
50
+ " export function onInject(callback: (css: string) => void): void;"
51
+ ];
52
+ n.forEach((s) => {
53
+ t.push(` export const ${s.name}: string;`);
54
+ }), t.push("}");
55
+ const f = t.join(`
56
+ `);
57
+ return { code: l, css: i, dts: f };
58
+ }
59
+ function _(c) {
60
+ const r = "pure-glyf/icons", n = "\0" + r, u = "pure-glyf/icons.css", i = "\0" + u, a = c.dts || "pure-glyf.d.ts";
61
+ let l = null, t = null, f = !1;
62
+ function s() {
63
+ try {
64
+ if (l = P(c.icons, f), p.writeFileSync(d.resolve(process.cwd(), a), l.dts), t) {
65
+ const e = t.moduleGraph.getModuleById(n);
66
+ e && (t.moduleGraph.invalidateModule(e), t.ws.send({
67
+ type: "full-reload",
68
+ path: "*"
69
+ }));
70
+ }
71
+ } catch (e) {
72
+ console.error("[pure-glyf] Generation failed:", e);
73
+ }
74
+ }
75
+ return {
76
+ name: "vite-plugin-pure-glyf",
77
+ enforce: "pre",
78
+ configResolved(e) {
79
+ f = e.command === "serve";
80
+ },
81
+ configureServer(e) {
82
+ t = e, Object.values(c.icons).forEach((o) => {
83
+ t == null || t.watcher.add(d.resolve(o));
84
+ }), t == null || t.watcher.on("change", (o) => {
85
+ o.endsWith(".svg") && s();
86
+ }), t == null || t.watcher.on("add", (o) => {
87
+ o.endsWith(".svg") && s();
88
+ }), t == null || t.watcher.on("unlink", (o) => {
89
+ o.endsWith(".svg") && s();
90
+ });
91
+ },
92
+ buildStart() {
93
+ s();
94
+ },
95
+ resolveId(e) {
96
+ if (e === r)
97
+ return n;
98
+ if (e === u)
99
+ return i;
100
+ },
101
+ load(e) {
102
+ if (e === n)
103
+ return l.code;
104
+ if (e === i)
105
+ return l.css;
106
+ }
107
+ };
108
+ }
109
+ export {
110
+ _ as pureGlyfPlugin
111
+ };
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "pure-glyf",
3
+ "version": "0.1.0",
4
+ "description": "Vite plugin and runtime for compiling SVGs into tree-shakeable CSS masks",
5
+ "type": "module",
6
+ "keywords": [
7
+ "icons",
8
+ "svg",
9
+ "css",
10
+ "tree-shaking",
11
+ "vite-plugin"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/eddow/pure-glyf.git"
16
+ },
17
+ "bugs": {
18
+ "url": "https://github.com/eddow/pure-glyf/issues"
19
+ },
20
+ "homepage": "https://github.com/eddow/pure-glyf#readme",
21
+ "author": "eddow <eddow@ownk.com>",
22
+ "sideEffects": false,
23
+ "main": "./dist/index.cjs",
24
+ "module": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js",
30
+ "require": "./dist/index.cjs"
31
+ },
32
+ "./plugin": {
33
+ "types": "./dist/plugin.d.ts",
34
+ "import": "./dist/plugin.js",
35
+ "require": "./dist/plugin.cjs"
36
+ },
37
+ "./inject": {
38
+ "types": "./dist/inject.d.ts",
39
+ "import": "./dist/inject.js",
40
+ "require": "./dist/inject.cjs"
41
+ }
42
+ },
43
+ "files": [
44
+ "dist"
45
+ ],
46
+ "scripts": {
47
+ "dev": "vite",
48
+ "build": "vite build && tsc --emitDeclarationOnly",
49
+ "build:watch": "vite build --watch",
50
+ "preview": "vite preview"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^25.0.9",
54
+ "tsx": "^4.21.0",
55
+ "typescript": "^5.7.0",
56
+ "vite": "^6.0.0",
57
+ "vite-plugin-dts": "^4.0.0"
58
+ },
59
+ "license": "MIT",
60
+ "packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808"
61
+ }