Skip to content

chore: migrate from TSDX to Vite, Vitest, and Biome - #4

Merged
hideokamoto merged 5 commits into
mainfrom
claude/migrate-tsdx-to-vite-013TiSjMSjKiXaSa2eYQ4Tu6
Nov 16, 2025
Merged

chore: migrate from TSDX to Vite, Vitest, and Biome#4
hideokamoto merged 5 commits into
mainfrom
claude/migrate-tsdx-to-vite-013TiSjMSjKiXaSa2eYQ4Tu6

Conversation

@hideokamoto

@hideokamoto hideokamoto commented Nov 16, 2025

Copy link
Copy Markdown
Owner
  • Replace TSDX with Vite for faster builds and modern tooling
  • Use Vitest for testing with improved performance
  • Adopt Biome for unified linting and formatting
  • Update package.json to use new build scripts and dependencies
  • Configure TypeScript for Vite with bundler mode
  • Fix type safety issues by replacing 'any' with proper types
  • Update exports in package.json for better module resolution

Summary by CodeRabbit

  • Chores
    • Migrated build tooling to Vite for improved build performance
    • Implemented Biome for unified code formatting and linting
    • Added ESM and CommonJS module export support for better compatibility
    • Upgraded test framework to Vitest with modern testing capabilities
    • Enhanced TypeScript configuration for stricter type safety

- Replace TSDX with Vite for faster builds and modern tooling
- Use Vitest for testing with improved performance
- Adopt Biome for unified linting and formatting
- Update package.json to use new build scripts and dependencies
- Configure TypeScript for Vite with bundler mode
- Fix type safety issues by replacing 'any' with proper types
- Update exports in package.json for better module resolution
@coderabbitai

coderabbitai Bot commented Nov 16, 2025

Copy link
Copy Markdown

Warning

Rate limit exceeded

@hideokamoto has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 0 minutes and 39 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between e6b6763 and d65f660.

📒 Files selected for processing (6)
  • .github/workflows/main.yml (2 hunks)
  • .github/workflows/size.yml (0 hunks)
  • biome.json (1 hunks)
  • package.json (2 hunks)
  • src/index.tsx (3 hunks)
  • vite.config.ts (1 hunks)

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

The changes represent a comprehensive tooling and build system modernization, migrating from tsdx to vite for building, replacing prettier/husky with biome for linting and formatting, adopting vitest for testing, and updating TypeScript configuration to modern standards with improved type safety in source code.

Changes

Cohort / File(s) Summary
Build & Development Tooling Configuration
vite.config.ts, vitest.config.ts, tsconfig.json, biome.json
New Vite configuration for library builds with ESM/CJS exports and React plugin support; new Vitest configuration with jsdom environment and global test APIs; TypeScript config modernized to ES2020 with bundler module resolution and enhanced linting constraints; new Biome configuration for integrated code formatting, linting, and import organization
Package Dependencies & Scripts
package.json
Build system migrated from tsdx to vite/biome/vitest; removed husky, prettier, and size-limit tooling; replaced with modern equivalents (@biomejs/biome, vite, vitest, vite-plugin-dts); updated module exports to include explicit dual-package support (main as .cjs, module as .mjs, types); scripts reorganized to use new tools (dev, build, test:watch, lint:fix, format)
Type Safety & JSX Runtime
src/index.tsx, test/blah.test.tsx
Type-only React imports leveraging JSX runtime; introduced WindowWithAdsbygoogle interface for typed window.adsbygoogle access; replaced unsafe any casting with typed workflow in source; removed explicit React import from test file

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

  • package.json: Verify all script mappings work correctly (dev, build, test, lint, format); cross-check dependency version compatibility between vite, vitest, biome, and TypeScript tooling
  • Dual-package exports: Validate that .cjs, .mjs, and .d.ts entry points are correctly configured and align with actual build output from vite.config.ts
  • TypeScript config: Ensure modern ES2020 target, bundler module resolution, and new flags (isolatedModules, noEmit, allowImportingTsExtensions) don't conflict with vite/vitest setups
  • Build/test configs: Verify vite and vitest configurations work in tandem and properly handle React/JSX transformation

Poem

🐰 From tsdx's old tools, a modern path unfolds,
Vite speeds the build, while Biome makes bold,
Types now secured where any once reigned,
JSX runtime blooms, new exports ordained,
Testing with vitest—our toolchain's refined! ✨

Pre-merge checks and finishing touches

✅ 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 accurately captures the main objective of the PR: migrating from TSDX to modern tooling (Vite, Vitest, and Biome). It directly aligns with the substantial changes across configuration files and build tooling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @hideokamoto, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request undertakes a significant modernization effort by migrating the project's core tooling from TSDX to a more contemporary stack comprising Vite for builds, Vitest for testing, and Biome for unified linting and formatting. This transition aims to boost development efficiency, improve build and test performance, and establish a consistent code style, ultimately leading to a more robust and maintainable codebase.

