@julian I think it might be possible with some build tooling magic...
Importing plugins using CJS is as you mentioned the easy part - await import() works both ways with CJS, and in a pinch you can use createRequire to get require back in ESM.
This even works with ESM plugins by just changing src/plugins/index.js to use (await import(libraryPath)).default (and ideally adding some way to resolve main from package.json since currently that change needs library in plugin.json to be defined )
The other way though is the problem - calling require on ESM will fail. So the big issue are the require.main.require calls.
However, I imagine it should be possible to fix that in the build step - though it would require building the server-side code too (which TS will require anyway). I'm not sure how one would go about it with Webpack, but Rollup already has a plugin for converting CommonJS to ESM (since it outputs ESM). I'm not sure how it handles require.main.require, but it probably could be transformed to work correctly as just a relative require before that plugin runs (or the plugin could just be improved to handle that).
But ultimately if there are other breaking plugin changes on the roadmap maybe just pairing migration to ESM with them would be simpler. Since importing CJS from ESM mostly works fine, I imagine it would be similar in difficulty to the switch to require.main.require for most plugins.