Note
On 24 August 2026, cease and desist letters were sent by X Corp. demanding a permanent takedown of Nitter instances and the project's repository.
UPDATE: Following legal advice, the Nitter project will continue. More details will be announced soon.
A free and open source alternative Twitter front-end focused on privacy and
performance.
Inspired by the Invidious project.
- No JavaScript required
- Zero ads
- All requests go through the backend, client never talks to Twitter
- Prevents Twitter from tracking your IP or JavaScript fingerprint
- Uses Twitter's unofficial API (no developer account required)
- Lightweight (for @nim_lang, 60KB vs 784KB from twitter.com)
- RSS feeds (instance-specific, often disabled due to abuse)
- Themes
- Mobile support (responsive design)
- AGPLv3 licensed, no proprietary instances permitted
Embeds(see https://github.com/zedeus/nitter/wiki/Embeds-guide)- Account system with timeline support
BTC: bc1qpqpzjkcpgluhzf7x9yqe7jfe8gpfm5v08mdr55
ETH: 0x24a0DB59A923B588c7A5EBd0dBDFDD1bCe9c4460
XMR: 42hKayRoEAw4D6G6t8mQHPJHQcXqofjFuVfavqKeNMNUZfeJLJAcNU19i1bGdDvcdN6romiSscWGWJCczFLe9RFhM3d1zpL
SOL: FF5bheiD5AqPEdc3eyjymJ8AoMRF1hS78Ht6FiSZZF1t
$Nitter: 4fSxCKc91ELQYVdv3tmHW8R15KoALPwEngyoQe1Xpump
ZEC: u1vndfqtzyy6qkzhkapxelel7ams38wmfeccu3fdpy2wkuc4erxyjm8ncjhnyg747x6t0kf0faqhh2hxyplgaum08d2wnj4n7cyu9s6zhxkqw2aef4hgd4s6vh5hpqvfken98rg80kgtgn64ff70djy7s8f839z00hwhuzlcggvefhdlyszkvwy3c7yw623vw3rvar6q6evd3xcvveypt
The wiki contains a list of instances and browser extensions maintained by the community.
It's impossible to use Twitter without JavaScript enabled, and as of 2024 you need to sign up. For privacy-minded folks, preventing JavaScript analytics and IP-based tracking is important, but apart from using a VPN and uBlock/uMatrix, it's impossible. Despite being behind a VPN and using heavy-duty adblockers, you can get accurately tracked with your browser's fingerprint, no JavaScript required. This all became particularly important after Twitter removed the ability for users to control whether their data gets sent to advertisers.
Using an instance of Nitter (hosted on a VPS for example), you can browse Twitter without JavaScript while retaining your privacy. In addition to respecting your privacy, Nitter is on average around 15 times lighter than Twitter, and in most cases serves pages faster (eg. timelines load 2-4x faster).
In the future a simple account system will be added that lets you follow Twitter users, allowing you to have a clean chronological timeline without needing a Twitter account.
- libpcre
- libsass
To compile Nitter you need a Nim installation, see nim-lang.org for details. It is possible to install it system-wide or in the user directory you create below.
To compile the scss files, you need to install libsass. On Ubuntu and Debian,
you can use libsass-dev.
Caching uses KV, release 2 or later. Each Nitter
instance connects to its local kv front; the fronts share storage backends.
There is no process-local data cache. Configure [Cache] kvEndpoint (default
http://127.0.0.1:8061), kvBucket (default nitter), and kvTimeoutMs
(default 1000). Create the named bucket in every kv back configuration;
its byte capacity and LRU eviction are controlled by KV. The old maxEntries
setting has been removed. Set [Cache] enabled = false to disable caching.
Profiles expire after one hour, photo rails after two hours, and account info
after one day. List and community metadata use listMinutes, and RSS feeds use
rssMinutes; setting either to 0 bypasses caching for that category. Username
to ID mappings have no time-based expiry but are subject to KV eviction.
Absolute expiry timestamps are stored alongside the values, so hosts need
synchronized clocks. Reads do not extend expiry times. KV keeps expired bytes
until overwrite or eviction; Nitter treats expired records as cache misses.
kvPrefix separates serialization namespaces; use the same prefix on instances
that should share data. Restarting Nitter or a front preserves cached values;
restarting a KV backend loses the values held by that backend. KV has no replication.
A failed or timed-out KV request is a cache miss (or a discarded cache write), so Nitter can continue serving through X. The cache HTTP client uses its own connections independently of the proxy configured for X.
Run nimble testCache for the client and application tests. To also test
against three real backends and fronts, build KV 2 and run
KV_BIN=/absolute/path/to/kv nimble testKv. This includes cross-process reads
and a front restart. Live X tests additionally require account sessions and
are enabled in CI with the NITTER_LIVE_TESTS repository variable.
Here's how to create a nitter user, clone the repo, and build the project
along with the scss and md files.
# useradd -m nitter
# su nitter
$ git clone https://github.com/pg83/nitter
$ cd nitter
$ nimble -l build -d:danger --mm:refc
$ nimble -l scss
$ nimble -l md
$ cp nitter.example.conf nitter.confSet your hostname, port, HMAC key, https (must be correct for cookies), and
cache settings in nitter.conf. Run Nitter by executing ./nitter or
using the systemd service below. You should run Nitter behind a reverse proxy
such as Nginx or
Apache for security and
performance reasons.
Build this fork locally to use the KV cache. The upstream Docker image
does not include these changes. The container must be able to reach a KV front:
with host networking the default localhost endpoint works; with a Compose bridge,
set kvEndpoint to a front reachable from that container.
First create your config file. The Docker commands mount it into the container, so it has to exist on the host beforehand. If you've cloned the repo:
cp nitter.example.conf nitter.confPlace your account sessions in sessions.jsonl, then build and run Nitter
in Docker:
docker build -t nitter:local .
docker run -v "$(pwd)/nitter.conf:/src/nitter.conf:ro" \
-v "$(pwd)/sessions.jsonl:/src/sessions.jsonl:ro" \
-d --network host nitter:localOr build and run the single service with Docker Compose:
docker compose up -d --buildNote the Docker commands mount nitter.conf and sessions.jsonl
from the directory you run them in. If a mounted file doesn't
exist, Docker silently creates a directory in its place and the container fails
with not a directory: Are you trying to mount a directory onto a file. Remove
that directory and create the file as shown above.
To run Nitter via systemd you can use this service file:
[Unit]
Description=Nitter (An alternative Twitter front-end)
After=syslog.target
After=network.target
[Service]
Type=simple
# set user and group
User=nitter
Group=nitter
# configure location
WorkingDirectory=/home/nitter/nitter
ExecStart=/home/nitter/nitter/nitter
Restart=always
RestartSec=15
[Install]
WantedBy=multi-user.targetThen enable and run the service:
systemctl enable --now nitter.service
Nitter currently prints some errors to stdout, and there is no real logging
implemented. If you're running Nitter with systemd, you can check stdout like
this: journalctl -u nitter.service (add --follow to see just the last 15
lines). If you're running the Docker image, you can do this:
docker logs --follow *nitter container id*
Feel free to join our Matrix channel. You can email me at zedeus@pm.me if you wish to contact me personally.
For legal inquiries and DMCA requests, contact legal@poast.org