X-Media Downloader is a premium, full-stack, glassmorphic web application built with React, Express, and TypeScript that extracts direct, downloadable MP4 video stream URLs from public Twitter/X posts.
This project does not use the official Twitter API. Instead, it leverages a reverse-engineered token calculation and queries the public Twitter Syndication API, replicating the behavior of official embedded web widgets.
- High-End Design System: Modern Glassmorphic UI with dynamic animated gradients, customizable dark/light themes, and custom animations utilizing Framer Motion.
- Micro-Animations: Smooth scale changes, sliding cards, and audio-style loading equalizers.
- Multiple Video Resolutions: Extracts and displays all available MP4 resolutions (e.g.,
1080p,720p,480p,360p) sorted by quality. - Interactive Video Preview: Directly preview the video in a premium player before downloading.
- Download History: Stores past downloads in the browser's
LocalStoragewith quick-reload, individual deletion, and history wipe controls. - Quick-Copy Stream Links: Direct buttons to copy raw CDN links or copy the post URL.
- Advanced Backend Protections: Integrates helmet security headers, custom logging, and rate limiting (max 30 download requests/15 mins per IP).
- TypeScript Everywhere: Strong types on both frontend and backend for robust, type-safe execution.
Frontend Client
- React 19 - Component-based UI library
- TypeScript - Static typing for robust code
- Vite - Lightning-fast build tool and development server
- Tailwind CSS - Utility-first styling framework
- Framer Motion - Powerful library for fluid animations
- Lucide React - Clean and modern SVG icon pack
- React Hot Toast - Toast notifications
Backend Server
- Node.js - JavaScript runtime environment
- Express.js - Fast, unopinionated web framework
- TypeScript - Static typing for backend services
- Axios - Promise-based HTTP client for external requests
- Helmet - Express middleware for securing HTTP headers
- Express Rate Limit - Basic rate-limiting middleware
X-Downloder/
├── client/ # Frontend Application (Vite + React + TS)
│ ├── src/
│ │ ├── components/ # Reusable glassmorphic UI components
│ │ │ ├── ThemeToggle.tsx # Animating Dark/Light switch
│ │ │ ├── DownloadForm.tsx # Link pasting, validating form
│ │ │ ├── VideoResult.tsx # Video player, resolutions, download links
│ │ │ ├── HistoryPanel.tsx # Local history panel list
│ │ │ └── LoadingSkeleton.tsx # Shimmer loading layout
│ │ ├── hooks/ # Custom state management hooks
│ │ │ ├── useTheme.tsx # Dark/Light theme coordinator
│ │ │ └── useHistory.tsx # LocalStorage downloader history
│ │ ├── services/ # Networking and API calling
│ │ │ └── api.ts # Backend connector
│ │ ├── utils/ # Helper utilities
│ │ │ └── helpers.ts # Duration and timestamp formatters
│ │ ├── App.tsx # Assembly, layout & toast provider
│ │ ├── index.css # Tailwind directives & glass panel styles
│ │ └── main.tsx # Entrypoint
│ ├── tailwind.config.js # Darkmode / glassmorphic extension config
│ ├── postcss.config.js
│ └── package.json
│
├── server/ # Backend API Server (Node + Express + TS)
│ ├── src/
│ │ ├── controllers/ # Request handling and validators
│ │ │ └── download.ts # POST /api/download controller
│ │ ├── routes/ # Route mapping
│ │ │ └── download.ts # Downloader router
│ │ ├── services/ # Downloader core scraper logic
│ │ │ └── twitter.ts # Syndication crawler & URL parser
│ │ ├── middleware/ # Express filters
│ │ │ └── rateLimiter.ts # Route-specific rate limits
│ │ ├── utils/ # Base-36 tokens & loggers
│ │ │ ├── token.ts # Validation token formula
│ │ │ └── logger.ts # Colored timestamp logs
│ │ └── index.ts # Server bootstrap
│ ├── tsconfig.json # Compiler rules
│ └── package.json
│
└── README.md # Setup, architecture & deployment guide
The backend scraper circumvents the need for developer API keys by querying the same endpoint Twitter uses to deliver embedded tweets to third-party websites: https://cdn.syndication.twimg.com/tweet-result?id={tweetId}&token={token}.
The token parameter is mandatory for this endpoint to return data. It is calculated by a specific formula matching the tweet's Snowflake ID:
In TypeScript, this is implemented as:
export function getToken(id: string): string {
const numId = Number(id); // Mimics JS float precision loss
return ((numId / 1e15) * Math.PI)
.toString(36)
.replace(/(0+|\.)/g, ''); // Strip periods and zeroes
}The endpoint returns a structured JSON payload. The backend parses mediaDetails to find an item with type === "video" or type === "animated_gif". The streams are found in the video_info.variants array, which we filter for content_type === "video/mp4" and sort by bitrate to deliver organized resolution outputs (like 720p, 480p).
- Node.js (v18.x or later recommended)
- npm or yarn
# Navigate to server
cd server
# Install dependencies
npm install
# Create environment file
cp .env.example .env
# Start development server
npm run devThe server will start on http://localhost:5000.
In a new terminal window:
# Navigate to client
cd client
# Install dependencies
npm install
# Start Vite dev server
npm run devThe application will launch on http://localhost:5173. Open this URL in your web browser.
| Variable | Description | Default |
|---|---|---|
PORT |
The port the Express server listens on. | 5000 |
NODE_ENV |
Running mode (development or production). |
development |
CORS_ORIGIN |
Allowed origin for cors request (frontend URL). | http://localhost:5173 |
By default, the client points to http://localhost:5000 for API requests. To change this, create a .env file:
VITE_API_URL=http://localhost:5000- Sign in to Render.
- Click New + and select Web Service.
- Connect your GitHub repository.
- Set the following options:
- Root Directory:
server - Environment:
Node - Build Command:
npm install && npm run build - Start Command:
npm start
- Root Directory:
- Under Advanced, add your Environment Variables:
NODE_ENV:productionPORT:10000(or whatever Render injects)CORS_ORIGIN:https://your-frontend-vercel-url.vercel.app
- Click Create Web Service. Note down the backend URL (e.g.,
https://x-downloader-api.onrender.com).
- Sign in to Vercel.
- Click Add New > Project and import your repository.
- In the project settings, set:
- Root Directory:
client - Framework Preset:
Vite - Build Command:
npm run build - Output Directory:
dist
- Root Directory:
- Add the Environment Variable:
VITE_API_URL:https://your-backend-api-url.onrender.com(Your Render backend URL, without a trailing slash)
- Click Deploy.
Building X-Media Downloader was a challenging but rewarding experience that involved both frontend polish and backend reverse-engineering.
Key Learnings & Challenges:
- API Reverse-Engineering: The biggest hurdle was bypassing the need for an official Twitter API key, which has become highly restricted. By analyzing how Twitter embeds tweets on third-party sites, I learned how to leverage the public Syndication API.
- Token Generation Logic: Discovering the mathematical formula to generate valid request tokens (multiplying the Snowflake ID by Pi and converting to Base36) was a fascinating dive into how platforms secure their internal endpoints.
- Advanced UI/UX: On the frontend, I wanted to move away from typical, boring utility apps. Using
framer-motionalongside Tailwind's custom configurations allowed me to build a premium, glassmorphic interface with micro-animations that feel responsive and alive. - State & Persistence: Managing local storage for the download history, alongside the dark/light mode toggle, helped solidify my understanding of maintaining complex, persistent states in a modern React application.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License.
⭐ If you find this project useful, please give it a star!
Built with ❤️ by Dhrubaraj Pati for developers
