Commands and Scaffold
The Harpia Framework provides a set of commands to streamline development. These commands are defined in the package.json file:
| Command | Description | 
|---|---|
start | Starts the application. | 
dev | Starts the application in development mode with hot-reloading. | 
tests | Runs tests for a specific module or directory (e.g., user/store). | 
lint | Runs lint for a specific module or file (e.g., user/controller/store). | 
g | Generates modules, files, and other scaffolding components. | 
studio | Starts Prisma Studio for database management. | 
seed | Runs database seed scripts. | 
migrate | Generates prisma client types and applies all pending database migrations. | 
deploy | Generates prisma client types and applies all pending database migrations. | 
You can run the
testscommand likebun tests userto execute all tests within theusermodule. To run tests sequentially, add the--runInBandflag, for example:bun tests user --runInBand.The
lintcommand can be used on a specific module, directory, or file. For example:
bun lint userlints the entireusermodule.bun lint user/controllerlints thecontrollerdirectory within theusermodule.bun lint user/controller/storelints a specific file.
Scaffold
Section titled “Scaffold”The Harpia Framework includes a powerful scaffolding system to help you generate commonly used application components with ease. This tool accelerates development and enforces a consistent structure across your codebase.
You can invoke the scaffolding tool using the following command:
bun gOr if you prefer, you can use the shorthand:
bun g <type>Where <type> can be one of the following:
modulecontrollertestfactoryseedtaskvalidationobserver
Examples
Section titled “Examples”Upon execution, you’ll be prompted to select what you want to generate:
? What do you want to forge? (Use arrow keys)❯ Module  Controller  Test  Factory  Seed  Task  Validation  ObserverOr you can specify the type directly:
bun g moduleModule
Section titled “Module”The Module option scaffolds a complete directory structure for a new feature or resource in your application. A typical module includes controllers, views, services, tests, and more, organized as follows:
Directoryyour-module-name
Directorycontrollers
- index.ts
 - create.ts
 - destroy.ts
 - edit.ts
 - list.ts
 - show.ts
 - store.ts
 - update.ts
 
Directorypages
Directorycreate
- page.html
 
Directoryedit
- page.html
 
Directorylist
- page.html
 
Directoryshow
- page.html
 
Directoryrepositories
- index.ts
 - create.ts
 - destroy.ts
 - list.ts
 - show.ts
 - update.ts
 
Directoryservices
- index.ts
 - create.ts
 - destroy.ts
 - list.ts
 - show.ts
 - update.ts
 
Directorytests
- .gitignore
 
Directoryvalidations
- index.ts
 - create.ts
 - update.ts
 
- your-module-name.routes.ts
 
