A typescript framework using Bun runtime.
Docs : bejibun.com
X : @bjbnframework
CA : CQhbNnCGKfDaKXt8uE61i5DrBYJV7NPsCDD9vQgypump
- Bun - Runtime
- Knex - Migrations & Seeders
- Objection - Model
- Vine - Validator
- Luxon - Date and Time
- React - Homepage only
If you don't have bun installed :
# Linux / Mac OS
curl -fsSL https://bun.sh/install | bash
# Windows
powershell -c "irm bun.sh/install.ps1 | iex"Setup the project.
bunx @bejibun/cli your-projectTo see list of available commands, run.
bun ace
bun ace help
bun ace --h
bun ace --helpTo see help of specific command, run :
bun ace help migrate:latest
bun ace migrate:latest --h
bun ace migrate:latest --helpTo fresh or drop all table and re-run the migrations, run :
bun ace migrate:freshExample :
This will DROP ALL tables and re-run ALL migrations. Are you want to continue? (Y/N): Y
✔ Rolled back all migrations
✔ Batch 1 finished
✔ 20250929_000001_tests.tsTo migrate the migrations, run :
bun ace migrate:latestExample :
✔ Batch 1 finished
✔ 20250929_000001_tests.tsTo rollback the migrations, run :
bun ace migrate:rollbackExample :
This will ROLLBACK latest migrations. Are you want to continue? (Y/N): Y
✔ Batch 1 finished
✔ 20250929_000001_tests.tsTo see migrations status, run :
bun ace migrate:statusExample :
✔ Completed Migrations :
✔ No migrations were completed.
✔ Pending Migrations :
✔ 20250929_000001_tests.tsTo execute seeder, run :
bun ace db:seedExample :
✔ Seeding finished
✔ 20250929_000001_seeder_test.tsTo run the project, run :
# Development Mode
bun dev
# Production Mode
bun startLogical processes
Example :
import BaseController from "@bejibun/core/bases/BaseController";
export default class HelloController extends BaseController {
public async hello(request: Bun.BunRequest): Promise<Response> {
return super.response.setData({
message: "Hello, world!",
method: request.method
}).send();
}
}Handle any incoming errors
Example :
import ExceptionHandler from "@bejibun/core/exceptions/ExceptionHandler";
export default class Handler extends ExceptionHandler {
public handle(error: any): globalThis.Response {
// Your code goes here
return super.handle(error);
}
}Handle any request before forwarding to controller
Example :
import type {HandlerType} from "@bejibun/core/types";
import Logger from "@bejibun/logger";
export default class TestMiddleware {
public handle(handler: HandlerType): HandlerType {
return async (request: Bun.BunRequest) => {
Logger.setContext("TestMiddleware").debug(request.url);
return handler(request);
};
}
}Usage :
import Router from "@bejibun/core/facades/Router";
import YourController from "@/app/controllers/YourController";
import TestMiddleware from "@/app/middlewares/TestMiddleware";
import LoggerMiddleware from "@/app/middlewares/LoggerMiddleware";
export default Router.prefix("test")
.middleware(
new TestMiddleware(),
new LoggerMiddleware()
)
.group([
Router.get("redis", "TestController@redis"),
Router.get("get", "TestController@get"),
Router.get("detail/:id", "TestController@detail"),
Router.post("add", "TestController@add"),
Router.post("edit", "TestController@edit"),
Router.delete("delete/:id", "TestController@delete"),
Router.get("restore/:id", "TestController@restore"),
Router.resource("path", YourController),
Router.resource("path", YourController, {
only: ["index", "store"] // "index" | "store" | "show" | "update" | "destroy"
}),
Router.resource("path", YourController, {
except: ["index", "store"] // "index" | "store" | "show" | "update" | "destroy"
})
]);Validate any incoming requests
Example :
import type {ValidatorType} from "@bejibun/core/types/ValidatorType";
import BaseValidator from "@bejibun/core/bases/BaseValidator";
import TestModel from "@/app/models/TestModel";
export default class TestValidator extends BaseValidator {
public static get detail(): ValidatorType {
return super.validator.compile(
super.validator.object({
id: super.validator.number().min(1).exists(TestModel, "id")
})
);
}
public static get add(): ValidatorType {
return super.validator.compile(
super.validator.object({
name: super.validator.string()
})
);
}
public static get edit(): ValidatorType {
return super.validator.compile(
super.validator.object({
id: super.validator.number().min(1).exists(TestModel, "id"),
name: super.validator.string()
})
);
}
public static get delete(): ValidatorType {
return super.validator.compile(
super.validator.object({
id: super.validator.number().min(1).exists(TestModel, "id")
})
);
}
public static get restore(): ValidatorType {
return super.validator.compile(
super.validator.object({
id: super.validator.number().min(1).exists(TestModel, "id", true)
})
);
}
}Usage :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";
export default class TestController extends BaseController {
public async detail(request: Bun.BunRequest): Promise<Response> {
const body = await super.parse(request);
await super.validate(TestValidator.detail, body);
const test = await TestModel.findOrFail(body.id as number | string);
return super.response.setData(test).send();
}
}Database table model
Example :
import BaseModel, {BaseColumns} from "@bejibun/core/bases/BaseModel";
import {DateTime} from "luxon";
export interface TestColumns extends BaseColumns {
name: string;
}
export default class TestModel extends BaseModel implements TestColumns {
public static tableName: string = "tests";
public static idColumn: string = "id";
declare id: bigint;
declare name: string;
declare created_at: DateTime | string;
declare updated_at: DateTime | string;
declare deleted_at: DateTime | string | null;
}Example :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
export default class TestController extends BaseController {
public async get(request: Bun.BunRequest): Promise<Response> {
const tests = await TestModel.all();
return super.response.setData(tests).send();
}
}Example :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";
export default class TestController extends BaseController {
public async detail(request: Bun.BunRequest): Promise<Response> {
const body = await super.parse(request);
await super.validate(TestValidator.detail, body);
const test = await TestModel.findOrFail(body.id as number | string);
return super.response.setData(test).send();
}
}Example :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";
export default class TestController extends BaseController {
public async add(request: Bun.BunRequest): Promise<Response> {
const body = await super.parse(request);
await super.validate(TestValidator.add, body);
const tests = await TestModel.create({
name: body.name as string
});
return super.response.setData(tests).send();
}
}Example :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";
export default class TestController extends BaseController {
public async edit(request: Bun.BunRequest): Promise<Response> {
const body = await super.parse(request);
await super.validate(TestValidator.edit, body);
const tests = await TestModel.find(body.id as number | string)
.update({
name: body.name as string
});
return super.response.setData(tests).send();
}
}Example :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";
export default class TestController extends BaseController {
public async delete(request: Bun.BunRequest): Promise<Response> {
const body = await super.parse(request);
await super.validate(TestValidator.delete, body);
const tests = await TestModel.find(body.id as number | string).delete();
return super.response.setData(tests).send();
}
}Example :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";
export default class TestController extends BaseController {
public async delete(request: Bun.BunRequest): Promise<Response> {
const body = await super.parse(request);
await super.validate(TestValidator.delete, body);
const tests = await TestModel.find(body.id as number | string).forceDelete();
return super.response.setData(tests).send();
}
}Example :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
export default class TestController extends BaseController {
public async get(request: Bun.BunRequest): Promise<Response> {
const tests = await TestModel.withTrashed();
return super.response.setData(tests).send();
}
}Example :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
export default class TestController extends BaseController {
public async get(request: Bun.BunRequest): Promise<Response> {
const tests = await TestModel.onlyTrashed();
return super.response.setData(tests).send();
}
}Example :
import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
export default class TestController extends BaseController {
public async restore(request: Bun.BunRequest): Promise<Response> {
const body = await super.parse(request);
await super.validate(TestValidator.restore, body);
const tests = await TestModel.find(body.id as number | string).restore();
return super.response.setData(tests).send();
}
}Example :
import type {Knex} from "knex";
import TestModel from "@/app/models/TestModel";
export function up(knex: Knex): void {
return knex.schema.createTable(TestModel.table, (table: Knex.TableBuilder) => {
table.bigIncrements("id");
table.string("name");
table.timestamps(true, true);
table.timestamp("deleted_at");
});
}
export function down(knex: Knex): void {
return knex.schema.dropTable(TestModel.table);
}Example :
import type {Knex} from "knex";
import TestModel from "@/app/models/TestModel";
export async function seed(knex: Knex): Promise<void> {
for (const name of ["Name 1", "Name 2", "Name 3"]) {
await TestModel.query(knex).insert({
name: name
});
}
}For public assets and Frontend use.
Currently, used for frontend initiation.
Any startup loads
Currently, only load from core package.
Example :
import "@bejibun/core/bootstrap";A filesystem facade, with built-in disk management including disks configuration and build disk at runtime.
- Standard Use
import Storage from "@bejibun/core/facades/Storage";
await Storage.exists("path/to/your/file.ext"); // Check if the file exists
await Storage.missing("path/to/your/file.ext"); // Check if the file doesn't exists
await Storage.get("path/to/your/file.ext"); // Get data content
await Storage.put("path/to/your/file.ext", "content"); // Store content to file
await Storage.delete("path/to/your/file.ext"); // Delete file- With Specified Disk
import Storage from "@bejibun/core/facades/Storage";
await Storage.disk("public").exists("path/to/your/file.ext");
await Storage.disk("public").missing("path/to/your/file.ext");
await Storage.disk("public").get("path/to/your/file.ext");
await Storage.disk("public").put("path/to/your/file.ext", "content");
await Storage.disk("public").delete("path/to/your/file.ext");- New Disk at Runtime
import Storage from "@bejibun/core/facades/Storage";
await Storage.build({
driver: "local", // "local" | DiskDriverEnum.Local
root: App.Path.storagePath("custom")
}).exists("path/to/your/file.ext");
await Storage.build({
driver: "local",
root: App.Path.storagePath("custom")
}).missing("path/to/your/file.ext");
await Storage.build({
driver: "local",
root: App.Path.storagePath("custom")
}).get("path/to/your/file.ext");
await Storage.build({
driver: "local",
root: App.Path.storagePath("custom")
}).put("path/to/your/file.ext", "content");
await Storage.build({
driver: "local",
root: App.Path.storagePath("custom")
}).delete("path/to/your/file.ext");Documentation : @bejibun/redis
Documentation : @bejibun/cors
Documentation : @bejibun/cache
Any commands for development
Usage: ace [options] [command]
Ace for your commander
Author: Havea Crenata <havea.crenata@gmail.com>
Options:
-v, --version Show the current version
-h, --help display help for command
Commands:
db:seed Run database seeders
hello:world Run hello world
install <packages...> Install package dependencies
maintenance:down [options] Turn app into maintenance mode
maintenance:up Turn app into live mode
make:command <file> Create a new command file
make:controller <file> Create a new controller file
make:middleware <file> Create a new middleware file
make:migration <file> Create a new migration file
make:model <file> Create a new model file
make:seeder <file> Create a new seeder file
make:validator <file> Create a new validator file
migrate:fresh [options] Rollback all migrations and re-run migrations
migrate:latest Run latest migration
migrate:rollback [options] Rollback the latest migrations
migrate:status [options] List migrations status
package:configure [options] Configure package after installation
help [command] display help for command
Examples:
$ bun ace --help
$ bun ace --version
$ bun ace migrate:latest- Installation CLI
bunx @bejibun/cli your-project - Controller
- Exception Handler
- Middleware
- Database
- Model
- Migration
- Seeder
- Validator
- Vine as Base Validator
- Vine with Database
-
.exists() -
.unique()
-
- Command
- External package can add Command
- Scaffolding
-
make:command -
make:controller -
make:middleware -
make:model -
make:validator
-
- Database
-
db:seed -
migrate:fresh -
migrate:latest -
migrate:rollback -
migrate:status
-
- Maintenance
-
maintenance:down -
maintenance:up
-
- Package
-
install <packages...> -
package:configure --package=...
-
- Routing
- Response
- Rate Limiter
- Cors (@bejibun/cors)
- Logger
- Redis (@bejibun/redis)
- Cache (@bejibun/cache)
- Expire Time
- Redis
- File Scheme
- x402 Protocol (@bejibun/x402)
- Storage
- Local
- Command
-
make:job
-
- Authentication
- Unit Test
- Mail Service
- Provider
- Sendgrid
- Mailjet
- Template
- Edge / Anything html with flexible params
- Provider
- Job Dispatch / Background Tasks
- Scheduler / Cronjob
- Command
-
scheduler:run
-
- Command
- Database Transaction
- Cache
- Memcached
- Storage
- S3 Read Docs
- Build own ORM based on Bun SQL
- Web3 ? We'll work on this after the framework stable
- Share your idea to Havea Crenata
- CSRF/XSS Protection
- Import Excel
- Export Excel
- Export PDF
If you find this project helpful and want to support it, you can donate via crypto :
| EVM | Solana |
|---|---|
![]() |
![]() |
| 0xdABe8750061410D35cE52EB2a418c8cB004788B3 | GAnoyvy9p3QFyxikWDh9hA3fmSk2uiPLNWyQ579cckMn |
Or you can buy this $BJBN (Bejibun) tokens here, beware of bots.


