Lil ORM is a lightweight and flexible ORM for Node.js, designed with a clear and intuitive API to simplify database operations. Engineered for adaptability, it enables efficient interaction with databases.
npm install lil-orm!ORM
While Lil ORM is primarily intended as a learning resource and experimental project, its lean design and user-friendly approach make it a noteworthy tool for those looking to understand the nuances of building APIs without the complexity that often accompanies larger ORMs.
Please note: Lil ORM is currently not recommended for use in production environments (yet), but rather as a learning tool and sandbox for testing and development purposes
⚠️ API are subjected to change ⚠️
jsonEquals and jsonContains.OnInsert and OnUpdate hooks for custom logic during data operations.SELECT clauses.``shell`
npm i lil-orm pg`shell`
npm i lil-orm sqlite3
`shell`
yarn add lil-orm pg
yarn add lil-orm sqlite3
typescript
@Entity('user')
class UserEntity {
@PrimaryKey({
autoIncrement: true,
})
@Column({
type: 'integer',
name: 'id',
})
id: number; @Column({
type: 'text',
name: 'name',
})
name: string;
@Column({
type: 'text',
name: 'email',
})
email: string;
@Column({
type: 'json',
name: 'config',
})
config: any;
@Column({
type: 'boolean',
name: 'is_active',
})
isActive: boolean;
@Column({
type: "date",
name: "created_at",
})
@OnInsert(() => new Date())
createdAt: Date;
@Column({
type: "date",
name: "updated_at",
})
@OnInsert(() => new Date())
@OnUpdate(() => new Date())
updatedAt: Date;
}
`
⚠️ Warning: Important Configuration RequiredTo ensure proper functioning of the library, please make sure to configure your TypeScript project correctly.
`json
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
`Other configurations
Option 1: Enable
useDefineForClassFieldsIn your project's
tsconfig.json, add or modify the compilerOptions section to include the following:`json
{
"compilerOptions": {
"useDefineForClassFields": true
}
}
`
Option 2: Initialize Every Property with Default ValuesIf you cannot enable
useDefineForClassFields or prefer not to modify your TypeScript configuration, make sure to explicitly initialize every property in your entity class with a default value.For example:
`typescript
@Entity('tableName')
class MyEntity {
@PrimaryKey({
autoIncrement: true,
})
@Column({
type: 'INTEGER'
})
id: number = 0;
@Column({
type: 'TEXT'
})
name: string = '';
// ...other properties
}
`Module Setup
`typescript
import { LilORM } from 'lil-orm';const databaseConnectionString = ':memory:';
const module = new LilORM(databaseConnectionString);
`Create Table
(experimental API name)
`typescript
module.createTable(UserEntity) //to create a table from an entity
`CRUD Operations
`typescript
//get repository
const repository = module.getRepository(UserEntity);//Insert
const userEntity = new UserEntity();
userEntity.id = 1;
userEntity.name = 'test';
userEntity.email = 'test@example.com';
userEntity.isActive = false;
userEntity.age = 42;
userEntity.config = null;
userEntity.createdAt = new Date();
await repository.insert(userEntity);
//Find by id
const users = await repository.retrieve(qb => qb.where('id').equals(1));
//Update
userEntity.name = 'updated';
await repository.update(userEntity, qb => qb.where('id').equals(1));
//Delete
await repository.delete({ id: 69 });
`Custom query with query builder
`typescript
let user: any[] = lilOrm.retrieve(
qb => qb.forEntity(UserEntity)
.where('isActive').equals(true)
.and('age').greaterThan(18)
.or('config').equals({ allowed: true })
.finalize(),
(data) => data)
`@OnInsert and @OnUpdate Hooks@OnInsertExecutes custom logic before a new entity is saved. Commonly used to set creation timestamps.
`typescript
@Column({ type: "date", name: "created_at" })
@OnInsert(() => new Date())
createdAt: Date;
`@OnUpdateTriggered automatically before an existing entity is updated. Typically used for updating modification timestamps.
`typescript
@Column({ type: "date", name: "updated_at" })
@OnUpdate(() => new Date())
updatedAt: Date;
`Debugging with
enableDebugModeTo assist in debugging and optimizing your SQL queries, you can enable a debug mode on your ORM repository instances. This mode logs the last SQL query executed, allowing you to review the raw SQL sent to the database.
$3
`typescript
const repository = lilOrm.getRepository(UserEntity);
repository.enableDebugMode();
console.log(repository.debugSQLQuery);
``Debug mode is intended for development and debugging purposes. Ensure it is disabled in production environments to avoid performance overhead and potential security risks.