How to use yjs in Node.js with TypeScript

Environment

node.js v16.16.0
TypeScript v4.7.4
yjs v13.5.41

Issue

yjs is imported fine in the React+TypeScript project but not so in the Node.js+TypeScript project

TypeScript compiler would give an error: Module 'yjs' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported synchronously. Use dynamic import instead.

Reproduce

My tsconfig.json:

{
  "ts-node": {
    "files": true
  },
  "compilerOptions": {
    "target": "ES2018",
    "module": "CommonJS",
    "moduleResolution": "NodeNext",
    "types": ["node", "mocha"],
    "lib": ["ESNext"],
    "importHelpers": true,
    "esModuleInterop": true,
    "sourceMap": true,
    "stripInternal": true,
    "skipLibCheck": true,
    "strict": true,
    "strictFunctionTypes": false,
    "noImplicitReturns": true,
    "noImplicitOverride": true,
    "noFallthroughCasesInSwitch": true,
    "useDefineForClassFields": true,
    "experimentalDecorators": true,

    "newLine": "LF",
    "composite": true,
    "rootDir": "./src",
    "outDir": "./dist"
  },
  "include": ["./src"],
  "exclude": ["./test"]
}

Hi @dizy ,

Since you specified "module": "CommonJS", you probably want to do const Y = require('yjs') instead.

I don’t advertise the use of commonjs anymore. If you still want to use commonjs, you can (Yjs provides a commonjs bundle), however, you need to adapt all code examples from import to require.

Thank you for replying. May I please ask instead of "module": "CommonJS", what kind of module would you recommend we generate for Node.js applications? I’ve tried changing it to both “ESNext” and “NodeNext”. Unfortunately neither worked.

Also, doing require in TypeScript will make const Y have any type, which isn’t quite ideal. :sob:
If only yjs has a typescript node.js example repo.

@dizy I recommend using a different template for tsconfig. There is something wrong with yours. This one works perfectly. I’ve also seen others that consume yjs without problems (e.g. jupyterlab/jupyterlab).

If you transpile your code before execution, then you should definitely use ESM and transpile to CJS if needed. Otherwise: if you start fresh give ESM a try. It’s sometimes harder to migrate existing projects.

Thank you again!

Removing the line "module": "CommonJS", in tsconfig.json resolves the problem, even though I don’t completely understand what removing it does.

:rofl:

1 Like