Why doesn't 'fs' work when imported as an ES6 module?

You must use import fs from 'fs', not import * as fs from 'fs'.

This is because (at least from the point of view of mjs files) the 'fs' module exports only one thing, which is called default. So if you write import * as fs from 'fs', fs.default.readFile exists but fs.readFile does not. Perhaps the same is true of all Node.js (CommonJS) modules.

Confusingly, in TypeScript modules (with @types/node and ES5 output), import fs from 'fs' produces error

error TS1192: Module '"fs"' has no default export

so in TypeScript you must write import * as fs from 'fs'; by default. It appears this can be changed to match the way mjs files work using the new "esModuleInterop": true option in tsconfig.json.