Skip to content

typescript@7 breaks config loading: expressive-code-twoslash is imported eagerly even when twoSlash is disabled #155

Description

@daveycodez

Summary

With typescript@7 installed in the workspace, loading any SolidBase config crashes before Vite even starts — including for projects that never enable twoslash.

failed to load config from .../apps/docs/vite.config.ts
error during build:
TypeError: Cannot read properties of undefined (reading 'ES2022')
    at node_modules/expressive-code-twoslash/dist/index.js:1628:27

Root cause

dist/config/mdx.js imports the twoslash plugin at module top level:

import ecTwoSlash from "expressive-code-twoslash";

but only uses it inside the if (sbConfig.markdown?.expressiveCode?.twoSlash) branch. expressive-code-twoslash evaluates the TypeScript compiler API at module scope (ts.ScriptTarget.ES2022), and it declares typescript as a peer dependency (^5.7), so it resolves whatever TypeScript the host project provides. TypeScript 7 (the native/Go compiler) no longer ships the in-process compiler JS API — the npm package's main export is essentially a version stub — so the import itself throws.

SolidBase's own import { convertCompilerOptionsFromJson } from "typescript" is unaffected because typescript ^5.9.3 is a real dependency of SolidBase and resolves its own copy; it's also only used inside the same twoslash branch.

Suggested fix

Load the plugin lazily, only when the feature is enabled, e.g.:

if (sbConfig.markdown?.expressiveCode?.twoSlash) {
  const { default: ecTwoSlash } = await import("expressive-code-twoslash");
  ...
}

(and move the convertCompilerOptionsFromJson import in with it). Twoslash itself can't support TS 7 until an in-process API exists for the native compiler (twoslash@0.3.x caps its peer range at ^6), so gating the import is the only way for TS 7 projects to use SolidBase — with twoslash off — today.

Environment

  • @kobalte/solidbase 0.6.9
  • typescript 7.0.2
  • @solidjs/start 2.0.0-beta.0, vite 8.1.5
  • bun 1.3.2 (reproduces under both hoisted and isolated linkers whenever expressive-code-twoslash's peer resolution lands on typescript@7)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions