A web dashboard that fetches recent tweets for any keyword using twikit (no API key needed) and scores them using VADER sentiment analysis. Results are optionally persisted to PocketBase for history tracking.
- 🔍 Keyword search — fetch up to 40 recent tweets per query
- 🧠 VADER sentiment scoring — positive / negative / neutral with compound score
- 🌐 Non-English detection — flags tweets where VADER may be inaccurate
- 🔗 Clickable tweet links — every tweet links directly to the original on X
- 📊 Sentiment distribution bar — visual breakdown at a glance
- 🗂️ PocketBase history — every analysis saved, browsable in the sidebar
- 📰 Editorial UI — clean newspaper-style dashboard, no build step needed
twitter-sentiment/
├── backend/
│ ├── app.py # Flask API server (twikit + VADER + PocketBase)
│ ├── pb_setup.py # One-time PocketBase collection setup script
│ ├── requirements.txt # Python dependencies
│ ├── .env.example # Environment variable template
│ ├── .env # Your credentials (never commit!)
│ ├── cookies.json # Exported from browser via Cookie-Editor
│ └── cookies_twikit.json # Auto-generated converted format
└── frontend/
└── index.html # Dashboard (open directly in browser, no build)
cd backend
pip install -r requirements.txttwikit uses your regular Twitter/X login session — no developer account required.
- Log in to x.com in your browser
- Install the Cookie-Editor extension:
- On x.com, click the extension → Export → Export as JSON
- Save the file as
backend/cookies.json
⚠️ Yourcookies.jsoncontains your session token — never share it or commit it to git.
cp .env.example .envEdit .env:
# Path to your exported cookies file
COOKIES_FILE=cookies.json
# PocketBase (optional — for history saving)
POCKETBASE_URL=http://127.0.0.1:8090
POCKETBASE_EMAIL=your_superuser@email.com
POCKETBASE_PASSWORD=your_superuser_passwordPocketBase is a single-file open source backend that saves all your analyses.
# Download PocketBase for Linux x64
wget https://github.com/pocketbase/pocketbase/releases/download/v0.36.5/pocketbase_0.36.5_linux_amd64.zip
unzip pocketbase_0.36.5_linux_amd64.zip
# Start PocketBase
./pocketbase serve
# Visit http://127.0.0.1:8090/_/ and create your superuser account
# Then add credentials to your .env file and run the setup script:
cd backend
python pb_setup.pyThis creates two collections automatically:
analyses— keyword, sentiment summary, percentages, timestamptweets— individual tweets linked to each analysis
PocketBase is completely optional. If not running, the app works normally — history just won't be saved.
cd backend
python app.py
# or with uv:
uv run python3 -u app.pyServer starts at http://localhost:5000
On first run, cookies.json is auto-converted to cookies_twikit.json (twikit's format).
Open frontend/index.html directly in your browser:
file:///home/youruser/twitter-sentiment/frontend/index.html
No build step, no npm, no bundler needed.
API base config for deployment:
If you host the frontend and backend on the same domain, the UI will call the same-origin /api automatically.
If your backend runs elsewhere, set a custom base URL on the <body> tag:
<body data-api-base="https://your-backend.example.com">- Start PocketBase (optional):
./pocketbase serve - Start Flask:
python backend/app.py - Open
frontend/index.html - Type any keyword, hashtag, or phrase and press Analyze →
- Results show:
- Verdict banner — overall sentiment + compound score
- Distribution bar — visual positive/negative/neutral split
- Tweet table — per-tweet labels, scores, engagement, timestamps
- Clickable timestamps — links to original tweet on X
- Non-English warnings — flagged rows where scoring may be unreliable
- Sidebar history — past analyses from PocketBase, click to re-run
VADER (Valence Aware Dictionary and sEntiment Reasoner) is specifically tuned for social media text.
| Compound Score | Classification |
|---|---|
| ≥ +0.05 | Positive ✅ |
| ≤ −0.05 | Negative ❌ |
| Between | Neutral ➡️ |
The compound score ranges from −1.0 (most negative) to +1.0 (most positive).
Non-English limitation: VADER is trained on English text only. Tweets in Hindi, Malayalam, Arabic, CJK scripts etc. will typically score near 0.000 (neutral) even if they carry strong sentiment. These are automatically flagged with a
🌐 non-english · VADER may be inaccuratebadge. For multilingual support, considercardiffnlp/twitter-xlm-roberta-base-sentiment.
| Layer | Technology |
|---|---|
| Scraping | twikit — no API key, uses browser cookies |
| NLP | VADER — fast, social-media-tuned |
| Backend | Flask + httpx |
| Database | PocketBase — single-file SQLite backend |
| Frontend | Vanilla HTML/CSS/JS — no framework, no build step |
| Fonts | Playfair Display + DM Sans + DM Mono (Google Fonts) |
Add these to your .gitignore:
backend/.env
backend/cookies.json
backend/cookies_twikit.json
pocketbase/pb_data/
- Never share your
cookies.json— it contains your Twitter session token - Regenerate your session (log out + back in) if you accidentally expose it
- PocketBase
pb_data/contains your database — back it up, don't commit it
- twikit returns ~20–40 tweets per search (one page of Twitter's internal API)
- Rate limits apply — avoid running many searches in rapid succession
- Cookie sessions expire periodically — re-export from browser when they do
- VADER is English-only — non-English tweets are flagged but scores are unreliable