npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mikro-orm-pg-migration-generator

v0.1.6

Published

A MikroORM migration generator extension for automatically managing PostgreSQL `updated_at` column triggers and functions.

Readme

Mikro ORM PostgreSQL Migration Generator

A MikroORM migration generator extension for automatically managing PostgreSQL updated_at column triggers and functions.

Why?

Unlike MySQL, PostgreSQL does not natively support the convenient ON UPDATE CURRENT_TIMESTAMP feature for automatically updating timestamp columns. Instead, the typical approach is to use database functions and triggers to achieve this behavior.

While MikroORM provides the onUpdate: () => new Date() option for automatically updating columns, this only works within ORM-managed code. For cases where you use query builders or raw SQL, it’s easy to miss handling the updated_at logic, leading to verbose and error-prone code.

This generator automatically creates the necessary migrations for PostgreSQL functions and triggers to keep your updated_at columns reliably updated, even outside the ORM.

Features

  • Automatic migrations for updated_at columns: Generates PostgreSQL migration scripts for triggers and functions that update your timestamp columns.
  • Custom column names: Support for columns other than updated_at.
  • Custom types: Works with types other than timestamptz.
  • Custom function and trigger names: Easily configure naming conventions.
  • Up/Down migration scripts: Automatically create and drop functions/triggers as part of migration.
  • Supports PostgreSQL versions 13 through 17.

Installation

# npm
npm install mikro-orm-pg-migration-generator @mikro-orm/migrations

# pnpm
pnpm add mikro-orm-pg-migration-generator @mikro-orm/migrations

Usage

Configure MikroORM to use the migration generator in your project:

import { defineConfig } from "@mikro-orm/postgresql";
import { createMigrationGeneratorClass } from "mikro-orm-pg-migration-generator";

export default defineConfig({
  // With default options
  migrations: { generator: createMigrationGeneratorClass() },

  // Or with customization
  migrations: {
    generator: createMigrationGeneratorClass({
      version: 17, // PostgreSQL parser version
      updatedAt: {
        // Custom column name matcher
        columnNameMatcher: ({ value }) => value.toLowerCase() === "update_date",
        // Custom column type matcher
        columnTypeMatcher: ({ value }) => value.toLowerCase() === "timestamp",
        // Custom function name
        functionNameFactory: (context) => "...",
        // Custom function up SQL
        functionUpSqlFactory: (context) => "...",
        // Custom function down SQL
        functionDownSqlFactory: (context) => "...",
        // Custom trigger name
        triggerNameFactory: (context) => "...",
        // Custom trigger up SQL
        triggerUpSqlFactory: (context) => "...",
        // Custom trigger down SQL
        triggerDownSqlFactory: (context) => "...",
      },
    }),
  },
});

Example: Generated Migration File

When calling mikro-orm migration:create for a users table with an updated_at column, the generated migration might look like:

// Migration20250928232237.ts
import { Migration } from "@mikro-orm/migrations";
export class Migration20250928232237 extends Migration {
  override async up(): Promise<void> {
    this.addSql(
      `create table "users" ( /* ... */ "updated_at" timestamptz not null default current_timestamp, /* ... */ );`
    );
    this
      .addSql(`create or replace function "fn_update_timestamp_users_updated_at"()
returns trigger as $$
begin
  new."updated_at" := current_timestamp;
  return new;
end;
$$ language plpgsql;`);
    this.addSql(`create trigger "tr_update_timestamp_users_updated_at"
before update on "users"
for each row
execute function "fn_update_timestamp_users_updated_at"();`);
  }

  override async down(): Promise<void> {
    this.addSql(
      `drop trigger if exists "tr_update_timestamp_users_updated_at" ON "users";`
    );
    this.addSql(
      `drop function if exists "fn_update_timestamp_users_updated_at"();`
    );
    this.addSql(`drop table if exists "users" cascade;`);
  }
}

Description

When you create a migration using mikro-orm migration:create for a table such as users with an updated_at column, the generator automatically creates the necessary function, and trigger for handling timestamp updates.

The up migration creates the trigger function, and trigger to update the timestamp column whenever a row is updated.

The down migration safely removes the trigger, and function, ensuring clean rollback.

This concise example shows how the generator integrates with MikroORM migrations for robust and automatic timestamp logic in your PostgreSQL schema.

How to Extend the Migration Generator

To add custom functionality—such as automatically formatting SQL with sql-formatter—extend the generator as follows:

# npm
npm install -D sql-formatter

# pnpm
pnpm add -D sql-formatter
import { createMigrationGeneratorClass } from "mikro-orm-pg-migration-generator";
import { format } from "sql-formatter";

const BaseMigrationGenerator = createMigrationGeneratorClass();

class CustomMigrationGenerator extends BaseMigrationGenerator {
  override createStatement(sql: string, padLeft: number): string {
    sql = format(sql, { language: "postgresql" });
    sql = `\n${sql}\n`;
    return super.createStatement(sql, padLeft);
  }
}

This example demonstrates how to wrap the migration generator and override methods—such as createStatement—to incorporate additional logic (e.g., SQL formatting). You can customize other behaviors the same way, making the generator flexible and easy to extend for advanced migration requirements.

License

MIT