Skip to content

bysages/lens

Repository files navigation

Lens

GitHub GitHub Actions Contributor Covenant

A high-performance image proxy and web services toolkit built with modern TypeScript. Lens provides a comprehensive suite of web utilities including image processing, screenshot capture, font serving, and more.

πŸš€ Features

Core Services

  • πŸ–ΌοΈ Image Proxy: IPX-powered image processing with resize, format conversion, optimization
  • πŸ“Έ Screenshot Capture: Fast website screenshot service with resource optimization
  • πŸ“„ Reader: Article content extraction (HTML/Markdown) with Readability
  • πŸ…°οΈ Font Service: Google Fonts compatible API with multiple providers
  • 🎨 Open Graph Images: Dynamic OG image generation
  • 🎯 Favicon Extraction: Smart favicon extraction from websites
  • πŸ‘€ Gravatar Proxy: Cached Gravatar avatar proxy with email or hash input
  • πŸ€– MCP Server: Model Context Protocol server exposing all services as tools via JSON-RPC 2.0

Performance & Scalability

  • ⚑ Redis Caching: Redis-powered caching with 24-hour intelligent caching
  • πŸš€ Resource Optimization: Optimized page loading with blocked unnecessary resources
  • πŸ›‘οΈ Rate Limiting: Rate limiting for expensive operations
  • πŸ”„ Graceful Degradation: Automatic fallbacks for missing services

πŸ“¦ Quick Start

Prerequisites

  • Node.js 22+
  • pnpm 10+ (recommended) or npm

Installation

# Clone the repository
git clone https://github.com/bysages/lens.git
cd lens

# Install dependencies
pnpm install

# Copy environment configuration
cp .env.example .env

Development

# Start development server
pnpm dev

# Build for production
pnpm build

# Preview production build
pnpm preview

The server will start on http://localhost:3000 by default.

πŸ› οΈ Configuration

Configuration

All configurations are optional and will gracefully degrade:

# Image proxy security
ALLOWED_DOMAINS=example.com,cdn.example.com

# Caching (significantly improves performance)
REDIS_URL=redis://localhost:6379

See .env.example for all available options.

πŸ“‘ API Reference

All cached responses include X-Cache headers (HIT/MISS) and ETag headers for conditional 304 responses.

Images

Image Proxy

Transform and optimize images on-the-fly:

GET /img/{modifiers}/{image_url}

Examples:

# Resize to 300px width, convert to WebP
https://api.bysages.com/img/w_300,f_webp/https://example.com/image.jpg

# Create 200x200 square thumbnail
https://api.bysages.com/img/s_200x200,q_80/https://example.com/image.png

# Smart crop with high quality
https://api.bysages.com/img/w_400,h_300,c_fill,q_95/https://example.com/photo.jpg

Supported Modifiers:

  • w_XXX - Width
  • h_XXX - Height
  • s_XXXxYYY - Size (width x height)
  • f_FORMAT - Format (webp, jpg, png, avif)
  • q_XXX - Quality (1-100)
  • c_MODE - Crop mode (fill, fit, pad)

Performance Features:

  • Redis caching for optimal performance
  • Automatic format optimization and compression

Screenshot Capture

Capture website screenshots with Playwright-aligned options:

GET /screenshot?url={website_url}&options

Examples:

# Basic screenshot
https://api.bysages.com/screenshot?url=https://example.com

# JPEG with custom quality
https://api.bysages.com/screenshot?url=https://example.com&type=jpeg&quality=80

# Mobile screenshot with custom viewport
https://api.bysages.com/screenshot?url=https://example.com&width=375&height=667&mobile=true

# Full page capture
https://api.bysages.com/screenshot?url=https://example.com&fullPage=true

# Clip region (x,y,width,height)
https://api.bysages.com/screenshot?url=https://example.com&clip=0,0,400,300

# Transparent background
https://api.bysages.com/screenshot?url=https://example.com&omitBackground=true

# Disable animations for clean capture
https://api.bysages.com/screenshot?url=https://example.com&animations=disabled

# Custom CSS scale
https://api.bysages.com/screenshot?url=https://example.com&scale=css

# Inject custom stylesheet
https://api.bysages.com/screenshot?url=https://example.com&style=body{background:red}

