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

sqlmorpheus

v0.2.7

Published

SQLMorpheus is a standalone SQL migration tool that automatically calculates the differences between a database and a defined state and updates the database structure accordingly. It is not bundled with any ORM or limited to a specific SQL dialect or SQL

Readme

SqlMorpheus

SQLMorpheus is a standalone SQL migration tool that automatically calculates the differences between a database and a defined state and updates the database structure accordingly. It is not bundled with any ORM or limited to a specific SQL dialect or SQL library, making it very flexible and easy to integrate into any (new or preexisting) project.

Its stand-out features are:

  • Database changes are calculated at runtime, allowing SqlMorpheus to be used with different database states without expecting any existing structure or having to recompile your app.
  • SQLMorpheus does not bundle its own SQL library but allows you to define database access yourself using any library you want. This not only prevents unnecessary overhead, it also makes SQLMorpheus very flexible and easy to migrate between database flavours.
  • While SQLMorpheus can work without (almost) any manual input, it optionally allows for destructive changes to be confirmed to prevent possible data loss.
  • It keeps a history of changes (and adds an interface for backups before migrations) and allows viewing all changes made and even roll back to a specific version.

How to install?

To install SqlMorpheus, run

npm install sqlmorpheus

How to use?

Because SqlMorpheus relies on the framework you choose for database access, it needs a little bit more setup code. But you only need to copy & paste a few simple lines of code:

1. Access the database

For SqlMorpheus to be able to access your database, you need to provide its runMigration call (see bellow) with a dbAccess object with three callback functions: runReadStatement(), runWriteStatement() and runTransaction(). Here is a full example for SQLite using better-sqlite3 For other SQL types you can copy one of the provided examples (see MySQL, Postgres, SQLite)

import {DatabaseAccess, runMigration} from "sqlmorpheus";
import BetterSqlite3 from "better-sqlite3";

const db = new BetterSqlite3(":memory:");
const dbAccess: DatabaseAccess = {
    runReadStatement: async (query: string) => db.prepare(query).all(), 
    runWriteStatement: async (query: string) => db.prepare(query).run(), 
    runTransaction: async (query: string) => {
        const transaction = db.transaction(() => db.exec(query));
        transaction();
    }
}

On top of the three mandatory methods, you can also define createBackup(). This callback is called whenever the version in DatabaseInstructions has changed and SqlMorpheus needs to change the database. An example implementation for a backup in SQLite would be:

const dbAccess: DatabaseAccess = {
    ...,
    createBackup: async (backupName: string) => {
        await db.backup(`backups/${backupName}.sqlite`)
    }
}

2. Define the database structure

This part might require the most work from you, but should be familiar to you if you have already used other migration libraries: You need to tell SqlMorpheus what structure it should mold your database into. To make this process as simple as possible, SqlMorpheus provides a convenient TableObj.create() builder (see TableObj example) or, if you prefer, you can also use decorators (see decorator example). Here is an example using TableObj.create():

import {DatabaseAccess, runMigration} from "sqlmorpheus";
const usersTable = TableObj.create("User", {
    userId: [0, {primaryKey: true}], 
    name: "Default name", 
    email: [null, {dataType: "string"}]
});
const messagesTable = TableObj.create("Message", {
    messageId: [0, {primaryKey: true}], 
    from: 0,
    to: 0, 
    content: ""
})
    .foreignKey("from", usersTable, "userId", {onDelete: "CASCADE"})
    .foreignKey("to", usersTable, "userId", {onDelete: "CASCADE"});

3. Create the database instructions and run the migration

Now we combine everything and call runMigration().

Example:

const instructions: DatabaseInstructions = {
    dialect: "Sqlite", 
    tables: [userTable, messagesTable], // usersTable and messagesTable are defined above 
    version: 1
};

await runMigration(dbAccess, instructions); // dbAccess is defined above

dialect

This property tells SqlMorpheus which SQL dialect your database uses.

tables

This property contains all tables that should be created in the database.

version

SqlMorpheus will only compare the database structure when the database version is different to the version property defined in DatabaseInstructions. The version property is also used to decide which manual migrations defined in preMigration() should be executed.

preMigration()

This method is run before database migrations (and comparisons) are executed. This is also the place where you allow specific destructive migrations or tell SqlMorpheus that you want to rename a table or column (rather than removing and adding it – which would be the default behaviour).

postMigration()

This method is run after the migration was finished. You will very rarely need it.

All properties are documented in DatabaseInstructions.

When does SqlMorpheus check for migrations?

SqlMorpheus will only compare the database when the version property is different to the version saved in the database itself (or if the database has no version defined at all).

How to rename a table or column?

SqlMorpheus has no way of telling if you want to rename a table / column or want to remove it and add a completely new one. To solve this, it relies on your input to tell it what to do (by default it just removes and adds a table / column). To tell it to rename a table / column, you call migration.renameTable(VERSION, "OLD_TABLENAME", "NEW_TABLENAME"); in preMigration() (example)

rollback your database

SqlMorpheus saves its changes into the database (into a table called __sqlmorpheus_migrations) which allows you to roll back the database to a previous state with a single command:

// `dbAccess` and `instructions` are defined above
await rollback(dbAccess, TARGET_VERSION, instructions.dialect);