🛠️ Note: The pages/ directory is only generated if the application is running in MODE=fullstack. If the mode is set to MODE=api, the pages/ directory will not be included.
This layout promotes modular development, making your application easier to scale and maintain by clearly separating responsibilities.
Controller
Section titled “Controller”Harpia lets you scaffold generic controller files with just one command:
bun g controllerChoose the Test option, then specify the module and test name.
Example:
✔ Module name: user✔ Controller name: genericThis creates a new file at:
modules/user/controllers/generic.ts
Harpia lets you scaffold ready-to-use test files with just one command:
bun gChoose the Test option, then specify the module and test name.
Example:
✔ What do you want to forge? Test✔ Module name: user✔ Test name: storeThis creates a new file at:
modules/user/tests/store.spec.ts
Each test file comes pre-configured with bun:test and the TestClient utility to help you get started quickly.
🔗 Learn more: Test Documentation
Factory
Section titled “Factory”The Factory option scaffolds a factory class used to generate seed data for your models.
To create a new factory, run the command:
bun gThen choose the Factory option:
? What do you want to forge? (Use arrow keys)  Module  Controller  Test❯ Factory  Seed  Task  Validation  ObserverYou’ll be prompted to enter a factory name, typically matching the model it’s for:
✔ What do you want to forge? Factory✔ Factory name (use a model name): userThis will generate a new file at:
app/database/factories/user.factory.ts
The generated file comes with a base structure like this:
import { Factory } from "app/helpers/Factory";import { User } from "..";
const UserFactory = new Factory().define(User, (faker) => {  return {    /**     * Define your model fields here using faker.js.     *     * Example:     * name: faker.person.fullName(),     */  };});
export { UserFactory }Factories include five core methods:
.create()– Creates and persists one record to the database..createMany(count)– Creates and persists multiple records..makeStubbed()– Generates one record’s data without saving it..makeStubbedMany(count)– Generates multiple records’ data without saving..merge(data)– Merges custom fields with generated data (works with all other methods).
Here’s an example of how to use a factory:
import { UserFactory } from "app/database/factories/user.factory";
await UserFactory.create();await UserFactory.createMany(2);
const user = await UserFactory.makeStubbed();const users = await UserFactory.makeStubbedMany(5);
await UserFactory.merge({ name: "John Doe" }).create();const customUser = await UserFactory.merge({ name: "John Doe" }).makeStubbed();💡 You can use factories in your tests and seeders to generate reliable and consistent mock data during development.
Seeding is the process of populating your database with initial data — useful for development, testing, or simply bootstrapping your application with some default content.
Harpia provides a powerful and flexible seeding system that integrates seamlessly with factories, allowing you to generate realistic data with ease.
You can generate seed files using the bun g command, or create them manually for full control over the data flow.
📖 Check out the full seeding guide to learn how to create, run, and structure your seed files effectively.
Tasks and Jobs
Section titled “Tasks and Jobs”Harpia supports background processing and scheduled tasks using the powerful cron library. Tasks are placed in the app/tasks directory and can be easily scaffolded using the bun g command.
Each task is a CronJob instance and runs on a schedule you define — perfect for background processing, database cleanup, notifications, and more.
📖 For a complete walkthrough, check the full guide on Tasks and Jobs.
Validation
Section titled “Validation”Harpia uses the Zod library for schema-based validation, providing a powerful and type-safe way to ensure that data conforms to expected formats before processing.
Scaffolding a Validation
Section titled “Scaffolding a Validation”You can generate a custom validation file using the bun g command:
bun gThen select the Validation option:
? What do you want to forge? (Use arrow keys)  Module  Controller  Test  Factory  Seed  Task❯ Validation  Observer
✔ Module name: user✔ Validation name: createThis will generate a new file at:
modules/user/validations/create.tsWith the following structure:
import AppError from "app/helpers/AppError";import * as z from "zod";
export const Schema = z.object({  // name: z.string().min(1).max(255),});
export type SchemaType = z.infer<typeof Schema>;
export async function create(data: SchemaType) {  try {    Schema.parse(data);  } catch (error) {    if (error instanceof z.ZodError || error instanceof AppError) {      throw error;    }
    throw AppError.E_GENERIC_ERROR("Unexpected error during validation.");  }}Default Validators on Module Creation
Section titled “Default Validators on Module Creation”When generating a new Module using bun g, Harpia automatically creates two default validation files:
create.tsupdate.ts
These files are located in:
modules/[module]/validations/They are also automatically exported through the module’s index.ts file:
import { create } from "./create";import { update } from "./update";
export const validation = {  create,  update,};This structure makes it easy to reuse validation logic consistently across your controllers or services.
💡 Tip: You can enhance your validations using Zod features like
.refine(),.superRefine(),.transform(), or schema composition for advanced use cases.
Observers
Section titled “Observers”Harpia provides a simple and powerful way to hook into Prisma lifecycle events using Observers. These let you react to model-level database operations such as create, update, delete, and more.
Observers live in the app/observers directory and are automatically registered when the application boots.
You can scaffold a new observer with:
bun gUse observers to:
- Log database activity
 - Send notifications or emails
 - Sync data with external APIs or services
 
Each observer is defined by attaching a callback to a Prisma operation on a specific model:
import { Observer } from ".";
Observer.model("User", "create", ({ data }) => {  console.log("New user created:", data);});🔗 Learn more: Observer Documentation
Authentication
Section titled “Authentication”Harpia supports secure, session-based authentication out of the box.
Use this command to scaffold the necessary files:
bun g --config session🔐 Full setup guide: Authentication Guide