docs/versioned_docs/version-7.0/folder-based-discovery.md
Instead of explicitly listing all entities, you can use glob patterns to discover entities automatically based on file naming conventions.
import { defineConfig } from '@mikro-orm/sqlite';
export default defineConfig({
// Glob patterns for compiled JavaScript files
entities: ['dist/**/*.entity.js'],
// Glob patterns for TypeScript source files (used in development)
entitiesTs: ['src/**/*.entity.ts'],
// ...
});
entitiesTs patternsentities patternsIt is important that
entitiespoints to the compiled JS files, andentitiesTspoints to the TS source files. You should not mix those.
A common convention is to use the .entity.ts suffix:
src/
├── modules/
│ ├── user/
│ │ └── user.entity.ts
│ ├── article/
│ │ ├── article.entity.ts
│ │ └── tag.entity.ts
│ └── common/
│ └── base.entity.ts
└── mikro-orm.config.ts
The paths are resolved using native Node.js glob, so you can use standard globbing patterns:
const orm = await MikroORM.init({
// All .entity.js files in dist folder recursively
entities: ['./dist/**/*.entity.js'],
// Multiple patterns
entities: ['./dist/modules/**/*.entity.js', './dist/shared/**/*.entity.js'],
// Negative patterns to exclude files
entities: ['./dist/**/*.entity.js', '!./dist/**/*.test.entity.js'],
});
:::note Brace expansion
Native Node.js glob does not support brace expansion patterns like src/{entities,modules}/*.ts. If you need this feature, use tinyglobby directly:
import { glob } from 'tinyglobby';
export default defineConfig({
entities: await glob(['src/{entities,modules}/*.ts']),
});
:::
If you are experiencing problems with folder-based discovery, use the mikro-orm debug CLI command to check what paths are actually being used:
npx mikro-orm debug
This will show you:
| Aspect | Explicit (entities: [User]) | Folder-based (entities: ['**/*.entity.js']) |
|---|---|---|
| Setup complexity | More code | Less code |
| Refactoring | IDE-supported | Manual pattern updates |
| Build tools | Works everywhere | May need configuration |
| Performance | Faster startup | Slightly slower (file scanning) |
| Error detection | Compile-time | Runtime |
defineEntity (recommended approach)When using the synchronous new MikroORM() constructor instead of MikroORM.init(), folder-based discovery is not supported:
// This works - async initialization supports folder-based discovery
const orm = await MikroORM.init({
entities: ['dist/**/*.entity.js'],
});
// This does NOT work - must use explicit entity references
const orm = new MikroORM({
entities: ['dist/**/*.entity.js'],
// use explicit references only with sync init
// entities: [User, Article],
});
You can combine multiple patterns and explicit references:
import { BaseEntity } from './entities/base.entity.js';
export default defineConfig({
entities: [
BaseEntity, // explicit reference
'dist/modules/**/*.entity.js', // glob pattern
],
entitiesTs: [
BaseEntity,
'src/modules/**/*.entity.ts',
],
});
This is useful when you have base entities that need to be loaded first, or when mixing discovery approaches.