Free, private, AI-powered OCR tool running entirely in your browser โ Extract text from images with 92-97% accuracy, zero API costs, and 100% data privacy.
- ๐ Lightning Fast - 2-7 second processing time
- ๐ 100% Private - All processing happens in your browser
- ๐ค AI-Powered - Hybrid OCR using Tesseract.js + TrOCR transformers
- ๐ Smart Fallback - Automatically uses best method for each image
- ๐จ Image Enhancement - 8 preprocessing techniques for better accuracy
- ๐ฐ Completely Free - No API costs, no hidden fees
- ๐ Dark/Light Mode - Beautiful UI with theme toggle
- ๐ฑ Mobile Friendly - Responsive design for all devices
- โจ V3 Premium UI - Aurora gradients, glass-morphism, micro-interactions
- โจ๏ธ Keyboard Shortcuts - Quick actions with keyboard (C/D/H/T/Escape)
- ๐ Local History - Last 20 results saved in browser
- โฟ Fully Accessible - WCAG 2.1 AA compliant, keyboard navigation
- ๐ฏ SEO Optimized - Intent-specific pages with FAQ rich snippets
Enable with VITE_UX_V2=1 environment variable for:
- Aurora Background - Animated gradient blobs with grain texture
- Glass Morphism - Modern glassmorphic cards with backdrop blur
- Staged Progress - 3-step progress indicator (Upload โ OCR โ Render)
- Confetti Animation - Celebratory micro-interaction on copy
- History Drawer - Slide-in drawer with last 20 results
- Keyboard Shortcuts:
C- Copy resultD- Download resultH- View historyT- Toggle themeEscape- Close drawer/clear result
- Core Web Vitals - LCP < 1.8s, INP < 200ms, CLS < 0.1
- 5 Intent Pages - SEO-optimized routes with FAQ sections
Original simple UI without premium features.
All canonical and OG/Twitter image URLs are computed as absolute using VITE_SITE_URL (see .env.example).
- Default OG image:
/og/default.png(1200ร630, logo/high contrast, โค200KB recommended) - Set per-route OG via
ogImageprop in SEO helpers/components. - Canonical links are always absolute.
How to set VITE_SITE_URL:
- Locally: add to
.env.local(e.g.VITE_SITE_URL=http://localhost:5173) - Vercel/Production: set in dashboard or
vercel.jsonenv block.
Validation: After deploy, validate with Twitter Card Validator and Facebook Sharing Debugger.
- 92-97% accuracy on printed text
- 70-85% accuracy on handwritten text
- Automatic confidence scoring
- Intelligent fallback for low-confidence results
This repo uses Spec-Driven Development for reliability and accessibility. All features, APIs, schemas, and UX contracts are defined in /specs and enforced in CI.
- Product features:
/specs/product/*.feature(BDD scenarios) - API contracts:
/specs/api/openapi.yml(OpenAPI) - Schemas:
/specs/schemas/*.json(JSON Schema) - UX tokens/contracts:
/specs/ux/tokens.json,/specs/ux/components/*.md - AI goldens:
/specs/ai/evals/goldens/*.json
- Always read relevant specs before proposing changes
- Update tests and contracts if specs change
- Use BDD runner and schema guard helpers for validation
- If spec changed, update tests & ADR
- BDD passing
- Schema/contract diffs clean
- No SEO/a11y regressions
npm run spec:lintโ Spectral lint for OpenAPInpm run spec:schemasโ Validate JSON schemas and tokensnpm run spec:testโ Playwright BDD testsnpm run spec:diffโ OAS diff for breaking changes
- Node.js 20+
- npm 10+ or yarn 4+
# Clone and setup
git clone https://github.com/ParthibanRajasekaran/text-from-image.git
cd text-from-image
npm install
# Start dev server
npm run dev
# Visit http://localhost:5173
# Run tests
npm run test
# Build for production
npm run buildDeploy your EXACT local code to production with zero drift:
# First time setup
npm run vercel:link # Link to your Vercel project
npm run vercel:pull:prod # Pull production environment variables
# Deploy to production
npm run deploy:prodAfter deployment, verify the footer shows the correct commit SHA matching your local git commit.
This project uses controlled deployments to avoid accidental deploys:
Preview Deployments (Pull Requests):
- Only triggers when PR has
deploy:previewlabel - Deploys to preview URL, posted as PR comment
- Cancelled automatically when new commits pushed
Production Deployments (Main Branch):
- Automatically deploys on push to
mainbranch - Skip with
[skip deploy]in commit message - Only deploys if app files changed (not docs-only)
Manual Deployment:
- GitHub UI: Actions โ Deploy to Vercel โ Run workflow
Add these in Settings โ Secrets and variables โ Actions:
| Secret | Where to get it |
|---|---|
VERCEL_TOKEN |
https://vercel.com/account/tokens |
VERCEL_ORG_ID |
Run vercel link, check .vercel/project.json |
VERCEL_PROJECT_ID |
Run vercel link, check .vercel/project.json |
Set these in Vercel Dashboard โ Project โ Settings โ Environment Variables:
# Feature Flags (Production environment)
VITE_UX_V2=true # Enable enhanced UI
VITE_ANALYTICS_ENABLED=true # Enable Web Vitals tracking
VITE_OCR_MIN_CONFIDENCE=60 # Tesseract confidence threshold๐ Full deployment guide: See docs/DEPLOYMENT.md for:
- Zero-drift deployment strategy
- Bundle size monitoring
- CI/CD setup
- Troubleshooting common issues
pages/ # SEO-optimized route pages (lazy-loaded)
โโโ ImageToText.tsx
โโโ ExtractTextFromImage.tsx
โโโ ...
components/ # Reusable React components
โโโ v3/ # Premium UI (Aurora, Glass, History)
โโโ AdSlot.tsx # AdSense slot containers
โโโ ...
hooks/ # Custom React hooks (useShortcuts, useLocalHistory, etc.)
lib/ # Business logic
โโโ consent.ts # Consent Mode v2 management
โโโ analytics.ts # Web Vitals tracking
โโโ config/ # Feature flags & env guards
services/ # OCR engines (Tesseract, TrOCR)
__tests__/ # Test suite (routes, SEO, a11y, deprecation)
User Upload
โ
File Validation (type, size)
โ
Image Preprocessing (optional)
โ
Tesseract OCR (fast, 2-5s)
โโ Confidence โฅ 60%? โ Return โ
โโ Fallback โ TrOCR AI (5-10s) โ Return โ
โ
Result Display + Copy/Download
| Layer | Technology |
|---|---|
| UI | React 19.2 + TypeScript 5.8 |
| Build | Vite 6.2 + Rollup (code splitting) |
| OCR | Tesseract.js 5.1 + TrOCR (AI) |
| Styling | CSS + Tailwind + Custom properties |
| State | React Hooks (useReducer, Context) |
| Testing | Vitest + Testing Library |
| Deployment | Vercel (automated via GitHub Actions) |
See .env.example for all available flags:
| Flag | Purpose | Default |
|---|---|---|
VITE_UX_V2 |
Enable premium UI (Aurora/Glass) | false |
VITE_ADSENSE_PUB_ID |
AdSense publisher ID (prod only) | unset |
VITE_SITE_URL |
Canonical domain for SEO | computed |
VITE_OCR_MIN_CONFIDENCE |
Tesseract confidence threshold | 60 |
See also: Env Guards for runtime validation.
- Supports PNG, JPG, WEBP
- Max file size: 20MB
- Drag & drop or click to browse
- Step 1: Validate file (type, size, browser compatibility)
- Step 2: Apply image preprocessing (optional, auto-enabled)
- Step 3: Try Tesseract OCR (fast method)
- Step 4: If confidence < 60%, fallback to TrOCR AI model
- Extracted text with confidence score
- Copy to clipboard
- Download as .txt or .doc
- Shows which method was used
| Metric | Value |
|---|---|
| Speed | 2-7 seconds average |
| Accuracy | 92-97% (printed text) |
| Cost | $0 (completely free) |
| Privacy | 100% client-side |
| Success Rate | 95%+ with hybrid approach |
| Aspect | Gemini API | This App | Winner |
|---|---|---|---|
| Speed | 1-2s | 2-7s | Gemini |
| Accuracy | 95-99% | 92-97% | Gemini |
| Cost | $0.001-0.01/image | $0 | This App ๐ |
| Privacy | โ Cloud | โ Local | This App ๐ |
| Offline | โ No | โ Yes* | This App ๐ |
*After first-time model download
- โ 100% client-side processing - No server uploads
- โ No data collection - Your images never leave your device
- โ No API keys required - No external dependencies
- โ No tracking - Privacy-first design
- โ GDPR compliant - No personal data processed
This project uses GitHub Actions for automated CI/CD with label-gated preview deploys to avoid waste:
Feature Branch โ PR โ [add deploy:preview label] โ Preview Deploy โ
โ
Main Branch โ Push โ Auto-Production Deploy โ
Key principles:
- โ All code changes go through tests first
- โ
Production deploys only from
mainbranch - โ
Preview deploys opt-in (require
deploy:previewlabel) - โ
Skip deploys with
[skip deploy]in commit message
Deployment workflow: .github/workflows/deploy.yml
Environment config: docs/DEPLOYMENT.md (setup, troubleshooting, env vars)
# Setup (one-time)
npm install -g vercel
vercel link --yes
# Deploy preview locally
vercel
# Deploy production locally
vercel --prod --confirmThis project uses aggressive code splitting to minimize initial load time:
- โ Dynamic Imports - Heavy libraries loaded only when needed
- โ Vendor Chunking - React, Tesseract, Transformers in separate chunks
- โ Lazy Loading - OCR engines loaded on-demand, not upfront
- โ Tree Shaking - Unused code automatically removed
| Chunk | Size (gzipped) | When Loaded |
|---|---|---|
index.js (main) |
~145 KB | Initial page load |
react-vendor.js |
~140 KB | Initial page load |
tesseract.js |
~23 KB | When user starts OCR |
transformers.js |
~199 KB | When AI fallback needed |
jspdf.js |
~40 KB | When user exports to PDF |
First-load JS: ~285 KB (gzipped) โ
Total app (all features): ~547 KB (gzipped)
# Generate interactive bundle visualization
npm run analyze
# Opens stats.html with treemap of all chunksThe analyzer shows:
- Which dependencies contribute most to bundle size
- How code splitting distributes code across chunks
- Gzipped and Brotli compressed sizes
- Duplicate dependencies (if any)
1. Tesseract.js (23 KB)
// โ Before: Loaded upfront
import Tesseract from 'tesseract.js';
// โ
After: Loaded when user starts OCR
const { recognize } = await import('tesseract.js');2. Transformers (199 KB)
// โ Before: Loaded upfront
import { pipeline } from '@xenova/transformers';
// โ
After: Loaded only as fallback or when requested
const { pipeline } = await import('@xenova/transformers');3. jsPDF (40 KB)
// โ Before: CDN script tag in index.html
<script src="https://cdn.../jspdf.umd.min.js"></script>
// โ
After: Loaded only when user exports PDF
const { default: jsPDF } = await import('jspdf');| Metric | Before | After | Improvement |
|---|---|---|---|
| First load JS | ~850 KB | ~285 KB | 67% reduction |
| Time to Interactive | ~5.2s | ~1.8s | 3.4s faster |
| Lighthouse Score | 72 | 94 | +22 points |
| Build warnings | "Some chunks > 500 KB" | โ None | Fixed |
โ DO:
- Keep initial bundle under 300 KB (gzipped)
- Use dynamic imports for heavy libraries
- Analyze bundle regularly with
npm run analyze - Lazy-load features users might not use
โ DON'T:
- Import entire libraries when you only need a few functions
- Load OCR engines upfront before user uploads image
- Bundle large assets (WASM, models) - serve from CDN or
/public
vite.config.ts- Rollup manual chunks configurationservices/*Service.ts- Dynamic imports for OCR enginesutils/fileUtils.ts- Dynamic import for jsPDFpackage.json- Bundle analyzer script
To apply for AdSense and enable monetization:
- Go to AdSense โSitesโ and add
https://freetextfromimage.com. - Ensure the site has live policy pages (
/privacy-policy,/terms,/about,/contact) and helpful guides (/image-to-text, etc.). - Add a Google-certified CMP and wire its callback to
updateConsent()insrc/consent/consent.ts.- Consent Mode v2 must fire before any ad scripts load.
- Set
VITE_ADSENSE_PUB_IDin Vercel (Production) after approval. - Add your publisher ID to
/public/ads.txt. - Use Search Console to submit your sitemap and fix Page Indexing/Core Web Vitals issues.
- Placement rules:
- No ads near upload/CTA areas; avoid accidental clicks.
- All ad slots reserve space to prevent CLS.
- Ads only load after consent and in Production.
Testing:
- Run
npm run sitemapto generate/public/sitemap.xml. - Run
npm run build && npm run testto verify build and ad readiness.
CMP Integration:
- See comments in
src/consent/consent.tsfor wiring a certified CMP callback. - Verify Consent Mode v2 fires before ads script loads.
AdSense Approval:
- Update
/public/ads.txtwith your real publisher ID after approval. - Use AdSense dashboard for auto ad configuration.
SEO:
- All pages have unique meta tags and canonical URLs.
- Guides and policy pages are crawlable and linked from Home/footer.
- robots.txt and sitemap.xml are present.
Performance:
- Ad slots use fixed min-height to prevent layout shift.
- No OCR/UX regressions; light/dark mode consistent.
See CONTRIBUTING.md for:
- Code standards & TypeScript conventions
- Accessibility (a11y) requirements
- Testing & how to run the test suite
- Commit message conventions
- PR process & deprecation policy
Quick checklist before submitting PR:
npm run lint # Fix linting issues
npm run test # Run full test suite
npm run build # Verify production buildThis project is licensed under the MIT License - see the LICENSE file for details.
- Tesseract.js - Apache 2.0
- @xenova/transformers - Apache 2.0
- React - MIT
- Vite - MIT
All dependencies are compatible with commercial use.
- Tesseract.js - Traditional OCR engine
- Transformers.js - Browser-based AI models
- Microsoft TrOCR - AI OCR model
- Repository: github.com/ParthibanRajasekaran/text-from-image
- Issues: github.com/ParthibanRajasekaran/text-from-image/issues
If you find this project useful, please give it a โญ๏ธ on GitHub!
Made with โค๏ธ by Parthiban Rajasekaran