Highlights

  • Build System Migration: Replaced TSDX with Vite for improved build performance and modern tooling.
  • Testing Framework Update: Switched from TSDX's testing setup to Vitest, enhancing test execution speed and developer experience.
  • Unified Code Tooling: Integrated Biome for consistent linting and formatting across the codebase, replacing previous tools like Prettier and TSDX's linter.
  • Dependency and Script Overhaul: Updated package.json to reflect new build, test, lint, and format scripts, along with adding and removing relevant development dependencies.
  • TypeScript Configuration Refinement: Adjusted tsconfig.json for compatibility with Vite's bundler mode and updated type safety practices.
  • Module Resolution Enhancement: Modified package.json to include 'exports' field for better module resolution and compatibility.
  • Type Safety Improvements: Addressed type safety issues in src/index.tsx by replacing 'any' with explicit type definitions for the window.adsbygoogle object.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request successfully migrates the project from TSDX to a more modern stack with Vite, Vitest, and Biome. The configuration files for the new tools are well-structured, and the changes in package.json reflect the migration. I've also noticed the improvements in type safety by removing any casts.

My review includes a few important points:

  • Critical: Several dependencies in package.json are pinned to versions that don't exist, which will break the build.
  • High: The Biome configuration points to a non-existent schema URL.
  • Medium: I've suggested a couple of minor refactorings in src/index.tsx and vite.config.ts for simplification and clarity.

Overall, this is a great step forward for the project's tooling. Addressing the dependency versions is the most critical part.

