# Hello, World!

> Source: https://learn-nestjs.com/hello-world/
> Part of Learn NestJS, free to read.

NestJS is a Node.js framework that gives a back end the thing Express deliberately does not: structure. Modules, dependency injection, decorators, and a strong convention for where everything goes.

That structure is why it is worth learning in 2026. A codebase where every piece has an obvious home is one you can review quickly — and reviewing is now most of the job.

## Create the project

```bash
npm i -g @nestjs/cli
nest new hello-nest
cd hello-nest && npm run start:dev
```

Open `http://localhost:3000`. You will see `Hello World!`.

## What was generated

```text
src/
  main.ts              entry point. creates the app, listens on a port.
  app.module.ts        the root module. wires everything together.
  app.controller.ts    handles HTTP requests. no business logic.
  app.service.ts       the logic. injected into the controller.
  app.controller.spec.ts
```

That four-file split is the whole mental model, and it repeats at every level of a Nest application.

## The entry point

```ts src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

`NestFactory.create` walks the module graph, constructs every provider, resolves every dependency, and hands you an application.

## The controller

```ts src/app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}
```

Two things are happening that are easy to miss:

1. `@Controller()` with no argument means this handles the root path. `@Controller('users')` would prefix every route in the class with `/users`.
2. `private readonly appService: AppService` in the constructor is **the whole dependency injection system**. You never write `new AppService()`. Nest reads the type, finds the provider, and passes it in.

## The service

```ts src/app.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}
```

`@Injectable()` marks the class as something Nest can construct and inject. Business logic lives here — not in the controller.

## The module

```ts src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

A module is a declaration of what belongs together. `controllers` handle requests; `providers` can be injected; `exports` makes a provider available to other modules that import this one.

:::tip Why the split matters more than it looks
Controllers should parse and serialise. Services should hold logic. Keeping that boundary means your logic is testable without HTTP, and it means an agent asked to "add validation" has an obvious place to put it. Blurring it is the single most common way a Nest codebase goes bad.
:::

## Add a route

```ts src/app.controller.ts
@Get('health')
health(): { status: string; at: string } {
  return { status: 'ok', at: new Date().toISOString() };
}
```

`http://localhost:3000/health` now returns JSON. Nest serialises objects automatically and sets the content type.

## Common questions

### Is NestJS just Angular for the back end?

The decorator syntax and the dependency injection are deliberately Angular-like, and that is where the resemblance ends. Nest runs on Express or Fastify underneath and is a server framework throughout.

### Do I need to know Express?

No, but it helps when you need to drop down a level. Nest exposes the underlying request and response objects when you ask for them, and most Express middleware works unchanged.

### Express or Fastify?

Express is the default and has the larger middleware ecosystem. Fastify is faster and the adapter is a one-line change. Start on Express; switch if benchmarks ever tell you to.
