A powerful and flexible database seeding library for NestJS applications with support for factories, data generation using Faker.js, and CLI commands
npm install @ackplus/nest-seederA powerful and flexible database seeding library for NestJS applications with support for factories, data generation using Faker.js, and CLI commands.
- ๐ฑ CLI-Based - Simple command-line interface, no app code modifications needed
- ๐ญ Factory Pattern - Generate realistic test data with Faker.js
- ๐ Multiple ORMs - Support for TypeORM, Mongoose, and Prisma
- ๐ฆ Batch Operations - Efficient bulk data insertion
- ๐ฏ Selective Seeding - Run specific seeders by name
- ๐ฅ Refresh Mode - Drop existing data before seeding
- ๐งช Test-Friendly - Perfect for testing and development
- ๐ TypeScript - Full TypeScript support with type safety
``bash`
npm install @ackplus/nest-seeder @faker-js/fakeror
pnpm add @ackplus/nest-seeder @faker-js/fakeror
yarn add @ackplus/nest-seeder @faker-js/faker
For TypeScript config files, also install:
`bash`
npm install -D ts-node typescript
`typescript
// src/entities/user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity('users')
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column({ unique: true })
email: string;
@Column()
role: string;
}
`
`typescript
// src/factories/user.factory.ts
import { Factory } from '@ackplus/nest-seeder';
export class UserFactory {
@Factory((faker) => faker.person.fullName())
name: string;
@Factory((faker) => faker.internet.email())
email: string;
@Factory((faker) => faker.helpers.arrayElement(['admin', 'user', 'guest']))
role: string;
}
`
`typescript
// src/seeders/user.seeder.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Seeder, DataFactory } from '@ackplus/nest-seeder';
import { User } from '../entities/user.entity';
import { UserFactory } from '../factories/user.factory';
@Injectable()
export class UserSeeder implements Seeder {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository
) {}
async seed(): Promise
// Create factory instance
const factory = DataFactory.createForClass(UserFactory);
// Generate 10 users
const users = factory.generate(10);
// Save to database
await this.userRepository.save(users);
console.log('โ
Seeded 10 users');
}
async drop(): Promise
// Clear all users
await this.userRepository.delete({});
console.log('๐๏ธ Dropped all users');
}
}
`
Create seeder.config.ts in your project root:
> Note: The seeder configuration is independent and does not require importing your main AppModule.
`typescript
// seeder.config.ts
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { User } from './src/entities/user.entity';
import { UserSeeder } from './src/seeders/user.seeder';
import * as dotenv from 'dotenv';
dotenv.config();
export default {
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
type: 'postgres',
host: config.get
port: config.get
username: config.get
password: config.get
database: config.get
entities: [User],
synchronize: true,
}),
}),
TypeOrmModule.forFeature([User]),
],
seeders: [UserSeeder],
};
`
Add script to package.json:
`json`
{
"scripts": {
"seed": "node -r ts-node/register -r tsconfig-paths/register ./node_modules/@ackplus/nest-seeder/dist/cli.js -c ./seeder.config.ts"
}
}
Run it:
`bash`
npm run seed
That's it! Your database is now seeded! ๐
Since you are running the seeder via a package script, you can pass arguments using --.
`bashRun all seeders
npm run seed
$3
| Option | Alias | Description | Default |
|--------|-------|-------------|---------|
|
--config | -c | Path to configuration file | (required) |
| --refresh | -r | Drop data before seeding | false |
| --name | -n | Run specific seeder(s) | (all) |
| --dummyData | -d | Include dummy data flag | false |
| --help | -h | Show help | |$3
You can also define specific scripts for convenience:
`json
{
"scripts": {
"seed": "node -r ts-node/register -r tsconfig-paths/register ./node_modules/@ackplus/nest-seeder/dist/cli.js -c ./seeder.config.ts",
"seed:refresh": "npm run seed -- --refresh",
"seed:users": "npm run seed -- --name UserSeeder",
"seed:watch": "nodemon --watch src/seeders --ext ts --exec \"npm run seed\""
}
}
`โ๏ธ Configuration
$3
`typescript
// seeder.config.ts
import { TypeOrmModule } from '@nestjs/typeorm';
import { User, Post, Comment } from './src/entities';
import { UserSeeder, PostSeeder, CommentSeeder } from './src/seeders';export default {
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT) || 5432,
username: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || 'postgres',
database: process.env.DB_NAME || 'mydb',
entities: [User, Post, Comment],
synchronize: true,
}),
TypeOrmModule.forFeature([User, Post, Comment]),
],
seeders: [UserSeeder, PostSeeder, CommentSeeder],
};
`$3
`typescript
// seeder.config.ts
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './src/schemas/user.schema';
import { UserSeeder } from './src/seeders/user.seeder';export default {
imports: [
MongooseModule.forRoot('mongodb://localhost/mydb'),
MongooseModule.forFeature([
{ name: User.name, schema: UserSchema }
]),
],
seeders: [UserSeeder],
};
`$3
`typescript
// seeder.config.ts
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './src/entities/user.entity';
import { UserSeeder } from './src/seeders/user.seeder';export default {
imports: [
TypeOrmModule.forRoot({
type: 'sqlite',
database: 'database.sqlite',
entities: [User],
synchronize: true,
}),
TypeOrmModule.forFeature([User]),
],
seeders: [UserSeeder],
};
`๐ญ Factories
$3
`typescript
import { Factory } from '@ackplus/nest-seeder';export class UserFactory {
@Factory((faker) => faker.person.fullName())
name: string;
@Factory((faker) => faker.internet.email())
email: string;
@Factory((faker) => faker.datatype.number({ min: 18, max: 80 }))
age: number;
}
`$3
`typescript
import { DataFactory } from '@ackplus/nest-seeder';
import { UserFactory } from './user.factory';// Create factory
const factory = DataFactory.createForClass(UserFactory);
// Generate one object
const user = factory.generate(1)[0];
// Generate multiple objects
const users = factory.generate(10);
// Generate with overrides
const admin = factory.generate(1, { role: 'admin' })[0];
`$3
`typescript
import { Factory } from '@ackplus/nest-seeder';export class PostFactory {
@Factory((faker) => faker.lorem.sentence())
title: string;
@Factory((faker) => faker.lorem.paragraphs(3))
content: string;
// Will be set manually in seeder
authorId: number;
}
`๐ฑ Seeders
$3
`typescript
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Seeder, DataFactory } from '@ackplus/nest-seeder';
import { User } from '../entities/user.entity';
import { UserFactory } from '../factories/user.factory';@Injectable()
export class UserSeeder implements Seeder {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository,
) {}
async seed(): Promise {
const factory = DataFactory.createForClass(UserFactory);
const users = factory.generate(10);
await this.userRepository.save(users);
}
async drop(): Promise {
await this.userRepository.delete({});
}
}
`$3
`typescript
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Seeder, DataFactory } from '@ackplus/nest-seeder';
import { User } from '../entities/user.entity';
import { Post } from '../entities/post.entity';
import { UserFactory } from '../factories/user.factory';
import { PostFactory } from '../factories/post.factory';@Injectable()
export class PostSeeder implements Seeder {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository,
@InjectRepository(Post)
private readonly postRepository: Repository,
) {}
async seed(): Promise {
// Get existing users
const users = await this.userRepository.find();
if (users.length === 0) {
console.log('โ ๏ธ No users found. Run UserSeeder first.');
return;
}
// Create posts for each user
const postFactory = DataFactory.createForClass(PostFactory);
for (const user of users) {
// Generate 3 posts per user
const posts = postFactory.generate(3).map(post => ({
...post,
author: user,
}));
await this.postRepository.save(posts);
}
console.log(
โ
Seeded ${users.length * 3} posts);
} async drop(): Promise {
await this.postRepository.delete({});
}
}
`$3
`typescript
import { Injectable } from '@nestjs/common';
import { Seeder, SeederServiceOptions, DataFactory } from '@ackplus/nest-seeder';@Injectable()
export class UserSeeder implements Seeder {
async seed(options?: SeederServiceOptions): Promise {
const factory = DataFactory.createForClass(UserFactory);
// Seed more data if dummyData flag is set
const count = options?.dummyData ? 100 : 10;
const users = factory.generate(count);
await this.userRepository.save(users);
console.log(
โ
Seeded ${count} users);
} async drop(): Promise {
await this.userRepository.delete({});
}
}
`Run with dummy data:
`bash
nest-seed -c seeder.config.ts --dummyData
`$3
`typescript
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Seeder, DataFactory } from '@ackplus/nest-seeder';
import { User } from '../schemas/user.schema';
import { UserFactory } from '../factories/user.factory';@Injectable()
export class UserSeeder implements Seeder {
constructor(
@InjectModel(User.name)
private readonly userModel: Model,
) {}
async seed(): Promise {
const factory = DataFactory.createForClass(UserFactory);
const users = factory.generate(10);
await this.userModel.insertMany(users);
}
async drop(): Promise {
await this.userModel.deleteMany({});
}
}
`๐ฅ Advanced Examples
$3
`typescript
// seeder.config.ts
import { CustomService } from './src/services/custom.service';export default {
imports: [
TypeOrmModule.forRoot({ / ... / }),
TypeOrmModule.forFeature([User]),
],
seeders: [UserSeeder],
providers: [CustomService], // Inject custom services
};
`$3
`typescript
// seeder.config.ts
import * as dotenv from 'dotenv';
dotenv.config();const isDev = process.env.NODE_ENV === 'development';
export default {
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.DB_HOST,
database: isDev ? 'mydb_dev' : 'mydb_prod',
synchronize: isDev,
}),
TypeOrmModule.forFeature([User, Post]),
],
seeders: isDev
? [UserSeeder, PostSeeder, TestDataSeeder]
: [UserSeeder, PostSeeder],
};
`$3
`typescript
@Injectable()
export class UserSeeder implements Seeder {
async seed(): Promise {
const factory = DataFactory.createForClass(UserFactory);
const batchSize = 1000;
const totalRecords = 10000;
for (let i = 0; i < totalRecords; i += batchSize) {
const users = factory.generate(batchSize);
await this.userRepository.save(users);
console.log( โ
Seeded ${Math.min(i + batchSize, totalRecords)}/${totalRecords} users);
}
} async drop(): Promise {
await this.userRepository.delete({});
}
}
`๐ API Reference
$3
`typescript
class DataFactory {
// Create factory for a class
static createForClass(factoryClass: new () => T): DataFactory
// Generate instances
generate(count: number, override?: Partial): T[]
}
`$3
`typescript
interface Seeder {
// Seed data into database
seed(options?: SeederServiceOptions): Promise
// Drop/clear data from database
drop(options?: SeederServiceOptions): Promise
}
`$3
`typescript
// Simple factory
@Factory((faker) => faker.person.fullName())
name: string;// With options
@Factory((faker) => faker.datatype.number({ min: 1, max: 100 }))
age: number;
// Array values
@Factory((faker) => faker.helpers.arrayElement(['admin', 'user']))
role: string;
`$3
`typescript
interface SeederServiceOptions {
refresh?: boolean; // Drop before seeding
name?: string[]; // Run specific seeders
dummyData?: boolean; // Custom flag for your logic
}
``Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License.
- Built with NestJS
- Powered by Faker.js
- Inspired by database seeding patterns from Laravel and other frameworks
If you have any questions or need help:
- Open an issue on GitHub
- Check the examples directory
- Review the Quick Start Guide
---
Made with โค๏ธ for the NestJS community