Skip to main content
The @talosjs/entity component is the foundation for domain models in the Talos framework. It ships the IEntity interface and the EntityClassType constructor type that every entity satisfies, so repositories, the container, and the database layer can refer to entities in a uniform, type-safe way. The package itself is intentionally tiny and dependency-free; the actual column mapping is done with TypeORM decorators on classes you generate with the CLI.

What it covers

Every entity exposes a string id through IEntity, which is the single contract that lets repositories and DI treat any model the same way. EntityClassType types a constructor that produces an IEntity, so you can pass entity classes around (DI tokens, repository factories) without falling back to any. Columns, primary keys, timestamps, and relations are all declared with standard TypeORM decorators, so there is nothing proprietary to learn. The package contributes only types and adds nothing to your runtime bundle. To start a new model, talos entity:create scaffolds a ready-to-edit entity with its test file and registers it in the module.

How it works

The package surface is two declarations:
An entity is a TypeORM class whose properties map to columns. You declare the table with @Entity, the primary key with @PrimaryColumn, plain columns with @Column, and the audit timestamps with @CreateDateColumn, @UpdateDateColumn, and @DeleteDateColumn. The id is generated up front so an instance always satisfies IEntity before it is persisted.

Usage

A minimal entity needs an id to satisfy IEntity:
In practice entities are TypeORM classes. Declare the table and map each property to a column:
EntityClassType lets helpers accept any entity class as a value:
Relations use the standard TypeORM decorators (@ManyToOne, @OneToMany, @ManyToMany, @OneToOne) alongside the columns.

Modeling tips

Always give an entity a string id. Generate it at construction (for example with random.nanoid(25)) so an instance satisfies IEntity before it is ever saved. Map every property explicitly by passing name, type, and length to @Column, which keeps the database schema predictable instead of inferred. When a column is nullable, mark it nullable: true and type it | null so the TypeScript type and the database constraint agree. Keep the audit columns. @CreateDateColumn, @UpdateDateColumn, and @DeleteDateColumn cover created and updated tracking along with soft deletes. When you pass an entity class as a value, type it as EntityClassType rather than Function or any. And when starting a model, scaffold with entity:create and trim the columns you don’t need; that’s easier than building one up from a blank file.

CLI command

Scaffold an entity class and its test file with the generator. It writes the class under modules/<module>/src/entities/<Name>Entity.ts, a spec under modules/<module>/tests/entities/<Name>Entity.spec.ts, and registers the class in the module’s entities array.
The generated entity comes pre-populated with common columns (locking, blocking, visibility, locale, and audit timestamps) ready for you to keep, adjust, or remove:
See entity:create for the full command reference.

Use with Claude and Codex

The generator ships a matching entity:create skill. It runs the scaffold and then guides your AI agent through completing the entity: adding the columns and relations the model needs, removing the scaffolded ones that don’t apply, and finishing the test file. Initialize the skills once for your agent:
Then ask Claude in natural language. It maps the request to the generator, runs it, and fills in the implementation:
Prompt
For example, the prompt above maps to entity:create --name=User, then adds email and name columns and trims the scaffolded ones.