DEV Community

Joshua Kaplan
Joshua Kaplan

Posted on

From Browser to Serverless: How We Protected Our AI Font Generation IP (And You Should Too)

From Browser to Serverless: How We Protected Our AI Font Generation IP (And You Should Too)

When we built GLIPH—an AI-powered tool that converts sketches into production fonts—we faced every web app founder's nightmare: our most valuable code was completely exposed in the browser.

Anyone could open DevTools, dig through our JavaScript, and reverse-engineer 6 months of custom AI algorithms. 😱

Here's how we moved our core IP to serverless functions and why you should consider the same approach for your proprietary logic.

🔍 The Problem: Client-Side = Exposed Code

Our original architecture looked like this:

// All of this was visible in the browser 🤦‍♂️ class SmartFontGenerator { async processGlyphSheet(glyphs) { // Custom AI glyph detection algorithms const enhancedGlyphs = await this.analyzeGlyphs(glyphs); // Proprietary vectorization logic const vectorizedGlyphs = this.vectorizeWithAI(enhancedGlyphs); // Advanced font generation with smart kerning return this.generateFont(vectorizedGlyphs); } } 
Enter fullscreen mode Exit fullscreen mode

Even with obfuscation, a determined developer could:

  • Extract our AI models
  • Reverse-engineer our vectorization algorithms
  • Copy our font generation logic
  • Build a competing product in weeks

🛡️ The Solution: Serverless IP Protection

We moved our crown jewels to Netlify Functions:

// netlify/functions/font-generator.js exports.handler = async (event, context) => { // API key protection if (event.headers['x-api-key'] !== process.env.GLIPH_FONT_SECRET) { return { statusCode: 401, body: 'Unauthorized' }; } try { const { glyphs, metrics } = JSON.parse(event.body); // 🔒 All proprietary logic now runs server-side const fontBuffer = await generateSmartFont(glyphs, metrics); return { statusCode: 200, body: JSON.stringify({ fontData: Buffer.from(fontBuffer).toString('base64') }) }; } catch (error) { return { statusCode: 500, body: 'Font generation failed' }; } }; // 🔒 Secret sauce hidden on server async function generateSmartFont(glyphs, metrics) { // Custom AI algorithms safely tucked away // Complex vectorization logic protected // Advanced font generation secured } 
Enter fullscreen mode Exit fullscreen mode

🔄 The Migration Challenges

1. Browser APIs Don't Exist in Node.js

Our client-side code used Image, Canvas, and document:

// ❌ This breaks in serverless functions const canvas = document.createElement('canvas'); const img = new Image(); img.onload = () => { ctx.drawImage(img, 0, 0); const imageData = ctx.getImageData(0, 0, width, height); }; 
Enter fullscreen mode Exit fullscreen mode

Solution: Pre-process image data on client, send pixel arrays:

// ✅ Client-side preprocessing const pixels = await dataUrlToPixels(glyph.dataUrl); const glyphData = { ...glyph, pixels: Array.from(pixels) // Send raw pixel data }; // Send to serverless function fetch('/.netlify/functions/font-generator', { method: 'POST', headers: { 'x-api-key': process.env.REACT_APP_GLIPH_FONT_SECRET }, body: JSON.stringify({ glyphs: [glyphData] }) }); 
Enter fullscreen mode Exit fullscreen mode

2. TypeScript → JavaScript Conversion

Our codebase was TypeScript. Serverless functions needed vanilla JS:

// Before: TypeScript with full type safety interface GlyphImage { id: string; dataUrl: string; vectorized: boolean; svgPathData?: string; } class SmartFontGenerator { private fontMetrics: FontMetrics; async processGlyphSheet(glyphs: GlyphImage[]): Promise<EnhancedGlyph[]> { // Complex typed logic } } 
Enter fullscreen mode Exit fullscreen mode
// After: Plain JavaScript for serverless class SmartFontGenerator { constructor() { this.fontMetrics = {}; } async processGlyphSheet(glyphs) { // Same logic, no types } } 
Enter fullscreen mode Exit fullscreen mode

3. Dependencies Management

Created netlify/functions/package.json:

{ "dependencies": { "opentype.js": "^1.3.3", "buffer": "^6.0.3" } } 
Enter fullscreen mode Exit fullscreen mode

📊 The Results

Before (Client-Side):

  • ❌ IP completely exposed
  • ❌ Large bundle sizes (AI models + logic)
  • ❌ Performance varies by device

After (Serverless):

  • ✅ IP protected behind API keys
  • ✅ Lighter client bundles
  • ✅ Consistent server performance
  • ✅ Easier to update algorithms
  • ✅ Built-in scaling

💰 The Business Impact

GLIPH processes font generation requests at $5/month per user. Our core IP is now:

  • Protected from reverse engineering
  • Centrally maintained and updatable
  • Scalable without client-side limitations

🛠️ When Should You Consider This?

Move logic to serverless when:

  • Your algorithms are your competitive advantage
  • You have complex AI/ML models
  • Processing is computationally intensive
  • You need consistent performance across devices
  • IP protection is business-critical

🔗 Want to See It In Action?

Check out GLIPH at [Gliph.us] - transform sketches into fonts using our protected AI pipeline.

Questions about serverless IP protection? Drop them below! 👇


Tags: #serverless #netlify #typescript #javascript #ip #startup #ai

Top comments (0)