Parameters:

Parameter Description Default
url Website URL (required) -
width Viewport width (100-2560) 1280
height Viewport height (100-1440) 720
type Output format (png, jpeg) png
quality Image quality, 1-100 (jpeg only) -
fullPage Capture full scrollable page (true/false) false
clip Clip region as x,y,width,height -
omitBackground Hide default white background (true/false, png only) false
scale Screenshot scale (css for CSS pixels, device for device pixels) device
animations Animation handling (disabled or allow) allow
caret Text caret (hide or initial) hide
style Custom CSS stylesheet to apply -
timeout Navigation timeout in ms (1000-30000) 10000
mobile Mobile viewport (true/false) false
darkMode Dark mode (true/false) false
waitUntil Navigation wait condition (load, domcontentloaded, networkidle) domcontentloaded
delay Additional delay in ms after page load (0-10000) -

Performance Notes:

  • Screenshots are cached for 1 day with rate limiting
  • Identical requests return cached results with sub-second response times
  • Resource optimization (blocking fonts, media, websockets) speeds up screenshot generation by 60-80%

Open Graph Images

Generate dynamic OG images:

GET /og?title={title}&description={description}

Examples:

# Basic OG image
https://api.bysages.com/og?title=Welcome&description=Get%20started%20with%20Lens

# Custom styling
https://api.bysages.com/og?title=Hello%20World&theme=dark&fontSize=72&width=1200&height=630

Caching:

  • Generated OG images are cached for 24 hours
  • Identical requests with same parameters return cached results instantly

Web Services

Reader (Content Extraction)

Extract rendered HTML or Markdown content from any URL:

GET /reader?url={website_url}&options

Examples:

# Extract rendered HTML
https://api.bysages.com/reader?url=https://github.com/bysages/lens

# Convert to Markdown
https://api.bysages.com/reader?url=https://github.com/bysages/lens&format=markdown

# Wait for full page load
https://api.bysages.com/reader?url=https://github.com/bysages/lens&waitUntil=load

Parameters:

Parameter Description Default
url Website URL (required) -
format Output format (html, markdown) html
waitUntil Navigation wait condition (load, domcontentloaded, networkidle) domcontentloaded
delay Additional delay in ms after page load (0-10000) -
timeout Navigation timeout in ms (1000-30000) 10000

Favicon Extraction

Extract high-quality favicons:

GET /favicon?url={website_url}&size={size}

Examples:

# Extract favicon
https://api.bysages.com/favicon?url=github.com

# Custom size
https://api.bysages.com/favicon?url=github.com&size=64

Features:

  • Smart favicon extraction from multiple sources (PWA manifests, Apple touch icons, HTML tags)
  • 30-day server-side caching with ETag/304 support
  • Automatic fallback to generated favicon if none found

Gravatar Proxy

Get Gravatar avatars by email, MD5 hash, or path. All query parameters (except email/hash) are forwarded directly to Gravatar. You can switch from Gravatar by simply replacing the URL prefix.

GET /gravatar/{md5}?{gravatar_params}
GET /gravatar?email={email}
GET /gravatar?hash={md5}&{gravatar_params}

Examples:

# By path (drop-in replacement for Gravatar URLs)
https://api.bysages.com/gravatar/{md5}?size=200

# By email
https://api.bysages.com/gravatar?email=user@example.com

# By MD5 hash
https://api.bysages.com/gravatar?hash={md5}

# With Gravatar parameters
https://api.bysages.com/gravatar?email=user@example.com&size=200&default=identicon&rating=pg

Parameters:

  • {md5} - MD5 hash in URL path (drop-in replacement mode)
  • email - Email address (will be MD5 hashed automatically)
  • hash - Pre-computed MD5 hash (alternative to email)
  • All other parameters are forwarded to Gravatar API

MCP Server

Model Context Protocol server exposing all Lens services as tools via JSON-RPC 2.0 over HTTP.

POST /mcp

Setup with Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "lens": {
      "url": "https://api.bysages.com/mcp"
    }
  }
}

Available Tools:

Tool Description Returns
reader Extract article content from a URL (HTML/Markdown) text
screenshot Capture a screenshot of a website image
favicon Extract a website's favicon image
og Generate a dynamic Open Graph image image
gravatar Get a Gravatar avatar by email or hash image
img Transform and optimize an image (resize, crop, convert) image

