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

egg-sequelize-next

v7.0.0

Published

Sequelize plugin for Egg 4, written in TypeScript/ESM

Readme

egg-sequelize-next

Sequelize plugin for Egg 4, written in TypeScript and shipped as ESM. It is the modernized successor of egg-sequelize, which stops at Egg 2/3.

This plugin only integrates Sequelize into Egg, please read the Sequelize documentation for the ORM itself.

  • Loads every model under app/model into app.model and ctx.model.
  • Model loading is asynchronous on Egg 4, so it is wired into the boot hooks instead of running when the plugin file is parsed.
  • Works with Egg's manifest and bundle based startups.
  • Ships types for app.model / ctx.model and for your own models.

Install

$ npm i --save egg-sequelize-next
$ npm i --save mysql2 # for the mysql and mariadb dialects

# or use another database backend
$ npm i --save pg pg-hstore # PostgreSQL
$ npm i --save sqlite3      # SQLite
$ npm i --save tedious      # MSSQL

Requirements: Node.js >= 22.18.0 and Egg >= 4.

Usage & configuration

  • Enable the plugin in config/plugin.ts:
import sequelizePlugin from 'egg-sequelize-next';

export default {
  ...sequelizePlugin(),
};

The traditional declaration keeps working too, for example in a CommonJS config/plugin.js:

exports.sequelize = {
  enable: true,
  package: 'egg-sequelize-next',
};
  • Edit your own configuration in config/config.{env}.ts:
export default {
  sequelize: {
    dialect: 'mysql', // support: mysql, mariadb, postgres, mssql, sqlite
    database: 'test',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: '',
    // delegate: 'myModel', // load all models to `app[delegate]` and `ctx[delegate]`, default to `model`
    // baseDir: 'my_model', // load all files in `app/${baseDir}` as models, default to `model`
    // exclude: 'index.js', // ignore `app/${baseDir}/index.js` when loading models, support glob and array
    // more sequelize options
  },
};

You can also configure the connection with a full URI:

export default {
  sequelize: {
    // the dialect and the database are taken from the uri
    connectionUri: 'mysql://root:password@localhost:3306/test',
  },
};

The plugin merges your configuration over these defaults:

{
  delegate: 'model',
  baseDir: 'model',
  logging(sql, timing) {
    // the elapsed time is only passed when `benchmark` is enabled
    const used = typeof timing === 'number' ? `(${timing}ms)` : '';
    app.logger.info('[egg-sequelize-next]%s %s', used, sql);
  },
  host: 'localhost',
  port: 3306,
  username: 'root',
  benchmark: true,
  define: {
    freezeTableName: false,
    underscored: true,
  },
}

Model files

Models live in app/model by default, and every file is loaded as a factory that receives the app and the sequelize instance of its datasource:

// app/model/user.js
module.exports = app => {
  const { STRING, INTEGER, DATE } = app.Sequelize;

  const User = app.model.define('user', {
    login: STRING,
    name: STRING(30),
    age: INTEGER,
    last_sign_in_at: DATE,
    created_at: DATE,
    updated_at: DATE,
  });

  User.findByLogin = async function(login) {
    return this.findOne({ where: { login } });
  };

  // don't use an arrow function here
  User.prototype.logSignin = async function() {
    return this.update({ last_sign_in_at: new Date() });
  };

  return User;
};

app.model is a sequelize instance, so app.model.sync(), app.model.query(), ... are all available. In a controller, use the per-request ctx.model:

// app/controller/user.js
class UserController extends Controller {
  async index() {
    this.ctx.body = await this.ctx.model.User.findAll();
  }

  async show() {
    const user = await this.ctx.model.User.findByLogin(this.ctx.params.login);
    await user.logSignin();
    this.ctx.body = user;
  }
}

Conventions

| model file | property | | ----------------- | ------------------------ | | user.js | app.model.User | | person.js | app.model.Person | | user_group.js | app.model.UserGroup | | user/profile.js | app.model.User.Profile |

  • Tables always have the timestamp fields created_at and updated_at.
  • Use the underscore style for column names, e.g. user_id, comments_count.
  • Files that do not export a factory function (e.g. module.exports = {}) are skipped.

Associate

Declare every association in Model.associate(): the plugin calls it after all models of the datasource are loaded, so the other models are guaranteed to be available.

Multiple datasources

config.sequelize.datasources loads several databases independently:

// config/config.default.js
exports.sequelize = {
  datasources: [
    {
      delegate: 'model', // load all models to app.model and ctx.model
      baseDir: 'model', // load models from `app/model/*.js`
      database: 'biz',
      // other sequelize configurations
    },
    {
      delegate: 'adminModel', // load all models to app.adminModel and ctx.adminModel
      baseDir: 'admin_model', // load models from `app/admin_model/*.js`
      database: 'admin',
      // other sequelize configurations
    },
  ],
};

A model file that is loaded for several datasources gets the sequelize instance of the datasource as second argument:

// app/model/user.js, loaded once per datasource
module.exports = (app, model) => {
  const { STRING, INTEGER } = app.Sequelize;

  const User = model.define('user', {
    name: STRING(30),
    age: INTEGER,
  });

  return User;
};

delegate may contain dots, e.g. subproperty.a, which groups datasources under one property (app.subproperty.a, ctx.subproperty.a).

TypeScript

app.model and ctx.model are typed, and an application can declare its own models by augmenting IModel:

// typings/index.d.ts
import 'egg';
import 'egg-sequelize-next';
import User from '../app/model/user';

declare module 'egg' {
  interface IModel {
    User: ReturnType<typeof User>;
  }
}

Upgrading from egg-sequelize

The configuration (delegate, baseDir, exclude, connectionUri, datasources, Sequelize, ...) is unchanged, only the package name and the loading life cycle changed:

  • Replace egg-sequelize with egg-sequelize-next in package.json and config/plugin.js.
  • Models are attached to app.model when the didLoad boot hook runs instead of when the boot file is parsed. Use app.beforeStart() or later if your code needs the models.
  • config.sequelize.ignore is deprecated, use config.sequelize.exclude.
  • The exclude patterns are matched by the plugin itself. The excluded files are still imported, but they are not registered as models.
  • @types/sequelize is not needed anymore, sequelize 6 ships its own types.

License

MIT