···82828383 // Legacy detection without exports field
8484 if (hasModule && hasMain) {
8585- // Has both module (ESM) and main (CJS) fields
8686- return 'dual'
8585+ // Check for dual packages (has module field and main points to cjs)
8686+ const mainIsCJS = pkg.main?.endsWith('.cjs') || (pkg.main?.endsWith('.js') && !isTypeModule)
8787+8888+ return mainIsCJS ? 'dual' : 'esm'
8789 }
88908991 if (hasModule || isTypeModule) {
+10
test/unit/shared/utils/package-analysis.spec.ts
···2626 expect(detectModuleFormat({ module: 'index.mjs', main: 'index.js' })).toBe('dual')
2727 })
28282929+ it('detects dual from type + module + main fields', () => {
3030+ expect(detectModuleFormat({ type: 'module', module: 'index.js', main: 'index.cjs' })).toBe(
3131+ 'dual',
3232+ )
3333+ })
3434+3535+ it('detects esm from type + module + main fields', () => {
3636+ expect(detectModuleFormat({ type: 'module', module: 'index.js', main: 'index.js' })).toBe('esm')
3737+ })
3838+2939 it('detects ESM from module field without main', () => {
3040 expect(detectModuleFormat({ module: 'index.mjs' })).toBe('esm')
3141 })