Skip to content

Subpath imports from @hugeicons/core-free-icons missing .d.ts files — intended behavior? #3

@aleix10kst

Description

@aleix10kst

Context

We're using @hugeicons/core-free-icons in a TanStack Start (Vite + Nitro SSR) monorepo. We prefer deep/subpath imports for icons to ensure reliable tree-shaking in SSR bundles, where barrel tree-shaking can be unreliable.

We noticed TypeScript errors when running tsc with subpath imports like:

import AbacusIcon from "@hugeicons/core-free-icons/AbacusIcon";
// TS error: Cannot find module '@hugeicons/core-free-icons/AbacusIcon' or its corresponding type declarations

The JS resolves fine at runtime — only the types are missing.

What We Found

The package.json exports field declares a types mapping for subpath imports:

"./*": {
  "types": "./dist/types/*.d.ts",
  "import": "./dist/esm/*.js"
}

But dist/types/ only contains the barrel declaration and loader files:

index.d.ts        (single file with all icon type declarations)
loader.native.d.ts
loader.node.d.ts
loader.web.d.ts

There are no individual per-icon .d.ts files (e.g., dist/types/AbacusIcon.d.ts doesn't exist), even though individual JS files exist in dist/esm/.

The typesVersions fallback ("*": ["./dist/types/*"]) doesn't help when using moduleResolution: "bundler" (or "node16"/"nodenext"), since the exports field takes precedence.

Verified on v3.1.1, v3.3.0, and v4.0.0.

Question

Is this a packaging oversight, or are subpath imports not an intended use case? The exports["./*"] mapping with a types condition suggests they should work, but the type files aren't generated to match.

Our Workaround

We added an ambient module declaration to unblock ourselves:

declare module "@hugeicons/core-free-icons/*" {
  type IconSvgObject =
    | [string, { [key: string]: string | number }][]
    | readonly (readonly [string, { readonly [key: string]: string | number }])[];

  const icon: IconSvgObject;
  export default icon;
}

This works fine — just wanted to flag it in case the exports types mapping was meant to be functional. Thanks for the great icon library!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions