AponiaJSDocs
Compare

AponiaJS vs NestJS

NestJS is a mature, platform-agnostic Node framework with a complete request pipeline. AponiaJS reuses its vocabulary on Bun with a much smaller feature set.

NestJS is the reference point for this project, so the honest comparison is mostly a list of what NestJS has and AponiaJS does not.

At a glance

Runtime

AponiaJS 0.6.0-alpha.18

Partial. Bun only

NestJS

Yes. Node, and Bun in practice

HTTP platform

AponiaJS 0.6.0-alpha.18

Partial. Elysia only

NestJS

Yes. Express or Fastify adapter

Maturity

AponiaJS 0.6.0-alpha.18

No. Alpha, API changes between releases

NestJS

Yes. Stable, years of production use

Modules and imports

AponiaJS 0.6.0-alpha.18

Yes. Implemented

NestJS

Yes. Implemented

Constructor injection

AponiaJS 0.6.0-alpha.18

Partial. Implemented, singleton only

NestJS

Yes. Request and transient scopes too

Controllers and decorators

AponiaJS 0.6.0-alpha.18

Yes. All seven methods, whole and named parameters

NestJS

Yes. Implemented

Validation

AponiaJS 0.6.0-alpha.18

Yes. Route schemas and @Validation() models

NestJS

Yes. ValidationPipe with class-validator

Guards, interceptors, pipes, filters

AponiaJS 0.6.0-alpha.18

No. Not implemented

NestJS

Yes. Implemented

Lifecycle hooks

AponiaJS 0.6.0-alpha.18

No. Not implemented

NestJS

Yes. OnModuleInit, OnApplicationShutdown, others

Testing module and overrides

AponiaJS 0.6.0-alpha.18

No. Not implemented

NestJS

Yes. Implemented

OpenAPI, microservices, GraphQL, queues

AponiaJS 0.6.0-alpha.18

No. Not implemented

NestJS

Yes. First-party packages

Typed HTTP client

AponiaJS 0.6.0-alpha.18

Partial. Eden Treaty from native routes

NestJS

Partial. Generated from OpenAPI, or manual

The code looks familiar

import { Body, Controller, Get, Injectable, Module, Param, Post } from "@aponiajs/common";
import { AponiaFactory } from "@aponiajs/platform-elysia";

@Injectable()
class UserService {
  findOne(id: string) {
    return { id };
  }
}

@Controller("users")
class UserController {
  constructor(private readonly users: UserService) {}

  @Get(":id")
  findOne(@Param("id") id: string) {
    return this.users.findOne(id);
  }
}

@Module({ controllers: [UserController], providers: [UserService] })
class AppModule {}

const app = await AponiaFactory.create(AppModule);
await app.listen(3000);

Anyone who has written NestJS can read that. The differences start one layer down.

@Injectable() carries less meaning

In AponiaJS the decorator exists so TypeScript emits constructor parameter types for the container. It does not attach scope metadata, because there are no scopes — every provider is a singleton constructed once at startup. See providers.

Validation is a schema, not a pipe

There is no ValidationPipe, no class-validator, and no class-transformer. A schema goes on the route decorator and a rejected request is answered before the handler runs:

const createUser = { body: z.object({ name: z.string().min(2) }) };

@Post("/", createUser)
create(@Body() body: z.infer<(typeof createUser)["body"]>) {
  return body;
}

Any Standard Schema validator works — Zod, ArkType, Valibot — alongside TypeBox and Elysia's t. Details in validation.

There is no request pipeline to hook into

This is the largest gap. NestJS gives you four extension points around a handler; AponiaJS gives you none of them yet. Cross-cutting behaviour is written as Elysia hooks instead, through native access or a plugin module. That works, but it is Elysia's model, not Nest's, and it does not participate in the module graph.

Errors are Problem Details

httpErrors.notFound("...") produces an RFC 9457 body with type, title, status, and detail. NestJS produces its own shape from HttpException. See errors.

Which one to pick

Choose NestJS when

  • you are shipping to production;
  • you need guards, interceptors, pipes, or exception filters;
  • you deploy to Node, or to a platform that does not run Bun;
  • you want OpenAPI documents generated from decorators;
  • you need microservices, GraphQL, queues, scheduling, or caching packages;
  • you want a testing module with provider overrides;
  • you are hiring, and Nest experience is a common line on a CV.

Choose AponiaJS when

  • Bun is already the runtime and Elysia is already the server;
  • module boundaries and constructor injection are what you miss from Nest, not the request pipeline;
  • you want Eden Treaty end-to-end types rather than a generated OpenAPI client;
  • alpha software is acceptable for this codebase.

Porting an existing Nest application

From NestJS has the concept-by-concept mapping, and current limitations lists every runtime feature that is still missing.

Frequently asked questions

Can I run NestJS on Bun instead of using AponiaJS?
Often yes. NestJS runs on Bun for many applications, and if your code depends on guards, interceptors, exception filters, provider scopes, or the testing module, that is the right path — AponiaJS does not implement any of them. AponiaJS is worth considering when you want the Elysia request engine and Eden Treaty types underneath a Nest-shaped codebase.
Is AponiaJS a fork of NestJS?
No. It is an independent implementation that borrows naming so the concepts transfer. There is no shared code, no platform adapter abstraction, and no compatibility guarantee with Nest packages.
Do NestJS decorators work in AponiaJS?
The names match but the packages do not. Import decorators from "@aponiajs/common" and the factory from "@aponiajs/platform-elysia". Nest packages such as @nestjs/common are not compatible.

On this page