# 1. Hello World, with a real entry point

We will build tic-tac-toe: two authenticated players, one shared board, and a server that decides whether each move is legal. Start with a page, not the whole game.

Download the complete project below, extract it into a new directory, then run:

```sh
npm ci
npm run hello
```

Use Node 22.13 or newer. Visit **http://localhost:8181**. You should see “Hello world!”. Stop this checkpoint with Ctrl+C before running the next one.


```tsx
import { defineApp, page } from 'redweb';

@page('/', { live: false })
class HomePage {
    render() { return <h1>Hello world!</h1>; }
}

const app = defineApp({ pages: [HomePage] });

await app.run();
```


`@page('/')` connects a class to a URL. `render()` returns TSX, which Redweb turns into HTML on the server. `live: false` means this page needs no live socket. `defineApp` gathers the application's parts; `run()` opens the listener.

Think of the page class as a recipe for a document. The browser receives the baked document, not a React application or the server's TypeScript.

## Why the entry point is so small

This project's `package.json` contains `"type": "module"`. Its compiler configuration extends `redweb/tsconfig.json`. That combination enables Redweb JSX, decorators, and top-level `await`:


```json
{
  "extends": "redweb/tsconfig.json",
  "compilerOptions": { "rootDir": "src", "outDir": "dist", "sourceMap": true },
  "include": ["src/**/*.ts", "src/**/*.tsx"]
}
```


You can still handle Promise failures as usual. The introduction does not need to demonstrate every error-handling or deployment option at once. The downloaded README explains port selection, template roots, signals, and the more configurable game factory used by tests.

**Checkpoint:** the page renders through an actual Node HTTP listener, with no browser framework. To add another page later, declare another decorated class and pass `pages: [HomePage, AboutPage]`.
