Sequelize is a monorepo ORM for Node.js supporting 9+ databases. Key architectural patterns:
@sequelize/core
) + dialect-specific packages (@sequelize/postgres
, @sequelize/mysql
, etc.)dialect.ts
, query-generator.js
, query-interface.js
, and connection-manager.ts
model.js
with TypeScript definitions, but all new code should be written in TypeScriptbuild-packages.mjs
to compile TypeScript to both CommonJS and ESM.ts
files for all new implementations# Build specific package
node build-packages.mjs core
node build-packages.mjs postgres
# Run tests by dialect
yarn test-integration-postgres
yarn test-unit
# Start local DBs for testing
yarn start-postgres-latest
yarn reset-postgres
# SSCCE (debugging minimal reproductions)
yarn sscce-postgres
dev/{dialect}/{latest|oldest}/
with start/stop/reset scriptspackages/core/test/config/config.ts
with environment-based settingsSupport.createMultiTransactionalTestSequelizeInstance()
for isolationWhen adding dialect features:
packages/{dialect}/src/dialect.ts
for feature support flagsquery-generator.js
(legacy) or query-generator.ts
(preferred for new features)query-interface.js
(legacy) or query-interface.ts
(preferred) for schema operations.js
files// Core pattern in tests and examples
this.User = sequelize.define('User', {
field: DataTypes.STRING,
uniqueField: { type: DataTypes.STRING, unique: true },
});
Support.getTestDialectTeaser()
for dialect-specific test descriptionsbeforeEach
/afterEach
with customSequelize.sync({ force: true })
and .close()
.test.js
for integration, .test.ts
for unit testspackages/core/test/chai-extensions.d.ts
import type { CreationOptional, InferAttributes, InferCreationAttributes } from '@sequelize/core';
import { DataTypes, Model } from '@sequelize/core';
import { Attribute, NotNull } from '@sequelize/core/decorators-legacy';
import { expect } from 'chai';
import { beforeAll2, sequelize, setResetMode } from '../support';
describe('Model#newFeature', () => {
// Skip entire suite if feature is not supported
if (!sequelize.dialect.supports.newFeature) {
return;
}
setResetMode('destroy');
const vars = beforeAll2(async () => {
class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
declare id: CreationOptional<number>;
@Attribute(DataTypes.INTEGER)
@NotNull
declare someField: number;
@Attribute(DataTypes.STRING)
declare name: string | null;
}
sequelize.addModels([User]);
await sequelize.sync({ force: true });
return { User };
});
beforeEach(async () => {
await vars.User.create({ someField: 1, name: 'test' });
});
it('works with basic functionality', async () => {
const user = await vars.User.findByPk(1, { rejectOnEmpty: true });
await user.newFeature();
expect(user.someField).to.equal(2);
});
it('handles edge cases properly', async () => {
const user = await vars.User.findByPk(1, { rejectOnEmpty: true });
await expect(user.newFeature({ invalid: 'option' })).to.be.rejected;
});
// Test dialect-specific behavior
if (sequelize.dialect.name === 'postgres') {
it('supports postgres-specific functionality', async () => {
const user = await vars.User.findByPk(1, { rejectOnEmpty: true });
await user.newFeature({ postgresOption: true });
expect(user.someField).to.equal(3);
});
}
// Test feature variations
if (sequelize.dialect.supports.newFeature?.advanced) {
it('supports advanced newFeature options', async () => {
const user = await vars.User.findByPk(1, { rejectOnEmpty: true });
await user.newFeature({ mode: 'advanced' });
expect(user.someField).to.equal(5);
});
}
});
dialect.supports.featureName
checks to skip unsupported testsSupport.createMultiTransactionalTestSequelizeInstance()
for proper isolationpackages/{dialect}/
├── src/
│ ├── dialect.ts # Feature flags & dialect config
│ ├── query-generator.js # SQL generation logic
│ ├── query-interface.js # Schema operations
│ ├── connection-manager.ts # Connection pooling
│ └── index.ts # Package exports
└── test/ # Package-specific tests
src/model.js
- Main Model class implementationsrc/sequelize.js
- Core Sequelize classsrc/associations/
- Relationship definitionssrc/data-types.ts
- Type systemtest/support.ts
- Test utilities and setup@sequelize/utils
provides shared utilities across packagespackages/core/test/support.ts
used across dialect testsexports
field in package.jsonlib/
directory with both .d.ts
and .d.mts
files@sequelize/core/decorators-legacy
dialect.supports.xyz
checks before implementing dialect-specific features.js
files with separate TypeScript definitions.js
files when necessary