Skip to content

harrrshall/handscript

Repository files navigation

Handscript Logo

Handscript

Convert handwritten notes to beautifully formatted PDFs using AI

FeaturesQuick StartDeploymentArchitectureGet Free API Keys


✨ Features

  • 📝 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!)

🚀 Quick Start

Prerequisites

Installation

# Clone the repository
git clone https://github.com/harrrshall/handscript.git
cd handscript

# Install dependencies
npm install

# Copy environment template
cp .env.example .env

Minimal Local Setup (Just Gemini!)

For local development, you only need one API key:

GEMINI_API_KEY=your_gemini_api_key

The 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

Run Locally

npm run dev

Open 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.


🔑 Get Free API Keys

All required services offer generous free tiers!

Google Gemini API (Required)

Free tier: 15 requests/minute, 1M tokens/day

  1. Go to Google AI Studio
  2. Sign in with your Google account
  3. Click "Create API key"
  4. Copy the key to your .env file

Backblaze B2 Storage (Production)

Free tier: 10 GB storage, 1 GB/day download

  1. Create account at backblaze.com/b2/sign-up.html
  2. Go to BucketsCreate a Bucket (set to Private)
  3. Go to App KeysAdd a New Application Key
  4. 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
  }
]

Upstash Redis (Production)

Free tier: 10,000 commands/day, 256 MB storage

  1. Sign up at console.upstash.com
  2. Create a new Redis database
  3. Copy UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN

Upstash QStash (Production - Optional)

Free tier: 500 messages/day

  1. Go to console.upstash.com/qstash
  2. Copy QSTASH_TOKEN, QSTASH_CURRENT_SIGNING_KEY, QSTASH_NEXT_SIGNING_KEY

Gmail SMTP (Optional - for email delivery)

  1. Enable 2-Step Verification
  2. Go to App Passwords
  3. Create a new App Password for "Mail"
  4. Use the 16-character password (without spaces)

🌐 Deployment

Deploy to Vercel

Deploy with Vercel

  1. Click the button above or import from GitHub
  2. Add all environment variables from .env.example (production section)
  3. Deploy!

Required Environment Variables for Production

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

Optional Variables

Variable Description
QSTASH_TOKEN For async background processing
GMAIL_USER Gmail address for email delivery
GMAIL_APP_PASSWORD Gmail app password

🏗️ Architecture

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│   Frontend      │────▶│   Next.js API    │────▶│   Gemini AI     │
│   (React)       │     │   Routes         │     │   (Transcribe)  │
└─────────────────┘     └──────────────────┘     └─────────────────┘
                               │
                    ┌──────────┴──────────┐
                    ▼                     ▼
            ┌──────────────┐      ┌──────────────┐
            │  Redis/      │      │  B2 Storage/ │
            │  In-Memory   │      │  Local Files │
            └──────────────┘      └──────────────┘

Key Components

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)

API Endpoints

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

🧪 Running Tests

npm test

📄 License

MIT © harrrshall


Made by Harshal singh

About

change handwritten pdf into typed beautiful pdf

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors