Your WhatsApp chats, visualized.
Turn your WhatsApp chat exports into beautiful, interactive analytics — entirely in your browser.
|
|
- Export your WhatsApp chat — Open any chat → ⋮ Menu → More → Export Chat (without media)
- Visit TexTale — Drop your
.txtor.zipfile - Explore — Dive into 7 chapters of visualized insights
Works with both 1-on-1 and group chat exports.
| Layer | Technology |
|---|---|
| Framework | React 19 + TypeScript |
| Styling | Tailwind CSS v4 |
| Animations | Motion (Framer Motion) |
| Build | Vite 7 |
| Charts | Custom SVG components |
| Parsing | Web Workers + custom parsers |
| Hosting | GitHub Pages |
# Clone the repo
git clone https://github.com/capturemathan/textale.git
cd textale
# Install dependencies
npm install
# Start dev server
npm run devOpen http://localhost:5173/textale/ in your browser.
npm run buildtextale/
├── public/ # Static assets (favicon, robots.txt)
├── src/
│ ├── analytics/ # Analytics engine & filtering
│ ├── components/
│ │ ├── charts/ # Custom SVG chart components
│ │ ├── common/ # Shared UI components
│ │ ├── discovered/ # Post-upload discovery view
│ │ ├── explorer/ # Main layout, sidebar, navigation
│ │ ├── icons/ # SVG icon components
│ │ ├── landing/ # Landing page & upload dropzone
│ │ ├── metrics/ # Metric cards & hero displays
│ │ ├── processing/ # Processing animation view
│ │ ├── share/ # Shareable card generator
│ │ └── tabs/ # 7 analytics tab pages
│ ├── lib/ # Formatting utilities
│ ├── parser/ # WhatsApp chat parsers
│ ├── store/ # React context state management
│ ├── types/ # TypeScript type definitions
│ └── workers/ # Web Worker for background processing
├── .github/workflows/ # GitHub Actions CI/CD
├── index.html # Entry HTML with security headers
├── vite.config.ts # Vite configuration
└── package.json
- Content Security Policy enforced via meta tags
- Referrer Policy set to
strict-origin-when-cross-origin - X-Content-Type-Options set to
nosniff - Source maps disabled in production builds
- No external API calls — zero network requests after page load
- No
eval(), nodangerouslySetInnerHTML— safe rendering throughout
Developed with ❤️ by Mathan