An interactive web application that visualizes social interaction networks around X (Twitter) profiles. Enter a profile URL, and explore the weighted graph of accounts that interact with that profile through mentions, replies, retweets, quotes, and likes.
- 🔍 Profile Input: Enter X profile URLs or handles to explore social graphs
- 📊 Interactive Graph Visualization: 2.5D graph with Cytoscape.js
- 🎨 Weighted Edges: Edge thickness represents interaction intensity
- 🎯 Node Interactions:
- Hover to see account details
- Click nodes to view full profile information
- Highlight connected nodes and edges
- 🎮 Controls:
- Scroll to zoom
- Click and drag to pan
- Arrow keys or A/D to rotate
- +/- keys to zoom in/out
- R to reset view
- ⚡ Real-time Data: Fetches interaction data from X API v2
- 📱 Responsive Design: Works on desktop and tablet devices
Backend:
- Node.js with Express.js
- X (Twitter) API v2 integration
- Graph data aggregation and normalization
Frontend:
- React 18 with Vite
- Cytoscape.js for graph visualization
- Tailwind CSS for styling
- Axios for API calls
x-social-graph-explorer/
├── backend/
│ ├── src/
│ │ ├── models/ # Data models (XProfile, GraphNode, etc.)
│ │ ├── services/ # XDataService, GraphBuilderService
│ │ ├── routes/ # API routes
│ │ └── server.js # Express server
│ ├── package.json
│ └── .env.example
├── frontend/
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── App.jsx
│ │ └── main.jsx
│ ├── package.json
│ └── vite.config.js
├── package.json # Root workspace config
└── README.md
- Node.js >= 18.0.0
- npm or yarn
- X (Twitter) API v2 Bearer Token
- Go to Twitter Developer Portal
- Create a developer account (if you don't have one)
- Create a new project/app
- Generate a Bearer Token with read permissions
- Save the Bearer Token securely
-
Clone the repository:
git clone <repository-url> cd x-social-graph-explorer
-
Install dependencies:
npm run install:all
Or install manually:
npm install cd backend && npm install cd ../frontend && npm install
-
Configure environment variables:
Copy the example environment file in the backend:
cp backend/.env.example backend/.env
Edit
backend/.envand add your X API Bearer Token:X_API_BEARER_TOKEN=your_bearer_token_here PORT=3001 NODE_ENV=development CORS_ORIGIN=http://localhost:5173
From the root directory, run both backend and frontend simultaneously:
npm run devOr run them separately:
Terminal 1 - Backend:
npm run dev:backendTerminal 2 - Frontend:
npm run dev:frontendThe application will be available at:
- Frontend: http://localhost:5173
- Backend API: http://localhost:3001
Build frontend:
cd frontend
npm run buildStart backend:
cd backend
npm start-
Open the application in your browser (http://localhost:5173)
-
Enter an X profile URL or handle:
- Full URL:
https://x.com/elonmuskorhttps://twitter.com/elonmusk - Handle:
@elonmuskor justelonmusk
- Full URL:
-
Click "Generate Graph" to fetch and visualize the social graph
-
Interact with the graph:
- Hover over nodes to see quick info
- Click nodes to view detailed information
- Scroll to zoom in/out
- Drag to pan around
- Arrow keys (or A/D) to rotate the graph
- R key to reset the view
Builds and returns the social graph for a given X handle.
Query Parameters:
handle(required): X handle without @limit(optional): Maximum number of interaction events (default: 100)maxResults(optional): Maximum tweets to analyze (default: 10)minWeight(optional): Minimum edge weight to include (default: 1)maxNodes(optional): Maximum nodes in graph (default: 500)minNodeScore(optional): Minimum node interaction score (default: 0)minEdgeWeight(optional): Minimum edge weight for filtering (default: 1)
Example:
GET /api/graph?handle=elonmusk&limit=50&maxResults=5Response:
{
"rootProfile": {
"id": "123456",
"handle": "elonmusk",
"displayName": "Elon Musk",
"avatarUrl": "https://..."
},
"nodes": [
{
"id": "123456",
"handle": "elonmusk",
"displayName": "Elon Musk",
"avatarUrl": "https://...",
"interactionScore": 100,
"isRoot": true
}
],
"edges": [
{
"id": "source-target",
"sourceId": "987654",
"targetId": "123456",
"weight": 12
}
]
}Error Responses:
400: Invalid or missing handle403: Profile is private or suspended404: Profile not found503: Rate limit exceeded or upstream API error500: Internal server error
-
Nodes: X accounts that interact with the target profile
- Properties: id, handle, displayName, avatarUrl, interactionScore, isRoot
-
Edges: Interaction relationships between accounts
- Properties: sourceId, targetId, weight (interaction count)
-
Interaction Types: reply, mention, retweet, quote, like
Different interaction types are weighted differently:
- Reply: 3 points
- Quote: 3 points
- Mention: 2 points
- Retweet: 2 points
- Like: 1 point
-
API Rate Limits: X API has rate limits. If you exceed them, you'll see a "Rate limit exceeded" error. Wait and try again later.
-
Mock Data: The current implementation uses simplified interaction fetching. For production use, you would need:
- Additional API endpoints for retweets, likes, replies
- Proper rate limiting handling
- Caching mechanisms
-
Private Accounts: Private accounts cannot be analyzed without proper authentication.
-
Performance: The graph visualization supports up to a few thousand nodes efficiently. Very large graphs may experience performance issues.
- Filter interactions by type (replies, retweets, likes)
- Time-based filters (last 7 days, last 30 days)
- Multiple layout algorithms (force-directed, concentric, hierarchical)
- Export graph as PNG or JSON
- Compare two profiles side-by-side
- True 3D visualization with Three.js
- Real-time graph updates
- Advanced analytics and metrics
Backend Services:
XDataService: Handles X API calls and data fetchingGraphBuilderService: Builds and normalizes the social graph
Frontend Components:
App: Main application componentProfileInputForm: Input form for profile URL/handleGraphView: Cytoscape.js graph visualizationNodeDetailsPanel: Side panel showing node detailsStatusBar: Loading and error messagesHeader: Application header
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
This project is provided as-is for educational and demonstration purposes.
Backend won't start:
- Check that
X_API_BEARER_TOKENis set inbackend/.env - Ensure port 3001 is not in use
- Check Node.js version (requires >= 18.0.0)
Frontend won't connect to backend:
- Verify backend is running on port 3001
- Check CORS configuration in
backend/src/server.js - Ensure proxy is configured in
frontend/vite.config.js
Graph not rendering:
- Check browser console for errors
- Verify API response is valid JSON
- Ensure Cytoscape.js dependencies are installed
Rate limit errors:
- Wait for rate limit window to reset (usually 15 minutes)
- Reduce
maxResultsparameter - Consider implementing caching
For issues, questions, or contributions, please open an issue on the repository.
Note: This application requires valid X (Twitter) API credentials and is subject to X API terms of service and rate limits.