npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@a_jackie_z/typeorm

v1.0.8

Published

A TypeORM wrapper with handy utilities for easier database management.

Readme

@a_jackie_z/typeorm

A TypeORM wrapper with handy utilities for easier database management.

Installation

npm install @a_jackie_z/typeorm reflect-metadata

Quick Start (30 seconds)

1. Set environment variables:

export DB_TYPE=postgres
export DB_POSTGRES_HOST=localhost
export DB_POSTGRES_PORT=5432
export DB_POSTGRES_USERNAME=postgres
export DB_POSTGRES_PASSWORD=yourpassword
export DB_POSTGRES_DATABASE=mydb

2. Connect to database:

import 'reflect-metadata'
import { createOrm } from '@a_jackie_z/typeorm'

const dataSource = createOrm()
await dataSource.initialize()
// ✓ Connected!

That's it! You're connected and ready to use TypeORM.

Basic Usage

Define an Entity

import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn } from '@a_jackie_z/typeorm'

@Entity('user')
export class User {
  @PrimaryGeneratedColumn()
  id!: number

  @Column()
  email!: string

  @Column()
  name!: string

  @CreateDateColumn()
  createdAt!: Date
}

CRUD Operations

import { createOrm } from '@a_jackie_z/typeorm'
import { User } from './entities/User.js'

const dataSource = createOrm({
  entities: [User],
  synchronize: true, // Only for development!
})

await dataSource.initialize()

const userRepo = dataSource.getRepository(User)

// Create
const user = userRepo.create({ email: '[email protected]', name: 'John' })
await userRepo.save(user)

// Read
const users = await userRepo.find()
const john = await userRepo.findOneBy({ email: '[email protected]' })

// Update
john.name = 'John Doe'
await userRepo.save(john)

// Delete
await userRepo.remove(john)

Environment Variables

PostgreSQL (Recommended)

DB_TYPE=postgres
DB_POSTGRES_HOST=localhost
DB_POSTGRES_PORT=5432
DB_POSTGRES_USERNAME=postgres
DB_POSTGRES_PASSWORD=yourpassword
DB_POSTGRES_DATABASE=mydb
DB_POSTGRES_LOGGING=false  # optional

MySQL / MariaDB

DB_TYPE=mysql  # or mariadb
DB_MYSQL_HOST=localhost
DB_MYSQL_PORT=3306
DB_MYSQL_USERNAME=root
DB_MYSQL_PASSWORD=yourpassword
DB_MYSQL_DATABASE=mydb
DB_MYSQL_LOGGING=false  # optional

SQLite (Default)

DB_TYPE=sqlite
DB_SQLITE_DATABASE=./data.db  # or :memory:
DB_SQLITE_LOGGING=false  # optional

If no DB_TYPE is set, SQLite with in-memory database is used by default.

Real-World Example

Production-ready setup with migrations and error handling:

import 'reflect-metadata'
import { logger } from '@a_jackie_z/logger'
import { createOrm, DataSource } from '@a_jackie_z/typeorm'
import { User } from './entities/User.js'
import { CreateUserTable1234567890 } from './migrations/1234567890-CreateUserTable.js'

export let dataSource: DataSource

try {
  dataSource = createOrm({
    entities: [User],
    migrations: [CreateUserTable1234567890],
    // migrations run automatically on startup
  })

  await dataSource.initialize()
  logger.info('Database connection established')
} catch (error) {
  logger.error(error, 'Database connection error')
  process.exit(1)
}

Features

Automatic Snake Case

Property names are automatically converted to snake_case in the database:

@Entity('user')
export class User {
  @Column()
  firstName!: string  // → first_name in database

  @CreateDateColumn()
  createdAt!: Date  // → created_at in database
}

Automatic Migrations

Migrations run automatically on startup (controlled by migrationsRun: true default):

const dataSource = createOrm({
  entities: [User],
  migrations: [CreateUserTable1234567890],
  // migrationsRun: true by default
})

await dataSource.initialize()
// All pending migrations executed ✓

Query Builder

const users = await dataSource
  .getRepository(User)
  .createQueryBuilder('user')
  .where('user.email LIKE :pattern', { pattern: '%@example.com' })
  .orderBy('user.createdAt', 'DESC')
  .take(10)
  .getMany()

Transactions

await dataSource.transaction(async (manager) => {
  const user = manager.create(User, {
    email: '[email protected]',
    name: 'Jane',
  })
  await manager.save(user)
  
  // More operations in same transaction...
})

API Reference

createOrm(options?)

Creates a TypeORM DataSource with environment-based configuration.

function createOrm(options?: Partial<DataSourceOptions>): DataSource

Default Configuration:

  • logging: ['migration', 'schema', 'error']
  • migrationsRun: true (runs migrations on startup)
  • namingStrategy: SnakeNamingStrategy (camelCase → snake_case)
  • synchronize: false (use migrations instead)

Override any option:

const dataSource = createOrm({
  entities: ['./entities/**/*.entity.ts'],
  migrations: ['./migrations/**/*.ts'],
  logging: true,
  synchronize: false, // NEVER true in production
})

Configuration Schemas

Type-safe configuration schemas for custom setup:

import { createConfig } from '@a_jackie_z/config'
import { postgresSchema, mysqlSchema, sqliteSchema } from '@a_jackie_z/typeorm'

// Use with custom environment
const config = createConfig(
  postgresSchema,
  {
    type: 'DB_TYPE',
    host: 'DB_POSTGRES_HOST',
    port: 'DB_POSTGRES_PORT',
    username: 'DB_POSTGRES_USERNAME',
    password: 'DB_POSTGRES_PASSWORD',
    database: 'DB_POSTGRES_DATABASE',
  },
  process.env
)

Testing

Use in-memory SQLite for fast tests:

import { createOrm } from '@a_jackie_z/typeorm'

const testDataSource = createOrm({
  type: 'sqlite',
  database: ':memory:',
  entities: [User],
  synchronize: true,  // OK for tests
  dropSchema: true,
})

await testDataSource.initialize()
// Run tests...
await testDataSource.destroy()

TypeScript Setup

Required in tsconfig.json:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Import reflect-metadata once at your app entry point:

import 'reflect-metadata'

Best Practices

  1. ✅ Use migrations for schema changes (never synchronize: true in production)
  2. ✅ Enable migrationsRun: true for automatic migration execution
  3. ✅ Use repositories for cleaner code
  4. ✅ Handle initialization errors gracefully
  5. ✅ Use environment variables for different environments
  6. ❌ Never commit database credentials to git

Re-exported TypeORM

All TypeORM exports are available:

import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  ManyToOne,
  OneToMany,
  // ... everything from 'typeorm'
} from '@a_jackie_z/typeorm'

License

MIT

Author

Sang Lu [email protected]