A lightweight, TypeScript-first ORM for Node.js built on MySQL. Inspired by Laravel's Eloquent and Mongoose, Haki ORM brings modern, intuitive database interactions to SQL while keeping your workflow simple and type-safe.
- Works naturally with TypeScript types for safe queries
- Provides am active record & repostiory pattern
- Fluent query builder similar to NoSQL API (mongoose, firebase)
- Built-in transactions, soft deletes, pagination, caching and job scheduling
- Optimized for performance monitoring and large scale operations
- Designed for developer productivity, not just RAW SQL
- Active Record Pattern: Intuitive model-based data manipulation
- Query Builder: Fluent, chainable query interface
- Transactions: ACID-compliant transaction support
- Connections: Efficient connection pooling
- Repository Pattern: Clean data access layer
- Data Generation: Test data creation
- Performance Monitoring: Track operation performance
npm install @haki-orm/mysql mysql2
import { Connection, Model } from './orm-library';
const connection = new Connection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'myapp',
connectionLimit: 10
});
await connection.connect();
Model.setConnection(connection);class User extends Model {
static tableName = 'users';
static fillable = ['name', 'email', 'age'];
static hidden = ['password'];
}
class Post extends Model {
static tableName = 'posts';
static fillable = ['title', 'content', 'user_id'];
}// Create
const user = await User.create({
name: 'John Doe',
email: 'john@example.com',
age: 30
});
// Read
const foundUser = await User.find(1);
const allUsers = await User.all();
const admins = await User.where('role', '=', 'admin');
// Update
await user.update({ age: 31 });
// Delete
await user.delete();Build complex queries with a fluent interface:
const posts = await Post.query()
.select('posts.*', 'users.name as author')
.join('users', 'posts.user_id', '=', 'users.id')
.where('posts.published', '=', true)
.where('posts.views', '>', 100)
.orderBy('posts.created_at', 'DESC')
.limit(10)
.get();Ensure data integrity with transactions:
await Transaction.run(connection, async (trx) => {
await trx.execute(
'INSERT INTO users (name) VALUES (?)',
['John']
);
await trx.execute(
'INSERT INTO profiles (user_id) VALUES (?)',
[1]
);
});Clean separation of data access logic:
const userRepo = new Repository(User);
const user = await userRepo.findBy('email', 'john@example.com');
const users = await userRepo.findMany([1, 2, 3]);
const latest = await userRepo.latest('created_at', 5);
await userRepo.chunk(100, async (users) => {
// Process 100 users at a time
});const user = DataGenerator.generateUser();
const users = DataGenerator.generateUsers(100);
const products = DataGenerator.generateProducts(50);
const email = DataGenerator.randomEmail();
const name = DataGenerator.randomName();
const date = DataGenerator.randomDate();const monitor = new PerformanceMonitor();
await monitor.measure('fetch-users', async () => {
return await User.query().limit(100).get();
});
const stats = monitor.getStats('fetch-users');
const slowest = monitor.getSlowestOperations(5);
const report = monitor.generateReport();const connection = new Connection(config);
await connection.connect();
await connection.disconnect();
await connection.query(sql, params);
await connection.execute(sql, params);
const stats = await connection.getStats();static async all<T>(): Promise<T[]>
static async find<T>(id): Promise<T | null>
static async findBy<T>(column, value): Promise<T | null>
static async create<T>(data): Promise<T>
static async where<T>(column, operator, value): Promise<T[]>
async save(): Promise<this>
async update(data): Promise<this>
async delete(): Promise<void>
async refresh(): Promise<this>select(...columns)
where(column, operator, value)
orWhere(column, operator, value)
whereIn(column, values)
whereNull(column)
whereLike(column, pattern)
join(table, first, operator, second)
leftJoin(table, first, operator, second)
orderBy(column, direction)
groupBy(...columns)
limit(value)
offset(value)
async get()
async first()
async count()Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - feel free to use this in your projects!
Built with TypeScript and MySQL2, inspired by Laravel's Eloquent ORM.
For more examples and detailed documentation, check out the usage.ts file.