Comment thread package.json
Comment on lines 60 to 76
"devDependencies": {
"@size-limit/preset-small-lib": "^5.0.3",
"@biomejs/biome": "^2.3.5",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"husky": "^7.0.2",
"@vitejs/plugin-react": "^5.1.1",
"@vitest/ui": "^4.0.9",
"jsdom": "^27.2.0",
"next": "^16.0.0",
"np": "^10.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"size-limit": "^5.0.3",
"tsdx": "^0.14.1",
"tslib": "^2.3.1",
"typescript": "^5.7.0"
"typescript": "^5.7.0",
"vite": "^7.2.2",
"vite-plugin-dts": "^4.5.4",
"vitest": "^4.0.9"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

Several dependencies are listed with versions that do not exist on the public npm registry (e.g., @biomejs/biome@^2.3.5, vite@^7.2.2, vitest@^4.0.9, next@^16.0.0). This will cause the dependency installation to fail. Please correct these versions to existing, published versions.

Comment thread biome.json
@@ -0,0 +1,41 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.5/schema.json",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The schema version 2.3.5 does not appear to be a valid published version for Biome, which can cause issues with schema validation in your IDE. This seems to correspond to the version in package.json, which is also not a valid version for @biomejs/biome. Please use a valid version for both the package and the schema URL. For example, the latest stable version is 1.8.3.

Comment thread src/index.tsx Outdated
Comment on lines +63 to +65
const adsbygoogle = window.adsbygoogle || [];
window.adsbygoogle = adsbygoogle;
adsbygoogle.push({});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This logic is correct, but it can be simplified. Now that window.adsbygoogle is properly typed, you can use a more concise one-liner which is both readable and type-safe.

Suggested change
const adsbygoogle = window.adsbygoogle || [];
window.adsbygoogle = adsbygoogle;
adsbygoogle.push({});
(window.adsbygoogle = window.adsbygoogle || []).push({});

Comment thread vite.config.ts
Comment on lines +13 to +30
build: {
lib: {
entry: resolve(__dirname, 'src/index.tsx'),
name: 'NextGoogleAds',
formats: ['es', 'cjs'],
fileName: format => `index.${format === 'es' ? 'mjs' : 'cjs'}`,
},
rollupOptions: {
external: ['react', 'react-dom', 'next/script'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
},
sourcemap: true,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The lib.name and rollupOptions.output.globals options are only used for UMD and IIFE formats. Since you are only building ES and CJS modules, these options have no effect and can be removed to simplify the configuration.

  build: {
    lib: {
      entry: resolve(__dirname, 'src/index.tsx'),
      formats: ['es', 'cjs'],
      fileName: format => `index.${format === 'es' ? 'mjs' : 'cjs'}`,
    },
    rollupOptions: {
      external: ['react', 'react-dom', 'next/script'],
    },
    sourcemap: true,
  },

@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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
package.json (1)

18-19: Critical: Update Node.js engine constraint to match dependency requirements.

The pipeline warning indicates that dependencies require Node.js >=20 or >=22, but the engines field specifies >=10. This mismatch will cause installation and CI failures.

Apply this diff to update the Node.js requirement:

   "engines": {
-    "node": ">=10"
+    "node": ">=20"
   },

Additionally, verify your CI workflows use Node.js 20 or later.

src/index.tsx (1)

1-83: Address the mixed exports warning from the build pipeline.

The pipeline warning indicates that mixing named and default exports may cause consumer confusion, requiring NextGoogleAds.default to access the default export in some environments.

Consider adding this to vite.config.ts to explicitly configure export behavior:

// In vite.config.ts build.lib section
build: {
  lib: {
    // ... existing config
  },
  rollupOptions: {
    // ... existing config
    output: {
      exports: 'named', // or 'auto' to suppress the warning
      // ... existing globals
    },
  },
}

Alternatively, if the default export is essential, document this requirement for CommonJS consumers.

🧹 Nitpick comments (1)
vitest.config.ts (1)

1-11: LGTM! Consider removing empty setupFiles array.

The Vitest configuration is correct and properly integrates React support with jsdom environment.

If no setup files are needed, consider removing the empty array for cleaner configuration:

   test: {
     globals: true,
     environment: 'jsdom',
-    setupFiles: [],
   },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 712e61b and e6b6763.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • biome.json (1 hunks)
  • package.json (3 hunks)
  • src/index.tsx (3 hunks)
  • test/blah.test.tsx (0 hunks)
  • tsconfig.json (1 hunks)
  • vite.config.ts (1 hunks)
  • vitest.config.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • test/blah.test.tsx
🧰 Additional context used
🪛 GitHub Actions: CI
vite.config.ts

[error] 37-37: ESModule error: require() of ES Module /home/runner/work/next-google-ads/next-google-ads/node_modules/@vitejs/plugin-react/dist/index.js from vite.config.ts is not supported. Use a dynamic import() instead.

package.json

[warning] 1-1: EBADENGINE Unsupported engine: some dependencies require Node.js >=20 or >=22. Current: Node 18.x. Consider upgrading Node.js to satisfy engine constraints.

src/index.tsx

[warning] 1-1: Entry module "src/index.tsx" is using named and default exports together. Consumers of your bundle will have to use NextGoogleAds.default to access the default export, which may not be what you want. Use output.exports: "named" to disable this warning.

🔇 Additional comments (7)
biome.json (1)

1-41: LGTM! Well-configured Biome setup.

The Biome configuration is well-structured with sensible defaults for formatting, linting, and import organization. The VCS integration and file inclusion patterns align well with the project structure.

tsconfig.json (1)

4-30: LGTM! Modern TypeScript configuration for Vite.

The updated configuration appropriately targets ES2020 with bundler module resolution and includes all necessary options for a Vite-based library build. The noEmit: true is correct here since Vite handles the actual build and vite-plugin-dts generates declarations.

package.json (2)

4-13: LGTM! Proper dual package configuration.

The exports, module, types, and main fields are correctly configured for dual ESM/CJS support with proper TypeScript declarations.


22-31: LGTM! Well-structured build and test scripts.

The migration from TSDX to Vite/Vitest/Biome scripts is complete and well-organized, providing good developer experience with watch modes and UI options.

src/index.tsx (2)

2-8: LGTM! Excellent type safety improvement.

The migration to type-only React imports and the introduction of WindowWithAdsbygoogle interface significantly improve type safety compared to the previous approach.


63-65: LGTM! Much safer than casting to any.

The typed approach to accessing window.adsbygoogle is a significant improvement over the previous (window as any) pattern.

vite.config.ts (1)

6-31: LGTM! Well-configured Vite library build.

Once the ESModule import issue is resolved, this configuration properly sets up:

  • Dual ESM/CJS output formats
  • TypeScript declaration generation
  • Correct externalization of peer dependencies
  • Source maps for debugging

Comment thread vite.config.ts
- Add "type": "module" to package.json for ESM support
- Update Node.js requirement to >=20.19.0 for Vite compatibility
- Use fileURLToPath for __dirname in ESM context
- Remove UMD/IIFE-specific options from Vite config
- Simplify adsbygoogle initialization code
- Disable noAssignInExpressions rule for cleaner code
- Remove Node.js 18.x from test matrix (requires >=20.19.0)
- Remove --ci flag from vitest command (automatically detected)
- Remove size-limit workflow (TSDX dependency removed)
- Remove cross-platform matrix (Windows, macOS)
- Use only Ubuntu with Node 20.x
- YAGNI: library has no platform-specific code
- Add Node.js version matrix (20.x LTS, 22.x latest)
- Keep OS to Linux only for simplicity
@hideokamoto
hideokamoto merged commit c24c6f8 into main Nov 16, 2025
3 checks passed
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.

2 participants