# How Nitter Identifies and Marks Pinned Tweets in Timeline Parsing

> Learn how Nitter identifies and marks pinned tweets during timeline parsing. Discover the technical details behind the pinned tweet flag and its distinct label.

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

---

**Nitter detects pinned tweets by parsing the `TimelinePinEntry` instruction in Twitter's GraphQL response and setting a boolean `pinned` flag on the Tweet object before rendering it with a distinct "Pinned" label.**

The open-source Twitter alternative Nitter (zedeus/nitter) parses Twitter's GraphQL timeline JSON to extract tweets and metadata. When processing timeline data, the parser specifically looks for a `TimelinePinEntry` instruction to identify content that users have pinned to their profiles. This detection happens early in the parsing pipeline, ensuring the pinned status propagates through the type system and into the rendered HTML views.

## Detecting Pinned Tweets in the GraphQL Response

In `src/parser.nim`, the timeline parser walks through the list of instructions returned by Twitter's GraphQL API. The parser checks for pinned content only when processing the first instruction set—specifically when `after.len == 0`—since pinned tweets always appear at the top of a user's timeline according to the source code.

### The TimelinePinEntry Instruction

When the parser encounters an instruction with the type name `"TimelinePinEntry"`, it extracts the embedded tweet and marks it accordingly:

```nim
if after.len == 0:
  if i.getTypeName == "TimelinePinEntry":
    let tweets = extractTweetsFromEntry(i{"entry"})
    if tweets.len > 0:
      var tweet = tweets[0]
      tweet.pinned = true                 # ← mark the tweet as pinned

      result.pinned = some tweet          # ← expose the pinned tweet to callers

```

This logic, found at lines 1008–1014 of `src/parser.nim`, ensures that only the first tweet in a `TimelinePinEntry` receives the pinned flag, and the result is stored in the `result.pinned` option field for downstream consumption.

## Storing the Pinned Flag in the Tweet Type

The **Tweet** type defined in `src/types.nim` includes a dedicated `pinned*: bool` field that carries this metadata throughout the application. This boolean allows the view layer to query `tweet.pinned` when deciding whether to render a pinned indicator, without needing to re-parse the original JSON or check instruction types again.

## Rendering the Pinned Label in Views

The view layer consumes the `pinned` boolean to generate appropriate UI indicators. Two primary locations handle this: the tweet header renderer and the timeline layout manager.

### Header Rendering Logic

In `src/views/tweet.nim`, the `renderHeader` procedure receives the `pinned` boolean and conditionally injects a "Pinned" banner:

```nim
proc renderHeader(tweet: Tweet; retweet: string; pinned: bool; prefs: Prefs; path = ""): VNode =
  buildHtml(tdiv):
    if pinned:
      let pinnedLabel =
        if "/i/communities/" in path: "Pinned by Community mods"
        else: "Pinned Tweet"
      tdiv(class="pinned"):
        span: icon("pin", pinnedLabel)
    ...

```

This code, located at lines 29–38, generates a `<div class="pinned">` element containing a pin icon and localized text. The logic also differentiates between standard pinned tweets and community-pinned content by checking the request path.

### Timeline Layout Adjustments

The timeline view in `src/views/timeline.nim` adjusts the container styling based on pinned status. At line 80, the code adds a `with-header` CSS class when a tweet is pinned or is a retweet:

```nim
let header = if tweet.pinned or tweet.retweet.isSome: "with-header " else: ""

```

This class allows the front-end stylesheets—specifically [`src/sass/timeline.scss`](https://github.com/zedeus/nitter/blob/main/src/sass/timeline.scss) at line 197—to apply distinct spacing or border treatments to visually separate pinned content from the chronological stream. The timeline view also respects user preferences to hide pinned tweets entirely.

## Summary

- Nitter identifies pinned tweets via the **`TimelinePinEntry`** instruction type in Twitter's GraphQL response, processed in `src/parser.nim` lines 1008–1014.
- The parser sets **`tweet.pinned = true`** only when `after.len == 0`, ensuring only the initial timeline entry qualifies.
- The **`Tweet`** type in `src/types.nim` stores the pinned status as a boolean field for type-safe access.
- **View rendering** in `src/views/tweet.nim` generates a "Pinned Tweet" label using the `.pinned` CSS class, with special handling for community pins.
- The timeline layout applies a **`with-header`** class to pinned tweets in `src/views/timeline.nim`, enabling distinct styling and honoring user preferences to hide pinned content.

## Frequently Asked Questions

### What is TimelinePinEntry in Nitter?

**TimelinePinEntry** is a specific instruction type in Twitter's GraphQL timeline response that indicates a pinned tweet at the top of a user's profile. Nitter's parser in `src/parser.nim` detects this entry by checking `i.getTypeName == "TimelinePinEntry"` and extracts the embedded tweet to mark it as pinned before processing the remaining chronological entries.

### How does Nitter distinguish between pinned tweets and regular tweets?

Nitter distinguishes pinned tweets by checking for the **`TimelinePinEntry`** instruction type only when parsing the first batch of timeline results (`after.len == 0`). Regular tweets appear under different instruction types like `TimelineAddEntries`. Once detected, the parser sets `tweet.pinned = true`, and downstream code treats this boolean flag as the source of truth for rendering decisions.

### Where is the pinned tweet flag stored in Nitter's codebase?

The pinned flag is stored in the **Tweet** record defined in `src/types.nim` as a `pinned*: bool` field. This field is populated during parsing in `src/parser.nim` and consumed by the view layer in `src/views/tweet.nim` and `src/views/timeline.nim` to conditionally render pinned indicators and apply layout classes.

### Can users hide pinned tweets in Nitter?

Yes, Nitter respects user preferences to hide pinned tweets. The timeline view in `src/views/timeline.nim` checks these preferences when constructing the timeline, allowing users to filter out pinned content. When hidden, the pinned tweet is excluded from the rendered timeline entirely, regardless of the `TimelinePinEntry` detection in the parser.