Skip to content

fix(deps): per-icon lucide-solid imports to shrink vite transform burst (#389) - #433

Open
omridevk wants to merge 1 commit into
mainfrom
fix/389-lucide-per-icon-imports
Open

fix(deps): per-icon lucide-solid imports to shrink vite transform burst (#389)#433
omridevk wants to merge 1 commit into
mainfrom
fix/389-lucide-per-icon-imports

Conversation

@omridevk

@omridevk omridevk commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Root cause (#389 strand)

The @conciv/app vitest-browser suite's cold-start import burst was 92% lucide-solid: barrel imports pulled all ~1700 icon modules through the vite transform on every cold run (solid packages are excluded from dep-prebundle, so the icons never hit the .vite cache). On starved x86 CI runners that 60-530s window is where Chromium's network service kills all page websockets at one instant, the vite client reloads the tester frame, and vitest browser mode cannot reconnect (upstream vitest-dev/vitest#10791) — the rotating-victim Browser connection was closed failure.

Profiled with DEBUG=vite:transform: 1969 of 2759 transformed modules were lucide-solid icons. With this change: 826 modules; local cold import 27.2s → 12.8s; Rosetta rig (x86, --cpus 1, cold .vite) import 190-290s → 46-69s, strand 0/6 vs 1/6 control (historical cold baseline ~35-50%/run).

Change

  • Per-icon default imports (lucide-solid/icons/<name>) across 54 files — lucide's own recommended pattern for vite dev perf.
  • no-restricted-imports guard in .oxlintrc.json so the barrel can't come back (type-only imports still allowed).
  • lucide-solid ships no "type" field and one ambient .d.ts shared across export conditions, so NodeNext types the per-icon default export as the module namespace (TS2604) — unfixed as of lucide-solid@1.31.0. Wildcard ambient overrides don't work (TS only consults them on resolution miss); each NodeNext package gets one generated lucide-solid-icons.d.ts with exact-specifier augmentation per icon (repo-wide union, identical content). apps/conciv needs none (bundler resolution). Deletable once upstream ships dual declarations.

Verification

  • typecheck 93/93, lint 98/98, build green; ui-kit-system/chat/chat-tools + app suites all green locally.
  • fallow audit --changed-since main: pass, zero INTRODUCED.
  • Rig A/B above; CI hammer on this PR is the decisive strand-rate check.

Closes #389

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor
    • Updated icon handling across the application and extensions for more consistent usage.
    • Preserved existing icon appearance, interactions, and overall application behavior.
    • Improved compatibility with the project’s type checking and code-quality tooling.
    • Added support for the available icon modules across shared interface components.

…st (#389)

Barrel imports from lucide-solid pulled all ~1700 icon modules through
the vite transform on every cold start (92% of @conciv/app's
vitest-browser cold-start import burst). Converted every value import
across the 54 files that used the barrel to per-icon default imports
resolved from lucide-solid's actual export map, and added a
no-restricted-imports guard so the barrel can't come back (type-only
imports still allowed).

lucide-solid ships no "type": "module" field and shares one ambient
.d.ts across its import/require/browser export conditions, so under
this repo's strict NodeNext module resolution the per-icon default
export types as the whole module namespace instead of the icon
component (TS2604). A wildcard ambient override
(`declare module 'lucide-solid/icons/*'`) does not fix this: TypeScript
only consults wildcard ambient modules when normal resolution fails,
and it succeeds here (just with the wrong shape). Exact-specifier
module augmentation does override the resolved type, so each affected
package gets one generated src/lucide-solid-icons.d.ts (or
src/cards/lucide-solid-icons.d.ts where the cards tsconfig scopes
separately) with one declare-module block per icon in the repo-wide
union, identical content everywhere. apps/conciv needs no shim: its
tsconfig uses moduleResolution: "bundler", which isn't affected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR restricts runtime imports from the lucide-solid package barrel, adds ambient declarations for individual icon modules, and migrates Lucide imports across the application and packages. Runtime icon usage remains unchanged.

Changes

Lucide direct import migration

Layer / File(s) Summary
Import restriction policy
.oxlintrc.json
Runtime imports from lucide-solid are restricted. Type-only imports remain permitted.
Icon module declarations
packages/*/src/**/lucide-solid-icons.d.ts
Package-local declarations expose supported lucide-solid/icons/* modules as typed default Solid components.
Runtime icon imports
apps/conciv/src/**/*.tsx, packages/**/src/**/*.tsx
Grouped Lucide imports now use individual icon module entry points. Component behavior remains unchanged.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR reduces Vite transform overhead but does not provide a root-cause analysis or directly address the Chromium teardown and browser disconnect failures in [#389]. Document how the import changes cause or prevent the failure in [#389], or link a separate issue that covers the Vite transformation performance work.
Out of Scope Changes check ⚠️ Warning The icon migration and generated declaration shims are not directly tied to the browser teardown and RPC failure described in [#389]. Keep this PR focused on the [#389] failure, or update the linked issue and objectives to include the Vite transformation performance scope.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: replacing barrel imports with per-icon lucide-solid imports to reduce Vite transformation time.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/389-lucide-per-icon-imports

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/ui-kit-system/src/lucide-solid-icons.d.ts (1)

1-475: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

11 byte-identical 475-line declaration files. Each file declares the same 66 lucide-solid/icons/* modules with the same body. The shared root cause is the generator: it emits the union of all icons into every package instead of emitting one shared declaration that packages reference. This adds about 5,200 duplicated lines and creates drift risk, because adding one icon requires regenerating 11 files.

Two additional consequences:

  1. Each package declares icons it does not import. For example, the tanstack extension uses one icon.
  2. declare module 'lucide-solid/icons/<name>' is a global augmentation. If two of these packages are ever compiled in one TypeScript program, the duplicate module declarations conflict.

Recommended direction: publish one declaration file from a single shared package, then reference it from each package tsconfig.json through types or an include path. Keep the generator, but have it write one file.

Note the path inconsistency as well: 9 files sit at <package>/src/, but two sit under src/cards/. Align them if the per-package files are kept.

  • packages/ui-kit-system/src/lucide-solid-icons.d.ts#L1-L475: keep this as the single source of truth, or move it to a dedicated types package, and export it for the other packages to reference.
  • packages/core/src/cards/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration; also move out of src/cards/ if the file is kept.
  • packages/extensions/recorder/src/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration.
  • packages/extensions/tanstack/src/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration.
  • packages/extensions/terminal/src/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration.
  • packages/extensions/test-runner/src/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration.
  • packages/extensions/try-it/src/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration.
  • packages/extensions/whiteboard/src/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration.
  • packages/tools/src/cards/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration; also move out of src/cards/ if the file is kept.
  • packages/ui-kit-chat-tools/src/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration.
  • packages/ui-kit-chat/src/lucide-solid-icons.d.ts#L1-L475: delete and reference the shared declaration.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui-kit-system/src/lucide-solid-icons.d.ts` around lines 1 - 475,
Replace the generator’s per-package output with one shared declaration
containing the 66 lucide-solid icon modules, keeping
packages/ui-kit-system/src/lucide-solid-icons.d.ts as the source of truth or
moving it to a dedicated types package. Configure every other package to
reference that declaration through its tsconfig types/include settings, and
delete the duplicated files in packages/core/src/cards/lucide-solid-icons.d.ts,
packages/extensions/recorder/src/lucide-solid-icons.d.ts,
packages/extensions/tanstack/src/lucide-solid-icons.d.ts,
packages/extensions/terminal/src/lucide-solid-icons.d.ts,
packages/extensions/test-runner/src/lucide-solid-icons.d.ts,
packages/extensions/try-it/src/lucide-solid-icons.d.ts,
packages/extensions/whiteboard/src/lucide-solid-icons.d.ts,
packages/tools/src/cards/lucide-solid-icons.d.ts,
packages/ui-kit-chat-tools/src/lucide-solid-icons.d.ts, and
packages/ui-kit-chat/src/lucide-solid-icons.d.ts; if retained, move the files
currently under src/cards/ to the common declaration location.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/ui-kit-system/src/lucide-solid-icons.d.ts`:
- Around line 1-475: Replace the generator’s per-package output with one shared
declaration containing the 66 lucide-solid icon modules, keeping
packages/ui-kit-system/src/lucide-solid-icons.d.ts as the source of truth or
moving it to a dedicated types package. Configure every other package to
reference that declaration through its tsconfig types/include settings, and
delete the duplicated files in packages/core/src/cards/lucide-solid-icons.d.ts,
packages/extensions/recorder/src/lucide-solid-icons.d.ts,
packages/extensions/tanstack/src/lucide-solid-icons.d.ts,
packages/extensions/terminal/src/lucide-solid-icons.d.ts,
packages/extensions/test-runner/src/lucide-solid-icons.d.ts,
packages/extensions/try-it/src/lucide-solid-icons.d.ts,
packages/extensions/whiteboard/src/lucide-solid-icons.d.ts,
packages/tools/src/cards/lucide-solid-icons.d.ts,
packages/ui-kit-chat-tools/src/lucide-solid-icons.d.ts, and
packages/ui-kit-chat/src/lucide-solid-icons.d.ts; if retained, move the files
currently under src/cards/ to the common declaration location.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 14fa6ae0-3cd3-474c-865d-2a70ef8f2304

📥 Commits

Reviewing files that changed from the base of the PR and between 7b59af1 and 9a70cbb.

📒 Files selected for processing (66)
  • .oxlintrc.json
  • apps/conciv/src/composer/actions.tsx
  • apps/conciv/src/composer/launch-menu.tsx
  • apps/conciv/src/composer/model-selector.tsx
  • apps/conciv/src/composer/session-selector.tsx
  • apps/conciv/src/pane/grab-reference.tsx
  • apps/conciv/src/pane/indicators.tsx
  • apps/conciv/src/pane/pane-composer.tsx
  • apps/conciv/src/pane/tool-fallback-card.tsx
  • apps/conciv/src/routes/panel.$sessionId.tsx
  • apps/conciv/src/routes/quick.tsx
  • apps/conciv/src/shell/notices.tsx
  • packages/core/src/cards/code-run-card.tsx
  • packages/core/src/cards/lucide-solid-icons.d.ts
  • packages/extensions/recorder/src/client.tsx
  • packages/extensions/recorder/src/lucide-solid-icons.d.ts
  • packages/extensions/recorder/src/tool/card.tsx
  • packages/extensions/tanstack/src/client/inspector-chip.tsx
  • packages/extensions/tanstack/src/lucide-solid-icons.d.ts
  • packages/extensions/terminal/src/client.tsx
  • packages/extensions/terminal/src/client/terminal-actions.tsx
  • packages/extensions/terminal/src/lucide-solid-icons.d.ts
  • packages/extensions/test-runner/src/lucide-solid-icons.d.ts
  • packages/extensions/test-runner/src/tool/card.tsx
  • packages/extensions/try-it/src/client/connect-pane.tsx
  • packages/extensions/try-it/src/lucide-solid-icons.d.ts
  • packages/extensions/whiteboard/src/client.tsx
  • packages/extensions/whiteboard/src/client/inbox.tsx
  • packages/extensions/whiteboard/src/lucide-solid-icons.d.ts
  • packages/extensions/whiteboard/src/tool/canvas/card.tsx
  • packages/extensions/whiteboard/src/tool/comment/card.tsx
  • packages/tools/src/cards/lucide-solid-icons.d.ts
  • packages/tools/src/cards/ui-card.tsx
  • packages/ui-kit-chat-tools/src/lucide-solid-icons.d.ts
  • packages/ui-kit-chat-tools/src/styled/tools/apply-patch-diff.tsx
  • packages/ui-kit-chat-tools/src/styled/tools/bash-card.tsx
  • packages/ui-kit-chat-tools/src/styled/tools/discovered-apis-card.tsx
  • packages/ui-kit-chat-tools/src/styled/tools/file-edit-card.tsx
  • packages/ui-kit-chat-tools/src/styled/tools/file-read-card.tsx
  • packages/ui-kit-chat-tools/src/styled/tools/search-card.tsx
  • packages/ui-kit-chat-tools/src/styled/tools/todo-card.tsx
  • packages/ui-kit-chat-tools/src/styled/tools/tool-lookup-card.tsx
  • packages/ui-kit-chat/src/lucide-solid-icons.d.ts
  • packages/ui-kit-chat/src/styled/action-bar.tsx
  • packages/ui-kit-chat/src/styled/activity.tsx
  • packages/ui-kit-chat/src/styled/attachment-dispatch.tsx
  • packages/ui-kit-chat/src/styled/attachment-ui.tsx
  • packages/ui-kit-chat/src/styled/branch-picker.tsx
  • packages/ui-kit-chat/src/styled/chain-of-thought.stories.tsx
  • packages/ui-kit-chat/src/styled/chain-of-thought.tsx
  • packages/ui-kit-chat/src/styled/composer.tsx
  • packages/ui-kit-chat/src/styled/model-selector.tsx
  • packages/ui-kit-chat/src/styled/now-line.tsx
  • packages/ui-kit-chat/src/styled/thread.tsx
  • packages/ui-kit-chat/src/tools/primitives/status-visual.tsx
  • packages/ui-kit-chat/src/tools/styled/collapsible-card.tsx
  • packages/ui-kit-chat/src/tools/styled/collapsible-section.tsx
  • packages/ui-kit-chat/src/tools/styled/json-tree.tsx
  • packages/ui-kit-chat/src/tools/styled/meta-tool-card.tsx
  • packages/ui-kit-chat/src/tools/styled/note-row.tsx
  • packages/ui-kit-chat/src/tools/styled/permission-card.tsx
  • packages/ui-kit-chat/src/tools/styled/tool-fallback.tsx
  • packages/ui-kit-chat/src/tools/styled/tool-group.tsx
  • packages/ui-kit-chat/src/tools/styled/tool-icon.tsx
  • packages/ui-kit-system/src/lucide-solid-icons.d.ts
  • packages/ui-kit-system/src/toast.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flaky: grab-reference.browser.test.tsx dies with 'Browser connection was closed' + extension teardown unhandled (CI shard-4)

1 participant