# What Web Framework Does Nitter Use for Its Routing?

> Discover the Nitter web framework: learn how Jester for Nim handles routing and request processing for its privacy-focused Twitter frontend. Find out more today!

- Repository: [Zed/nitter](https://github.com/zedeus/nitter)
- Tags: internals
- Published: 2026-08-29

---

**Nitter uses the Jester web framework for Nim to handle HTTP routing, request handling, and serving its privacy-focused Twitter frontend.**

Nitter is an open-source alternative Twitter frontend written in the Nim programming language. According to the zedeus/nitter source code, the application leverages **Jester**—a lightweight, high-performance HTTP server framework—to manage all routing logic, from timeline pages to media proxies.

## Jester: The Web Framework Powering Nitter's Routing

Nitter’s HTTP layer is built entirely on Jester, a popular web framework for Nim that provides both an HTTP server and a domain-specific language (DSL) for defining routes. This framework enables Nitter to efficiently serve its front-end pages, RSS feeds, media proxies, and API endpoints.

The dependency is declared at the application entry point in `src/nitter.nim#L7` with the statement `import jester`. This import initializes the HTTP server that listens for incoming requests and dispatches them to the appropriate route handlers throughout the codebase.

### Core Routing Imports in Nitter

Every route module in Nitter explicitly imports Jester to access its routing DSL and request objects. For example:

- **Timeline routes**: `src/routes/timeline.nim#L3` imports Jester to define the timeline router
- **Media routes**: `src/routes/media.nim#L6` imports Jester to handle media proxy requests

This consistent pattern ensures all route handlers utilize Jester’s `Request` object for accessing headers, query parameters, and cookies, while the `router` macro defines clean URL patterns.

## How Nitter Defines Routes with Jester

Jester provides a declarative DSL using the `routes:` block or `router Name:` definitions. Nitter leverages these constructs to separate concerns across different modules. The framework supports path parameters using the `@` syntax (e.g., `@id`) and provides built-in HTTP method matching for `get`, `post`, `put`, and `delete` handlers.

In `src/routes/timeline.nim`, Nitter uses the `router timeline:` declaration to group related endpoints, while `src/routes/router_utils.nim` contains shared helper utilities that also depend on Jester’s request handling capabilities.

## Code Examples from the Nitter Source

The following patterns illustrate how Nitter implements routing with Jester throughout its codebase.

### Basic Jester Server Setup

This simplified example shows the foundation used in `src/nitter.nim`:

```nim
import jester

routes:
  get "/":
    resp "Welcome to Nitter!"

  get "/status/@id":
    # `@id` captures the path parameter

    resp "Showing tweet " & paramStr("id")

```

### Modular Route Definitions

The timeline router in `src/routes/timeline.nim` demonstrates Jester’s modular router pattern:

```nim

# src/routes/timeline.nim

import jester, karax/vdom

router timeline:
  get "/":
    # Render the home timeline

    resp renderHomeTimeline()

```

### Accessing the Request Object

Nitter frequently accesses the Jester `Request` object to inspect headers and client data, as seen in view layer files:

```nim

# src/views/tweet.nim

from jester import Request

proc tweetView(req: Request, tweetId: string): string =
  # Access query parameters, cookies, and headers

  let userAgent = req.headers.getOrDefault("User-Agent")
  # Build and return HTML for the tweet

  result = renderTweet(tweetId, userAgent)

```

## Key Source Files for Nitter Routing

Understanding Nitter’s routing requires examining these specific files in the zedeus/nitter repository:

- **`src/nitter.nim`** — The application entry point that imports Jester and starts the HTTP server
- **`src/routes/router_utils.nim`** — Helper utilities for route handling that extend Jester’s functionality
- **`src/routes/timeline.nim`** — Implements timeline routes using Jester’s `router` DSL
- **`src/routes/media.nim`** — Media-proxy routes demonstrating direct Jester request usage
- **`src/views/tweet.nim`** — View layer processing that accepts Jester `Request` objects as parameters

## Summary

- **Nitter uses Jester** as its exclusive web framework for HTTP routing and request handling
- The application is written in **Nim**, leveraging Jester’s lightweight, high-performance server capabilities
- Routing logic is centralized in `src/nitter.nim` and modularized across files in `src/routes/`
- Jester’s DSL provides path parameter capture (e.g., `@id`), HTTP method routing, and request object access
- All route modules explicitly import Jester to maintain consistent request handling patterns

## Frequently Asked Questions

### What web framework does Nitter use for its backend?

Nitter uses the **Jester** web framework for Nim. This framework provides the HTTP server, routing DSL, and request handling capabilities that power Nitter’s entire frontend and API layer, as evidenced by the `import jester` statements found throughout the source tree.

### Is Nitter built with Express.js or Flask?

No. Despite functioning as a Twitter frontend proxy, Nitter is not built with JavaScript or Python frameworks. It is written entirely in **Nim** and uses **Jester**, a Nim-specific web framework that offers similar routing capabilities to Express.js but compiles to native code for better performance.

### How does Nitter handle dynamic URL parameters?

Nitter leverages Jester’s path parameter syntax using the `@` symbol. For example, in route definitions like `get "/status/@id"`, the `@id` segment captures the value from the URL and makes it accessible via `paramStr("id")` or similar accessor methods within the route handler.

### Where is the main routing configuration in Nitter's codebase?

The main routing configuration begins in `src/nitter.nim`, which imports Jester and initializes the server. Individual route modules like `src/routes/timeline.nim` and `src/routes/media.nim` then define specific endpoint handlers using Jester’s `router` DSL and `routes` blocks, creating a modular routing architecture.