---
title: Routes
description: Static routes, index files, and how file names map to HTTP URLs in Nooh.
---

Every `.ts` file inside your `routes` directory is a route. The file's **path relative to the routes root** becomes the URL; the file's **name suffix** — the part before `.ts` — encodes the HTTP method.

## File naming convention

A route filename follows this pattern:

```
<name>.<method>.ts
```

Where `<name>` is the last segment of the URL path and `<method>` is a lowercase HTTP method. Some examples:

| File | URL | Method |
|------|-----|--------|
| `routes/index.get.ts` | `/` | `GET` |
| `routes/health.get.ts` | `/health` | `GET` |
| `routes/users/index.get.ts` | `/users` | `GET` |
| `routes/users/index.post.ts` | `/users` | `POST` |
| `routes/products/index.delete.ts` | `/products` | `DELETE` |

:::note
The name `index` is special: it maps to the root of the current directory, not a literal `/index` path. `routes/users/index.get.ts` becomes `GET /users`, not `GET /users/index`.
:::

## A minimal route

```ts
// src/routes/health.get.ts
import { get } from "@router/health";

export default get((c) => c.json({ status: "ok" }));
```

That is the entire file. The `get` factory is generated by Nooh for this exact route path; importing it from anywhere else is a type error.

## Multiple methods on the same path

You can have multiple files for the same path as long as the method suffix is different:

<FileTree>

- routes/
  - users/
    - index.get.ts
    - index.post.ts

</FileTree>

Both produce routes on `/users` — `GET /users` and `POST /users` — and each is a separate file with its own handler, middleware, and dependencies.

## Nested paths

Directories map directly to URL segments. Nesting directories nests the path:

<FileTree>

- routes/
  - api/
    - v1/
      - users/
        - index.get.ts

</FileTree>

This produces `GET /api/v1/users`. There is no special configuration needed — the filesystem layout is the routing table.

## Route handler shape

The generated factory accepts either a plain Hono handler or an options object:

```ts
// Plain handler — fastest, fewest moving parts
export default get((c) => c.text("Hello"));

// Options object — middleware, validation, DI, error handling
export default get({
  middleware: [authMiddleware],
  handler: ({ c }) => c.text("Hello"),
});
```

The options object is documented fully in the relevant sections (Dependency Injection, Validation, Error Handling). The plain handler is valid any time you do not need those features.
