Use when defining TypeORM entities, writing migrations, or building repository/query-builder code in TypeScript. Covers entity and relation decorators, the Data Mapper pattern, migrations, the query builder, transactions, and multi-database configuration.
63
74%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./skills/typeorm/SKILL.mdYou are an expert in TypeORM, TypeScript, and database design with a focus on the Data Mapper pattern and enterprise application architecture.
Required settings in tsconfig.json:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strict": true,
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node"
}
}experimentalDecorators and emitDecoratorMetadata are both mandatory — without
them decorators won't compile and column metadata won't resolve.
A representative entity uses a generated primary key, typed @Columns, and the
managed timestamp columns:
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity('users')
export class User {
@PrimaryGeneratedColumn()
id!: number;
@Column({ type: 'varchar', length: 255, unique: true })
email!: string;
@Column({ type: 'varchar', length: 255, nullable: true })
name!: string | null;
@Column({ type: 'boolean', default: true })
isActive!: boolean;
@CreateDateColumn()
createdAt!: Date;
@UpdateDateColumn()
updatedAt!: Date;
}For the full primary-key options (UUID, custom, composite), the complete column decorator/option set (numeric, enum, JSON, soft-delete, version), and all relation types (one-to-one, one-to-many/many-to-one, many-to-many), see reference.md.
// data-source.ts
import { DataSource } from 'typeorm';
import { User } from './entities/User';
import { Post } from './entities/Post';
export const AppDataSource = new DataSource({
type: 'postgres',
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT || '5432'),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
// Entity configuration
entities: [User, Post],
// Or use glob pattern: entities: ["src/entities/**/*.ts"]
// Migrations
migrations: ['src/migrations/**/*.ts'],
// Synchronize - NEVER use in production
synchronize: false,
// Logging
logging: process.env.NODE_ENV === 'development',
// Connection pool
poolSize: 10,
// SSL (for production)
ssl:
process.env.NODE_ENV === 'production'
? { rejectUnauthorized: false }
: false,
});
// Initialize connection
AppDataSource.initialize()
.then(() => console.log('Data Source initialized'))
.catch((error) => console.error('Error initializing Data Source:', error));AppDataSource.getRepository(Entity), then use
find, findOne, create, save, update, delete, and softDelete.relations: ['posts'] (or a
leftJoinAndSelect in the query builder) instead of eager: true, to avoid
N+1 query storms.synchronize: true in production — generate and run migrations
for every schema change.@Index().release() a manually created QueryRunner in a finally block.Full API detail — repository methods, custom repositories, the query builder, migrations, transactions, framework integration, and best practices — lives in the reference.
<EntityName><MigrationName>7741177
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.