Convert handwritten notes to beautifully formatted PDFs using AI
Features • Quick Start • Deployment • Architecture • Get Free API Keys
- 📝 AI-Powered Transcription — Uses Google Gemini 2.5 Flash to accurately transcribe handwritten notes
- 🔢 LaTeX Math Support — Renders mathematical equations beautifully using KaTeX
- 📄 PDF Generation — Creates professional, formatted PDF documents
- 📧 Email Delivery — Sends completed PDFs directly to your inbox
- ⚡ Async Processing — Handles multi-page documents with parallel processing
- 🎨 Modern UI — Clean, responsive interface with glassmorphism design
- 🏠 Local Dev Mode — Run locally with just a Gemini API key (no external services needed!)
# Clone the repository
git clone https://github.com/harrrshall/handscript.git
cd handscript
# Install dependencies
npm install
# Copy environment template
cp .env.example .envFor local development, you only need one API key:
GEMINI_API_KEY=your_gemini_api_keyThe app will automatically:
- ✅ Use in-memory storage instead of Redis
- ✅ Use local filesystem (
public/uploads/) instead of B2 cloud storage - ✅ Bypass QStash and process requests directly
npm run devOpen http://localhost:3000 in your browser.
Note: In local dev mode, files are stored in
public/uploads/and state is kept in memory. Data will be lost when the server restarts.
All required services offer generous free tiers!
Free tier: 15 requests/minute, 1M tokens/day
- Go to Google AI Studio
- Sign in with your Google account
- Click "Create API key"
- Copy the key to your
.envfile
Free tier: 10 GB storage, 1 GB/day download
- Create account at backblaze.com/b2/sign-up.html
- Go to Buckets → Create a Bucket (set to Private)
- Go to App Keys → Add a New Application Key
- Copy
keyID,applicationKey, and note your bucket endpoint
📦 B2 CORS Configuration (Required)
Update your bucket's CORS rules:
[
{
"corsRuleName": "allowAll",
"allowedOrigins": ["*"],
"allowedHeaders": ["*"],
"allowedOperations": ["s3_put", "s3_get", "s3_head"],
"maxAgeSeconds": 3600
}
]Free tier: 10,000 commands/day, 256 MB storage
- Sign up at console.upstash.com
- Create a new Redis database
- Copy
UPSTASH_REDIS_REST_URLandUPSTASH_REDIS_REST_TOKEN
Free tier: 500 messages/day
- Go to console.upstash.com/qstash
- Copy
QSTASH_TOKEN,QSTASH_CURRENT_SIGNING_KEY,QSTASH_NEXT_SIGNING_KEY
- Enable 2-Step Verification
- Go to App Passwords
- Create a new App Password for "Mail"
- Use the 16-character password (without spaces)
- Click the button above or import from GitHub
- Add all environment variables from
.env.example(production section) - Deploy!
| Variable | Description |
|---|---|
GEMINI_API_KEY |
Google Gemini API key |
B2_BUCKET_NAME |
Backblaze B2 bucket name |
B2_REGION |
B2 region (e.g., us-east-005) |
B2_KEY_ID |
B2 application key ID |
B2_APPLICATION_KEY |
B2 application key |
B2_ENDPOINT |
B2 S3-compatible endpoint |
UPSTASH_REDIS_REST_URL |
Upstash Redis REST URL |
UPSTASH_REDIS_REST_TOKEN |
Upstash Redis token |
| Variable | Description |
|---|---|
QSTASH_TOKEN |
For async background processing |
GMAIL_USER |
Gmail address for email delivery |
GMAIL_APP_PASSWORD |
Gmail app password |
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Frontend │────▶│ Next.js API │────▶│ Gemini AI │
│ (React) │ │ Routes │ │ (Transcribe) │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
┌──────────┴──────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Redis/ │ │ B2 Storage/ │
│ In-Memory │ │ Local Files │
└──────────────┘ └──────────────┘
| Directory | Purpose |
|---|---|
app/ |
Next.js App Router pages and API routes |
app/api/ |
Backend API endpoints |
app/components/ |
React UI components |
lib/ |
Shared utilities and services |
lib/gemini.ts |
Gemini AI integration |
lib/s3.ts |
Storage (B2 or local filesystem) |
lib/redis.ts |
State (Upstash or in-memory) |
| Endpoint | Method | Description |
|---|---|---|
/api/jobs |
POST | Create new transcription job |
/api/jobs/[id]/status |
GET | Get job status |
/api/jobs/[id]/finalize |
POST | Generate final PDF |
/api/get-upload-url |
POST | Get presigned upload URL |
/api/download/[key] |
GET | Download generated PDF |
npm testMIT © harrrshall
Made by Harshal singh
