RiserBob logoRiserBobv1.0.0
HomeDocsCLIRelease notes

Getting started

  • Introduction
  • Installation
  • Quick start
  • Project structure

Core concepts

  • Routing
  • Request
  • Responses
  • Error handling

Middleware

  • Middleware
  • Authentication
  • Logger and CORS

Data

  • Validation

Structure and tooling

  • Modules
  • CLI

Examples

  • Build a project
  • Mongoose
  • Drizzle ORM
  • Sequelize
  • JWT and cookies
  • File uploads

Packages

  • Cookies

Resources

  • Troubleshooting
  • Release notes
  • License
  • Security
  • Contributing
Getting started

Project structure

How a project created with bun create riser-bob is organised.

A new project is organised by feature. Each feature lives in its own folder under src/modules/, and src/index.ts only wires things together.

Output
my-app/  package.json  tsconfig.json  src/    index.ts    modules/      users/        users.module.ts        users.controller.ts        users.route.ts      rules/        create.ts        update.ts      schemas/        user.schema.ts

What each file does

FileRole
src/index.tsCreates the app, registers modules and starts the server on port 4000.
users.module.tsWires the controller, the auth middleware and the router together, then registers the feature.
users.controller.tsHolds the handlers: create, findAll, findOne, update, delete, plus verifyToken. Every body is a TODO for you to fill in.
users.route.tsMaps paths to handlers and decides which routes are protected.
rules/create.ts and rules/update.tsValidation rules for each action, written as a ValidationSchema. update.ts starts as a copy of the create rule.
schemas/user.schema.tsAn empty file, reserved for the shape of your data. Fill it with the schema of the database layer you choose.

The entry file

src/index.ts
import { RiserBob } from "riser-bob";import { UsersModule } from "./modules/users/users.module"; async function bootstrap() {  const bob = new RiserBob();   bob.spongGet("/", (spongReq, spongRes) => {    return spongRes.send("Welcome to RiserBob APIs");  });   new UsersModule().register(bob);   bob.spongListen(4000, () => {    console.log("🧽 RiserBob is running at http://localhost:4000 🍍");  });} bootstrap().catch((error: unknown) => {  console.error("[RiserBob] Failed to start application:", error);  process.exit(1);});

The bootstrap function is async on purpose: it is the place to connect to a database before the server starts listening. If anything fails, the error is logged and the process exits with code 1.

Add middleware such as loggerMiddleware or corsMiddleware right after new RiserBob(), before any route is registered. See Middleware.

How a bigger project grows

As features multiply, move the rules and the schema into the module that owns them and add folders for shared code. This is the layout of a complete app with authentication, a database and file uploads:

Output
src/  index.ts  config/    database/connect-db.ts    token/token.ts    cloudinary/cloudinary-config.ts    cloudinary/cloudinary.ts  middlewares/    admin.middleware.ts  utils/    plugins/uuid.plugin.ts  modules/    auth/      auth.module.ts      auth.route.ts      auth.controller.ts      rules/login.rule.ts      rules/register.rule.ts    users/      users.module.ts      users.route.ts      users.controller.ts      rules/create.rule.ts      rules/update.rule.ts      schemas/user.schema.ts    tasks/      ...    profiles/      ...

Read Modules to see what is inside each file, CLI to generate new ones, and Build a project to build this layout step by step.

PreviousQuick startNextRouting

On this page

  • What each file does
  • The entry file
  • How a bigger project grows