Fonts

Font Service

Google Fonts compatible API with both v1 and v2 endpoints:

GET /css?family={font_family}&display=swap
GET /css2?family={font_family}&display=swap

API Differences:

Feature /css (v1) /css2 (v2)
Multiple fonts family=A|B (pipe separator) family=A&family=B (repeated parameter)
Style syntax FontName:400,700 (old) FontName:wght@400;700 (new, strict)
Variable fonts ❌ Not supported βœ… Full support with ranges (wght@200..900)
Base URL fonts.googleapis.com/css fonts.googleapis.com/css2

Parameters:

  • family - Font family name (required)
  • display - Font display strategy (default: swap)
  • subset - Font subset (default: latin)
  • provider - Font provider (google, bunny, fontshare, fontsource, default: google)
  • proxy - Use proxy for font files (true/false, default: false)

Examples:

# Basic font (v1 API - pipe separator)
https://api.bysages.com/css?family=Roboto:wght@400;700|Open+Sans:wght@300;400;600&display=swap

# Multiple fonts (v2 API - repeated family parameter)
https://api.bysages.com/css2?family=Inter:wght@400;700&family=Roboto:wght@300;400&display=swap

# Variable fonts with weight range (v2 only)
https://api.bysages.com/css2?family=Inter:wght@200..800&display=swap

# Font metadata
https://api.bysages.com/webfonts?sort=popularity&category=sans-serif

Recommendations:

  • Use /css for legacy compatibility with old Google Fonts syntax
  • Use /css2 for modern applications with variable fonts and better optimization
  • Both endpoints support all font providers (Google, Bunny, Fontshare, Fontsource)

πŸ—οΈ Architecture

Lens is built with modern web standards and follows clean architecture principles:

Core Technologies

  • Runtime: Node.js 22+ with Nitro
  • Language: TypeScript with strict type safety
  • Image Proxy: IPX with Sharp
  • Browser Automation: Playwright with Crawlee BrowserPool
  • Caching: Redis with unstorage

Design Principles

  • KISS (Keep It Simple): Simple, focused solutions over complex abstractions
  • DRY (Don't Repeat Yourself): Shared utilities and configurations
  • Graceful Degradation: Fallbacks for missing dependencies
  • Type Safety: Comprehensive TypeScript coverage
  • Performance First: Optimized for speed and efficiency

πŸš€ Deployment

Prerequisites

  • Node.js 22+ runtime
  • pnpm 10+ package manager
  • Redis (optional, for distributed caching)

Production Deployment

# Build the application
pnpm run build

# Start production server
pnpm run preview

Docker Deployment (Recommended)

Option 1: Using Docker Compose

# Copy environment variables
cp .env.example .env

# Edit .env file to configure your settings
# nano .env

# Start the application
docker-compose up -d

# View logs
docker-compose logs -f app

# Stop the application
docker-compose down

The application will be available at http://localhost:3000

The stack includes:

  • Lens application on port 3000
  • Redis for distributed caching (optional but recommended)

Option 2: Using Docker Run

# Pull the official image
docker pull bysages/lens:latest

# Run container with host network (recommended for accurate IP logging)
docker run -d \
  --name lens \
  --network host \
  --env-file .env \
  --restart unless-stopped \
  bysages/lens:latest

# View logs
docker logs -f lens

# Stop the container
docker stop lens
docker rm lens

Option 3: Build from Source

# Build Docker image
docker build -t lens .

# Run container
docker run -d \
  --name lens \
  --network host \
  --env-file .env \
  --restart unless-stopped \
  lens

Environment Variables

All configurations are optional:

# Image Proxy Security
ALLOWED_DOMAINS=example.com,cdn.example.com

# Caching (significantly improves performance)
REDIS_URL=redis://localhost:6379

See .env.example for all available options.

πŸ“„ License

MIT License - see LICENSE file for details.


Built with ❀️ by By Sages

About

A high-performance image proxy and web services toolkit built with modern TypeScript. Lens provides a comprehensive suite of web utilities including image processing, screenshot capture, font serving, and more.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages