Quick Start

Build your first MiiaJS API in under a minute.
Want the fastest path? Run npx @miiajs/cli new my-app to scaffold a ready-to-run project with a controller, service, and module already wired up.

1. Create a controller

import { Controller, Get, Post, type RequestContext } from '@miiajs/core'

@Controller('/hello')
class HelloController {
  @Get('/')
  greet() {
    return { message: 'Hello, Miia!' }
  }

  @Get('/:name')
  greetUser(ctx: RequestContext) {
    return { message: `Hello, ${ctx.params.name}!` }
  }

  @Post('/')
  async echo(ctx: RequestContext) {
    const body = await ctx.json()
    return { received: body }
  }
}

2. Create a module

import { Module } from '@miiajs/core'

@Module({
  controllers: [HelloController]
})
class AppModule {}

3. Create the app and start the server

app.listen() initializes the DI container, compiles routes, and starts the server. Bun and Deno are auto-detected; for Node.js pass a server adapter:

import { Miia } from '@miiajs/core'

const app = new Miia().register(AppModule)

await app.listen(3000)
By default, Miia registers SIGTERM/SIGINT/SIGHUP handlers on listen() so Ctrl+C and container stop events trigger a graceful destroy() (closing the server, running every provider's onDestroy, exiting cleanly). See Application Lifecycle for opt-out and behavioural details.

4. Test it

curl http://localhost:3000/hello
# {"message":"Hello, Miia!"}

curl http://localhost:3000/hello/world
# {"message":"Hello, world!"}

curl -X POST http://localhost:3000/hello \
  -d '{"foo":"bar"}' \
  -H "Content-Type: application/json"
# {"received":{"foo":"bar"}}

Next steps

  • Add services with @Injectable() and inject()
  • Add validation with @ValidateBody() and any ZodLike schema
  • Add authentication with @miiajs/auth
  • Generate API docs with @miiajs/swagger