Skip to content

create-vite: suggestions on how to replace CJS dependencies #23526

Description

@Timbic

Description

Hello my vite friends! Recently, I created my own scaffolder inspired by create-vite, and while developing it I found a few things that could improve create-vite as well. Primarily, I'm talking about the dependencies @clack/prompts, mri, and cross-spawn. Each one of them either is a CJS package or brings a CJS package along - and since I am the biggest hater of CJS, I cannot stand this. Thankfully, most of these problems can be solved in just a few lines!!!

P.S. Turns out @vercel/detect-agent is also a CJS package... Sadly, I don't have a solution for this one (who ships CJS in 2026?!).

Suggested solution

  • @clack/prompts

@clack/prompts has a transitive dependency called sisteransi, which released v2.0.0 several months ago and ported the codebase to ESM with no API changes. Sadly, @clack/prompts still relies on the older version (1.0.5), which is still CJS. I've already opened an issue on their side asking to bump sisteransi to v2, but for now we can simply override the version in pnpm-workspace.yaml:

overrides:
  sisteransi: "2.0.0"

This change is also useful because unused code from sisteransi can now be tree-shaken away.

  • mri
    This one is the most hilarious! By default, when the target is set to node, tsdown first searches for the main: entry in package.json and only then the module: entry. mri ships two versions:
    • CJS version for the main: entry
    • ESM version for the module: entry

If we add this to tsdown.config.ts:

{
  inputOptions: {
        resolve: {
             mainFields: ["module", "main"],
         },
  },
}

we flip the order so tsdown picks the correct (ESM) version of mri.

  • cross-spawn
    This one is harder.
    cross-spawn is a very popular package, yet it hasn't received a single commit in the past 2 years - not great. I couldn't find any drop-in replacements... so I decided to build one myself! cross-spawn-esm is a modern ESM + TypeScript port with several advantages over the original: it's ~50% smaller, has zero dependencies, ships types out of the box, and, of course, it's tree-shakable. The migration is very simple - check my Migration guide for more details.

In essence:

Before:

import spawn from 'cross-spawn'

// line 402
const { status, error } = spawn.sync(command, args, options)
// line 624
const { status } = spawn.sync(command, replacedArgs, {
  stdio: 'inherit',
})

After:

import { spawnSync } from 'cross-spawn-esm'

// line 402
const { status, error } = spawnSync(command, args, options)
// line 624
const { status } = spawnSync(command, replacedArgs, {
  stdio: 'inherit',
})

I guess this is the riskiest option since the package is very new and doesn't have many downloads, but you can take a look and decide whether you want to give it a shot. After all, since you're bundling your dependencies, there's no risk even if it turns out I'm a villain about to publish a virus in the next version lmao :)

  • Results:

After these changes, what do we get?

  • Fewer transitive dependencies to worry about
  • 4 kB reduction in the bundle
  • Almost a fully ESM package (I should talk to the folks at Vercel about @vercel/detect-agent...)
  • Since I'm the maintainer of cross-spawn-esm, you can always reach out to me if you hit any bugs or vulnerabilities - I'll patch them

It's not a lot, but it's honest work. If you decide against the @clack/prompts and cross-spawn changes, at least do the mri one so I can sleep well. After all, God's kingdom will arrive when no CJS is left in the wild ❤️

P.S. If needed, I can also open the PRs for these changes. Peace 🕊️

Alternative

No response

Additional context

No response

Validations

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions