Bug Description
The default TypeScript migration template (templates/migration-template.ts) uses a value import for ColumnDefinitions, but ColumnDefinitions is only exported as a type from the package — it has no runtime representation in the compiled JavaScript bundle.
Template (current)
import { ColumnDefinitions, MigrationBuilder } from 'node-pg-migrate';
export const shorthands: ColumnDefinitions | undefined = undefined;
export async function up(pgm: MigrationBuilder): Promise<void> {}
export async function down(pgm: MigrationBuilder): Promise<void> {}
Error
When running migrations with tsx (or Node.js 22.6+ --experimental-strip-types), the generated migration file fails at runtime:
SyntaxError: The requested module 'node-pg-migrate' does not provide an export named 'ColumnDefinitions'
Root Cause
In dist/bundle/index.d.ts, ColumnDefinitions is exported with the type modifier:
export { ..., type ColumnDefinitions, ... }
In dist/bundle/index.js, ColumnDefinitions is not exported at all — it's a TypeScript interface with no runtime representation.
The library's own source code correctly uses import type { ColumnDefinitions } in src/migration.ts:
import type { ColumnDefinitions } from './operations/tables';
But the template uses a value import (import { ColumnDefinitions }), which is inconsistent.
Why this breaks
- With traditional
tsc compilation, TypeScript erases ColumnDefinitions from the import because it's only used as a type annotation → works
- With tsx, swc, or Node.js native type stripping, the import binding is checked against the module's actual exports at the ESM level before types are erased → fails
Suggested Fix
Change the template to use import type:
import type { ColumnDefinitions, MigrationBuilder } from 'node-pg-migrate';
export const shorthands: ColumnDefinitions | undefined = undefined;
export async function up(pgm: MigrationBuilder): Promise<void> {}
export async function down(pgm: MigrationBuilder): Promise<void> {}
Or split the imports:
import type { ColumnDefinitions } from 'node-pg-migrate';
import { MigrationBuilder } from 'node-pg-migrate';
Note: MigrationBuilder IS a runtime export (it's a class), so it can remain a value import.
Environment
- node-pg-migrate: 8.0.4 (latest)
- Node.js: 22.x
- tsx: installed as loader
- Package type:
"type": "module" (ESM)
Workaround
Use the template-file-name config option with a custom template that uses import type:
{
"template-file-name": "database/migrations/template.ts",
"ignore-pattern": "template\\.ts"
}
Bug Description
The default TypeScript migration template (
templates/migration-template.ts) uses a value import forColumnDefinitions, butColumnDefinitionsis only exported as a type from the package — it has no runtime representation in the compiled JavaScript bundle.Template (current)
Error
When running migrations with tsx (or Node.js 22.6+
--experimental-strip-types), the generated migration file fails at runtime:Root Cause
In
dist/bundle/index.d.ts,ColumnDefinitionsis exported with thetypemodifier:In
dist/bundle/index.js,ColumnDefinitionsis not exported at all — it's a TypeScript interface with no runtime representation.The library's own source code correctly uses
import type { ColumnDefinitions }insrc/migration.ts:But the template uses a value import (
import { ColumnDefinitions }), which is inconsistent.Why this breaks
tsccompilation, TypeScript erasesColumnDefinitionsfrom the import because it's only used as a type annotation → worksSuggested Fix
Change the template to use
import type:Or split the imports:
Note:
MigrationBuilderIS a runtime export (it's a class), so it can remain a value import.Environment
"type": "module"(ESM)Workaround
Use the
template-file-nameconfig option with a custom template that usesimport type:{ "template-file-name": "database/migrations/template.ts", "ignore-pattern": "template\\.ts" }