Skip to content
Moost

Enterprise Patterns. Startup Speed.

Stop Fighting Your Framework.

Same app. Less boilerplate. Better focus.

NestJS 5 files
health.controller.ts
ts
@Controller()
export class HealthController {
  @Get('health')
  health() { return 'ok' }
}
health.module.ts
ts
@Module({ controllers: [HealthController] })
export class HealthModule {}
app.controller.ts
ts
@Controller()
export class AppController {
  @Get('hello/:name')
  hello(@Param('name') name: string) {
    return `Hello, ${name}!`
  }
}
app.module.ts
ts
@Module({
  imports: [HealthModule],
  controllers: [AppController],
})
export class AppModule {}
main.ts
ts
const app = await NestFactory.create(AppModule)
await app.listen(3000)
Moost 2 files
health.controller.ts
ts
@Controller()
export class HealthController {
  @Get('health')
  health() { return 'ok' }
}
main.ts
ts
@ImportController(HealthController)
class App extends Moost {
  @Get('hello/:name')
  hello(@Param('name') name: string) {
    return `Hello, ${name}!`
  }
}

const app = new App()
app.adapter(new MoostHttp()).listen(3000)
app.init()

Simplify Your DTOs.

NestJS + class-validator 2 files
create-user.dto.ts
ts
export class CreateUserDto {
  @ApiProperty({ description: 'Name', example: 'Alice', minLength: 2 })
  @IsString()
  @MinLength(2)
  @MaxLength(100)
  name: string

  @ApiProperty({ description: 'Email', example: 'a@b.com' })
  @IsEmail()
  email: string

  @ApiProperty({ description: 'Password', minLength: 8 })
  @IsString()
  @MinLength(8)
  password: string

  @ApiProperty({ description: 'Role', required: false, enum: UserRole })
  @IsOptional()
  @IsEnum(UserRole)
  role?: UserRole

  @ApiProperty({ description: 'Address', type: () => AddressDto })
  @ValidateNested()
  @Type(() => AddressDto)
  address: AddressDto
}
address.dto.ts
ts
export class AddressDto {
  @ApiProperty({ example: '123 Main St' })
  @IsString()
  street: string

  @ApiProperty({ example: 'Springfield' })
  @IsString()
  city: string

  @ApiProperty({ example: '62704' })
  @IsString()
  @Matches(/^\d{5}$/)
  zip: string
}
Moost + Atscript 1 file Learn more →
create-user.as
atscript
export interface CreateUserDto {
  @meta.example "Alice"
  @expect.minLength 2
  @expect.maxLength 100
  name: string

  @meta.example "a@b.com"
  email: string.email

  @meta.sensitive
  @expect.minLength 8
  password: string

  role?: UserRole

  address: {
    @meta.example "123 Main St"
    street: string

    @meta.example "Springfield"
    city: string

    @meta.example "62704"
    @expect.pattern /^\d{5}$/
    zip: string
  }
}
0 req/s
21-route SaaS benchmark — fastest DI framework, 10% ahead of NestJS.
See benchmarks →

One pattern. Every event type.

HTTP, WebSocket, CLI, Workflows — the same controllers, DI, and decorators everywhere.

Docs →
ts
@Controller('users')
export class UsersController {
  @Get(':id')
  find(@Param('id') id: string) {
    return this.db.findUser(id)
  }

  @Post()
  create(@Body() dto: CreateUserDto) {
    return this.db.createUser(dto)
  }
}
ts
@Controller()
export class ChatController {
  @Message('join', '/chat/:room')
  join(
    @Param('room') room: string,
    @MessageData() data: { name: string },
  ) {
    const { join, broadcast } = useWsRooms()
    join()
    broadcast('system', { text: `${data.name} joined` })
  }

  @Message('message', '/chat/:room')
  send(@MessageData() data: { text: string }) {
    const { broadcast } = useWsRooms()
    broadcast('message', data)
  }
}
ts
@Controller()
export class Commands {
  @Cli('deploy/:env')
  deploy(
    @Param('env') env: string,
    @CliOption('verbose', 'v') verbose: boolean,
  ) {
    if (verbose) console.log(`Target: ${env}`)
    return `Deploying to ${env}...`
  }
}
ts
@Injectable('FOR_EVENT')
@Controller()
export class OnboardingWf {
  @WorkflowParam('context')
  ctx!: { name: string; approved?: boolean }

  @Workflow('onboard')
  @WorkflowSchema(['validate', 'review', 'welcome'])
  entry() {}

  @Step('validate')
  validate(@WorkflowParam('input') input: { name: string }) {
    this.ctx.name = input.name
  }

  @Step('review')
  review() {
    return { inputRequired: { fields: ['approved'] } }
  }

  @Step('welcome')
  welcome() {
    return `Welcome, ${this.ctx.name}!`
  }
}

Released under the MIT License.