Relevant source files
The following files were used as context for generating this wiki page:
- drizzle-arktype/scripts/fix-imports.ts
- drizzle-typebox/scripts/fix-imports.ts
- drizzle-zod/scripts/fix-imports.ts
- drizzle-valibot/scripts/fix-imports.ts
- drizzle-orm/scripts/fix-imports.ts
- drizzle-orm/scripts/build.ts
- drizzle-valibot/scripts/build.ts
- drizzle-arktype/scripts/build.ts
- drizzle-zod/scripts/build.ts
- drizzle-typebox/scripts/build.ts
- drizzle-seed/scripts/build.ts
- drizzle-kit/build.ts
- turbo.json
- drizzle-orm/tsup.config.ts
- drizzle-kit/build.dev.ts
- drizzle-kit/imports-checker/checker.ts
- package.json
- drizzle-kit/src/serializer/pgImports.ts
- drizzle-typebox/rollup.config.ts
- drizzle-valibot/rollup.config.ts
- drizzle-kit/src/serializer/singlestoreImports.ts
- drizzle-kit/src/serializer/studio.ts
- drizzle-zod/rollup.config.ts
- drizzle-seed/rollup.config.ts
- drizzle-arktype/rollup.config.ts
- drizzle-kit/imports-checker/index.ts
- tsconfig.json
- integration-tests/vitest-ci.config.ts
- drizzle-seed/tsconfig.json
- integration-tests/sst-env.d.ts
Overview
The monorepo build pipeline coordinates task execution, multi-entry compilation, bundling, and distribution packaging across packages like drizzle-orm, drizzle-kit, drizzle-seed, and schema validation adapters using Project Structure. Powered by Turborepo task orchestration, the pipeline resolves package dependencies and build caching rules at the repository root turbo.json:1-253. Individual packages compile source files into production-ready CommonJS and ESM formats through tsup, Rollup, and esbuild workflows while rewriting path aliases and verifying bundle boundaries drizzle-orm/scripts/build.ts:1-76, drizzle-kit/build.ts:1-150, drizzle-kit/imports-checker/checker.ts:1-296.
Sources: turbo.json:1-253, drizzle-orm/scripts/build.ts:1-76, drizzle-kit/build.ts:1-150, drizzle-kit/imports-checker/checker.ts:1-296
Turborepo Task Orchestration
Task orchestration across the monorepo root is defined in turbo.json, which governs pipeline topology, package-level dependencies, input file sets, and build caching behavior turbo.json:1-254. The pipeline executes tasks such as building, type-checking, linting, packaging, and testing by tracking precise dependencies between packages turbo.json:3-253. For instance, drizzle-orm#build acts as the foundational primitive upon which all companion library builds, CLI tooling, and test harnesses depend turbo.json:32-209.
Sources: turbo.json:32-240
The root task definitions govern specific execution parameters and file watch patterns. The root configuration specifies inputs, outputs, and logging levels to optimize remote and local caching turbo.json:1-254.
| Task Name | Depends On | Inputs | Outputs | Output Logs |
|---|---|---|---|---|
//#lint | ^test:types, drizzle-orm#build | **/*.ts, !**/node_modules, !**/dist, !**/dist-dts | None | new-only |
test:types | ^test:types, drizzle-orm#build, drizzle-seed#build | src/**/*.ts, tests/**/*.ts, tsconfig.json, tests/tsconfig.json, ../tsconfig.json | None | new-only |
drizzle-orm#build | None | src/**/*.ts, package.json, README.md, ../README.md, tsconfig.json, tsconfig.*.json, tsup.config.ts, scripts/build.ts, scripts/fix-imports.ts, ../tsconfig.json | dist/**, dist-dts/** | new-only |
drizzle-kit#build | drizzle-orm#build | src/**/*.ts, package.json, README.md, ../README.md, tsconfig.json, tsconfig.*.json, tsup.config.ts, scripts/build.ts, scripts/fix-imports.ts, ../tsconfig.json | dist/**, dist-dts/** | new-only |
drizzle-zod#build | drizzle-orm#build | src/**/*.ts, package.json, README.md, ../README.md, tsconfig.json, tsconfig.*.json, tsup.config.ts, scripts/build.ts, scripts/fix-imports.ts, ../tsconfig.json | dist/**, dist-dts/** | new-only |
drizzle-typebox#build | drizzle-orm#build | src/**/*.ts, package.json, README.md, ../README.md, tsconfig.json, tsconfig.*.json, tsup.config.ts, scripts/build.ts, scripts/fix-imports.ts, ../tsconfig.json | dist/**, dist-dts/** | new-only |
drizzle-valibot#build | drizzle-orm#build | src/**/*.ts, package.json, README.md, ../README.md, tsconfig.json, tsconfig.*.json, tsup.config.ts, scripts/build.ts, scripts/fix-imports.ts, ../tsconfig.json | dist/**, dist-dts/** | new-only |
drizzle-arktype#build | drizzle-orm#build | src/**/*.ts, package.json, README.md, ../README.md, tsconfig.json, tsconfig.*.json, tsup.config.ts, scripts/build.ts, scripts/fix-imports.ts, ../tsconfig.json | dist/**, dist-dts/** | new-only |
eslint-plugin-drizzle#build | drizzle-orm#build | src/**/*.ts, package.json, README.md, ../README.md, tsconfig.json, tsconfig.*.json, tsup.config.ts, scripts/build.ts, scripts/fix-imports.ts, ../tsconfig.json | dist/**, dist-dts/** | new-only |
drizzle-seed#build | drizzle-orm#build | src/**/*.ts, package.json, README.md, ../README.md, tsconfig.json, tsconfig.*.json, tsup.config.ts, scripts/build.ts, scripts/fix-imports.ts, ../tsconfig.json | dist/**, dist-dts/** | new-only |
integration-tests#build | drizzle-orm#build, drizzle-seed#build | src/**/*.ts, package.json, README.md, ../README.md, tsconfig.json, tsconfig.*.json, tsup.config.ts, scripts/build.ts, scripts/fix-imports.ts, ../tsconfig.json | dist/**, dist-dts/** | new-only |
pack | build, test:types | dist/** | package.tgz | new-only |
test | build, test:types | tests/**/*.test.ts, tests/**/*.test.cjs, tests/**/*.test.mjs | None | new-only |
Sources: turbo.json:3-252
Note
All build tasks across companion validation packages (drizzle-zod, drizzle-typebox, drizzle-valibot, drizzle-arktype), tooling (drizzle-kit, eslint-plugin-drizzle), and test suites explicitly require drizzle-orm#build to complete first, establishing core runtime outputs before dependent compilation phases run turbo.json:51-182.
Tip
The root package.json maps short aliases to Turborepo invocations, allowing developers to execute full pipeline builds via pnpm build or target specific packages using filters such as pnpm build:orm package.json:4-14.
Sources: turbo.json:51-182, package.json:4-14
Core Package tsup Compilation
The compilation of drizzle-orm relies on a multi-entry configuration processed by tsup alongside custom build orchestration scripts. Every TypeScript source file under src/ serves as an independent compilation entry point without bundling or splitting enabled, maintaining individual file structures for both CommonJS and ESM module outputs.
| Option | Value | Purpose |
|---|---|---|
entry | entries (src/**/*.ts) | Discovers all source files to compile as individual entry points |
outDir | 'dist.new' | Directs initial compilation output to a staging directory before atomic replacement |
format | ['cjs', 'esm'] | Generates both CommonJS and ESM distribution formats simultaneously |
bundle | false | Disables bundling to preserve module file boundaries |
splitting | false | Disables code splitting across entries |
sourcemap | true | Emits source maps for debugging compiled artifacts |
tsconfig | 'tsconfig.build.json' | Specifies the TypeScript build configuration file |
Sources: drizzle-orm/tsup.config.ts:1-19
Warning
Because bundle: false and splitting: false are configured in tsup.config.ts, relative import specifiers in compiled output lack file extensions unless post-processed, which would break native Node.js ESM resolution rules.
Sources: drizzle-orm/tsup.config.ts:10-11
The complete build script orchestrated by scripts/build.ts executes parallel compilation tasks, declaration file generation, and import path rewriting before finalizing the distribution directory.
Sources: drizzle-orm/scripts/build.ts:49-76
To resolve path aliases and ensure proper extension mapping for both ESM and CJS outputs, scripts/fix-imports.ts parses generated files using recast and visits import declarations, export declarations, require calls, and dynamic imports.
function resolvePathAlias(importPath: string, file: string) {
if (importPath.startsWith('~/')) {
const relativePath = path.relative(path.dirname(file), path.resolve('dist.new', importPath.slice(2)));
importPath = relativePath.startsWith('.') ? relativePath : './' + relativePath;
}
return importPath;
}
function fixImportPath(importPath: string, file: string, ext: string) {
importPath = resolvePathAlias(importPath, file);
if (!/\..*\.(js|ts)$/.test(importPath)) {
return importPath;
}
return importPath.replace(/\.(js|ts)$/, ext);
}Sources: drizzle-orm/scripts/fix-imports.ts:8-25
Note
The import fixer script processes dist.new by targeting cjsFiles (*.{cjs,d.cts}) with .cjs extensions and esmFiles (*.{js,d.ts}) with .js extensions, updating import, export, require(), type-only imports, and dynamic await import() expressions.
Sources: drizzle-orm/scripts/fix-imports.ts:27-101
Companion Validation Package Bundling
Rollup and Build Orchestration
Companion validation packages (drizzle-zod, drizzle-typebox, drizzle-valibot, and drizzle-arktype) share an identical build pipeline architecture. Each package build begins by removing the existing dist directory, then invokes Rollup with the TypeScript compiler plugin referencing tsconfig.build.json. Following bundling, path resolution utilities execute, README.md and package.json are copied into the distribution folder, declaration files are duplicated with .d.mts and .d.cts extensions via cpy, and a recast-based import rewriting script standardizes module specifiers.
| Companion Package | External Dependencies | Entry Point |
|---|---|---|
drizzle-zod | /^drizzle-orm\/?/, zod | src/index.ts |
drizzle-typebox | /^drizzle-orm\/?/, @sinclair/typebox | src/index.ts |
drizzle-valibot | /^drizzle-orm\/?/, valibot | src/index.ts |
drizzle-arktype | /^drizzle-orm\/?/, arktype | src/index.ts |
Sources: drizzle-zod/rollup.config.ts:6-26, drizzle-typebox/rollup.config.ts:6-26, drizzle-valibot/rollup.config.ts:6-26, drizzle-arktype/rollup.config.ts:6-26, drizzle-zod/scripts/build.ts:5-16
Note
All four validation adapters configure Rollup outputs for both ESM and CommonJS formats simultaneously, emitting .mjs entry files, .cjs entry files, corresponding chunk files with content hashes, and enabled sourcemaps.
Sources: drizzle-zod/rollup.config.ts:7-22, drizzle-typebox/rollup.config.ts:7-22, drizzle-valibot/rollup.config.ts:7-22, drizzle-arktype/rollup.config.ts:7-22
Import Rewriting and Path Aliasing
The build process concludes by executing a post-processing script using recast to traverse compiled output files in the dist directory. This script resolves path aliases beginning with ~/ relative to dist.new and normalizes explicit file extensions across CommonJS, ESM, and modern module variants.
function resolvePathAlias(importPath: string, file: string) {
if (importPath.startsWith('~/')) {
const relativePath = path.relative(path.dirname(file), path.resolve('dist.new', importPath.slice(2)));
importPath = relativePath.startsWith('.') ? relativePath : './' + relativePath;
}
return importPath;
}
function fixImportPath(importPath: string, file: string, ext: string) {
importPath = resolvePathAlias(importPath, file);
if (!/\..*\.(js|ts)$/.test(importPath)) {
return importPath;
}
return importPath.replace(/\.(js|ts)$/, ext);
}Sources: drizzle-zod/scripts/fix-imports.ts:8-25, drizzle-typebox/scripts/fix-imports.ts:8-25, drizzle-valibot/scripts/fix-imports.ts:8-25, drizzle-arktype/scripts/fix-imports.ts:8-25
Warning
The import fixer inspects import declarations, export declarations, named export sources, require call expressions, TypeScript import types, and dynamic await import() expressions, replacing extensions with .cjs, .js, or .mjs depending on the target file set.
Sources: drizzle-zod/scripts/fix-imports.ts:27-135, drizzle-typebox/scripts/fix-imports.ts:27-135, drizzle-valibot/scripts/fix-imports.ts:27-135, drizzle-arktype/scripts/fix-imports.ts:27-135
Seed Package Distribution Setup
The distribution pipeline for drizzle-seed relies on an execution script built with zx, combined with a Rollup configuration that targets dual-format outputs. The build sequence begins by removing the existing dist directory, executing Rollup with the TypeScript compiler plugin referencing tsconfig.build.json, running resolve-tspaths for path alias resolution, and copying README.md and package.json into the distribution folder.
#!/usr/bin/env -S pnpm tsx
import 'zx/globals';
import cpy from 'cpy';
await fs.remove('dist');
await $`rollup --config rollup.config.ts --configPlugin typescript`;
await $`resolve-tspaths`;
await fs.copy('README.md', 'dist/README.md');
await cpy('dist/**/*.d.ts', 'dist', {
rename: (basename) => basename.replace(/\.d\.ts$/, '.d.mts'),
});
await cpy('dist/**/*.d.ts', 'dist', {
rename: (basename) => basename.replace(/\.d\.ts$/, '.d.cts'),
});
await fs.copy('package.json', 'dist/package.json');Sources: drizzle-seed/scripts/build.ts:1-15
Note
Following declaration generation, cpy duplicates all generated .d.ts declaration files within the dist folder into .d.mts and .d.cts extensions to support both ESM and CommonJS TypeScript consumers.
Sources: drizzle-seed/scripts/build.ts:9-14
| Rollup Property / Option | Target Value / Setting | Purpose |
|---|---|---|
input | src/index.ts | Primary entry point for bundling |
| ESM Format Output | format: 'esm', dir: 'dist', [name].mjs | ECMAScript module distribution bundle |
| CJS Format Output | format: 'cjs', dir: 'dist', [name].cjs | CommonJS module distribution bundle |
external | /^drizzle-orm\/?/, 'pure-rand' | Externalized packages excluded from the bundle |
| TypeScript Plugin Config | tsconfig: 'tsconfig.build.json' | Compiler configuration utilized during Rollup bundling |
Sources: drizzle-seed/rollup.config.ts:4-28
Warning
The TypeScript configuration (tsconfig.json) sets "noEmit": true for local type checking and development, whereas Rollup invokes the compiler plugin referencing tsconfig.build.json to emit compilation outputs.
Sources: drizzle-seed/rollup.config.ts:25-27, drizzle-seed/tsconfig.json:37-37
CLI esbuild Pipeline
Production and Development Bundling
Production and development workflows for drizzle-kit leverage esbuild and tsup to bundle utilities, API endpoints, and CLI binaries targeting Node.js environments. The production workflow executed in build.ts invokes esbuild.buildSync to bundle ./src/utils.ts into CommonJS and ESM targets (dist/utils.js and dist/utils.mjs), alongside compiling the CLI entry point ./src/cli/index.ts into dist/bin.cjs with version injection via process.env.DRIZZLE_KIT_VERSION.
esbuild.buildSync({
entryPoints: ['./src/utils.ts'],
bundle: true,
outfile: 'dist/utils.js',
format: 'cjs',
target: 'node16',
platform: 'node',
external: [
'commander',
'json-diff',
'glob',
'esbuild',
'drizzle-orm',
...driversPackages,
],
banner: {
js: `#!/usr/bin/env node`,
},
});
esbuild.buildSync({
entryPoints: ['./src/utils.ts'],
bundle: true,
outfile: 'dist/utils.mjs',
format: 'esm',
target: 'node16',
platform: 'node',
external: [
'commander',
'json-diff',
'glob',
'esbuild',
'drizzle-orm',
...driversPackages,
],
banner: {
js: `#!/usr/bin/env node`,
},
});
esbuild.buildSync({
entryPoints: ['./src/cli/index.ts'],
bundle: true,
outfile: 'dist/bin.cjs',
format: 'cjs',
target: 'node16',
platform: 'node',
define: {
'process.env.DRIZZLE_KIT_VERSION': `"${pkg.version}"`,
},
external: [
'esbuild',
'drizzle-orm',
...driversPackages,
],
banner: {
js: `#!/usr/bin/env node`,
},
});Sources: drizzle-kit/build.ts:23-81
Note
The production compiler injects executable shebang banners (#!/usr/bin/env node) into the generated distribution files while leaving external driver packages, drizzle-orm, esbuild, commander, json-diff, and glob unbundled.
Sources: drizzle-kit/build.ts:30-41, drizzle-kit/build.ts:50-61, drizzle-kit/build.ts:73-80
| Driver Category | Externalized Package Identifiers |
|---|---|
| PostgreSQL Drivers | pg, postgres, @vercel/postgres, @neondatabase/serverless, @electric-sql/pglite |
| MySQL Drivers | mysql2, @planetscale/database |
| SQLite Drivers | @libsql/client, better-sqlite3, bun:sqlite |
Sources: drizzle-kit/build.ts:7-21
API Compilation and Post-Processing
The asynchronous main function in the production build script utilizes tsup to compile the library entry points ./src/index.ts and ./src/api.ts into dual-format CommonJS and ESM outputs with generated TypeScript declarations.
const main = async () => {
await tsup.build({
entryPoints: ['./src/index.ts'],
outDir: './dist',
external: [
'esbuild',
'drizzle-orm',
...driversPackages,
],
splitting: false,
dts: true,
format: ['cjs', 'esm'],
outExtension: (ctx) => {
if (ctx.format === 'cjs') {
return {
dts: '.d.ts',
js: '.js',
};
}
return {
dts: '.d.mts',
js: '.mjs',
};
},
});
await tsup.build({
entryPoints: ['./src/api.ts'],
outDir: './dist',
external: [
'esbuild',
'drizzle-orm',
...driversPackages,
],
splitting: false,
dts: true,
format: ['cjs', 'esm'],Sources: drizzle-kit/build.ts:83-119
Warning
Post-processing reads ./dist/api.js and replaces dynamic await import( expressions with synchronous require( calls to resolve dynamic require issues involving the glob and fs modules in CommonJS outputs.
Sources: drizzle-kit/build.ts:120-147
Development Workflow Script
The development bundling script defined in build.dev.ts configures esbuild to target local debugging workflows by emitting development binaries and copying runtime loader scripts.
esbuild.buildSync({
entryPoints: ['./src/utils.ts'],
bundle: true,
outfile: 'dist/utils.js',
format: 'cjs',
target: 'node16',
platform: 'node',
external: ['drizzle-orm', 'esbuild', ...driversPackages],
banner: {
js: `#!/usr/bin/env -S node --loader @esbuild-kit/esm-loader --no-warnings`,
},
});
esbuild.buildSync({
entryPoints: ['./src/cli/index.ts'],
bundle: true,
outfile: 'dist/index.cjs',
format: 'cjs',
target: 'node16',
platform: 'node',
external: [
'commander',
'json-diff',
'glob',
'esbuild',
'drizzle-orm',
...driversPackages,
],
banner: {
js: `#!/usr/bin/env -S node --loader ./dist/loader.mjs --no-warnings`,
},
});
cpSync('./src/loader.mjs', 'dist/loader.mjs');Sources: drizzle-kit/build.dev.ts:18-51
Tip
The development build configures custom shebang banners referencing @esbuild-kit/esm-loader and ./dist/loader.mjs alongside syncing ./src/loader.mjs directly into the dist directory via cpSync.
Sources: drizzle-kit/build.dev.ts:26-28, drizzle-kit/build.dev.ts:46-51
Import Analysis and Boundary Enforcement
Static Import Analysis Engine
The drizzle-kit module includes a static import checker and boundary enforcement system designed to validate allowed module boundaries, track access chains, and detect forbidden external dependencies across codebase files. The ImportAnalyzer class processes an entry point file (such as ./drizzle-kit/src/cli/index.ts), recursively inspecting import declarations using custom resolvers and micromatch pattern matching against defined whitelists or blacklists.
class ImportAnalyzer {
private localImportRegex = /^(\.?\.?\/|\.\.?$)/;
private importedFileFormatRegex = /^.*\.(ts|tsx|mts|cts|js|jsx|mjs|cjs|json)$/i;
private visited: Set<string> = new Set<string>();
private externals: External[] = [];
private accessChains: Record<string, ChainLink[][]> = {};
constructor(
private basePath: string,
private entry: string,
private listMode: ListMode,
private readonly wantedList: string[],
private localPaths: string[],
private logger?: boolean,
private ignoreTypes?: boolean,
) {}Sources: drizzle-kit/imports-checker/checker.ts:30-47
Note
The analyzer recognizes custom local paths configured via localPaths (such as src) and resolves target files across TypeScript and JavaScript extensions including .ts, .mts, .cts, .tsx, .js, .mjs, .cjs, and .jsx, as well as checking directory index files.
Sources: drizzle-kit/imports-checker/checker.ts:67-109
| Config Field | Type | Purpose |
|---|---|---|
basePath | string | Base directory path for resolving modules |
entry | string | Entry point file path for analysis |
whiteList | string[] (optional) | Permitted external import patterns (whitelist mode) |
blackList | string[] (optional) | Forbidden external import patterns (blacklist mode) |
localPaths | string[] (optional) | Custom path prefixes treated as local source files |
ignoreTypes | boolean (optional) | Skip analysis of type-only imports |
logger | boolean (optional) | Enable console logging during file traversal |
Sources: drizzle-kit/imports-checker/checker.ts:245-260
Whitelist Boundary Enforcement
The CLI verification script initializes analyzeImports pointing to ./drizzle-kit with localPaths set to src, ignoring type imports and enforcing a strict whitelist of permitted external modules and built-in Node.js libraries. Any external package imported outside this whitelist generates a reported issue containing the file path, violating import name, and full access chains.
const issues = analyzeImports({
basePath: './drizzle-kit',
localPaths: ['src'],
whiteList: [
'@drizzle-team/brocli',
'json-diff',
'path',
'fs',
'fs/*',
'url',
'zod',
'node:*',
'hono',
'glob',
'hono/*',
'hono/**/*',
'@hono/*',
'crypto',
'hanji',
],
entry: './drizzle-kit/src/cli/index.ts',
logger: true,
ignoreTypes: true,
}).issues;Sources: drizzle-kit/imports-checker/index.ts:4-27
Warning
The default import checker whitelist explicitly restricts external dependencies to the approved packages listed below; introducing unlisted third-party packages causes build and validation check failures.
Sources: drizzle-kit/imports-checker/index.ts:7-23
| Whitelisted Package / Pattern | Category / Purpose |
|---|---|
@drizzle-team/brocli | CLI command parser framework |
json-diff | JSON structure comparison utility |
path, fs, fs/*, url, crypto, node:* | Node.js standard libraries and path utilities |
zod | Schema validation and parsing library |
hono, hono/*, hono/**/*, @hono/* | Lightweight web application framework and routing |
glob | File pattern matching utility |
hanji | Terminal UI rendering or prompt utility |
Sources: drizzle-kit/imports-checker/index.ts:8-22
Related
On This Page
OverviewTurborepo Task OrchestrationCore Package tsup CompilationCompanion Validation Package BundlingRollup and Build OrchestrationImport Rewriting and Path AliasingSeed Package Distribution SetupCLI esbuild PipelineProduction and Development BundlingAPI Compilation and Post-ProcessingDevelopment Workflow ScriptImport Analysis and Boundary EnforcementStatic Import Analysis EngineWhitelist Boundary EnforcementRelated