⚠️Vike will probably deprecate support for user-land CJS code soon. (Using CJS packages will still be supported for the foreseeable future.)
If you have a use case that requires the source code of your Vike app to be written in CJS then let us know and we'll consider not deprecating it. We would then create a new setting
disableCJSWarning
instead.
While you can use Vike with CJS, we recommend using ESM instead.
Most of your code should already be ESM, as code processed by Vite is always ESM. But some of your server code may not be processed by Vite and may be CJS.
If you get the following warning:
[vike][Warning] We recommend setting package.json#type to "module"
Then, in order to remove the warning, add this to your package.json
:
// package.json
{
// ...
type: "module"
}
This makes Node.js treat all .js files as ESM.
If you have .js files written in CJS then migrate them to ESM, for example:
// CJS code
const express = require('express')
const { renderPage } = require('vike/server')
// ESM code
import express from 'express'
import { renderPage } from 'vike/server'
An escape hatch is to use the
.cjs
and.mjs
file extensions: it enables you to choose between CJS and ESM on a file-by-file basis (regardless ofpackage.json#type
).
TypeScript migration
Depending on your setup, you may need to append .js
to the path of your imports:
// someTypeScriptFile.ts
import { something } from './some/module'
import { something } from './some/module.js'
You can use this script to automatically apply this change.
This is typically only needed for library code (e.g. your monorepo packages used by your application code). For the application code itself, you can use TypeScript's new
--moduleResolution bundler
option instead.
Monorepo migration
If you aren't using a monorepo, then migrating the source code of your Vike app from CJS to ESM is usually straightforward.
Even if you use a monorepo that uses a mix of ESM/CJS packages, the migration of your Vike app is still straightforward: usually there aren't any monorepo package that depends on your Vike app. (In other words, your Vike app is a root in your monorepo dependency graph.)
That said, migrating your whole monorepo isn't easy: the issue is that CJS modules cannot (easily) import ESM modules.
Node.js 22 added support for
require()
'ing ES modules behind a--experimental-require-module
flag, see Node.js Blog > Node.js 22 is now available! > Support require()ing synchronous ESM graphs.This means you can use Node.js 22 and ignore the following recommendation.
But because ESM modules can import CJS modules (unlike the opposite), a sensible strategy is to migrate your monorepo in a top-down fashion: first migrate CJS modules that aren't required by other CJS modules.
For example, you can usually starting migrating your Vike app and then later migrate its monorepo dependencies.
You can use a script to help determine what package in your monorepo is a candidate for CJS->ESM migration. For example:
- check-esm.js
Basically it uses some rush tools to figure out which packages are already using type module. It fails if there are any packages that aren't allowlisted that are not type module yet. It also prints an overview like this to show which packages are still used in CJS packages. Once a package is not used in CJS packages it's green and good to migrate.
Contributions welcome to share your script.