Skip to main content

Architecture Overview

Technical Overview for Engineers​

This document provides a technical overview of NetPad's architecture, key patterns, and where things live in the codebase.


Tech Stack​

LayerTechnologyNotes
FrameworkNext.js 14+ (App Router)Required
UI LibraryReact 18+Required
Component LibraryMaterial-UI (MUI) 5Prefer over Tailwind
LanguageTypeScriptStrict typing required
DatabaseMongoDB AtlasOnly supported database
DB DriverMongoDB Driver 6.5+Minimum version
Vector SearchMongoDB Atlas Vector SearchFor RAG features
AI/LLMCentralized providerOllama β†’ OpenAI β†’ OpenRouter
Workflow EditorReactFlowVisual DAG editor

High-Level Architecture​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ NetPad Platform β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Forms β”‚ β”‚ Workflows β”‚ β”‚ Data Mgmt β”‚ β”‚ AI β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β€’ Builder β”‚ β”‚ β€’ Visual β”‚ β”‚ β€’ Browser β”‚ β”‚ β€’ Conv. β”‚ β”‚
β”‚ β”‚ β€’ WYSIWYG β”‚ β”‚ Editor β”‚ β”‚ β€’ Connection β”‚ β”‚ Forms β”‚ β”‚
β”‚ β”‚ β€’ 30+ Fields β”‚ β”‚ β€’ 25+ Nodes β”‚ β”‚ Vault β”‚ β”‚ β€’ 15+ β”‚ β”‚
β”‚ β”‚ β€’ Converstnl β”‚ β”‚ β€’ Triggers β”‚ β”‚ β€’ Import/ β”‚ β”‚ Agents β”‚ β”‚
β”‚ β”‚ β€’ Analytics β”‚ β”‚ β€’ Execution β”‚ β”‚ Export β”‚ β”‚ β€’ RAG β”‚ β”‚
β”‚ β”‚ β”‚ β”‚ Engine β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚ β”‚ Platform Services β”‚β”‚
β”‚ β”‚ Organizations β”‚ Projects β”‚ Auth β”‚ Billing β”‚ Permissions β”‚ API β”‚β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚ β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚ β”‚ MongoDB Integration β”‚β”‚
β”‚ β”‚ Atlas β€’ Self-hosted β€’ Atlas Data API β”‚β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Repository Structure​

netpad-3/
β”œβ”€β”€ src/ # Main Next.js application
β”‚ β”œβ”€β”€ app/ # App Router pages and API routes
β”‚ β”‚ β”œβ”€β”€ api/ # 165+ API endpoints
β”‚ β”‚ β”œβ”€β”€ (dashboard)/ # Dashboard routes
β”‚ β”‚ └── (public)/ # Public routes
β”‚ β”‚
β”‚ β”œβ”€β”€ components/ # React components
β”‚ β”‚ β”œβ”€β”€ FormBuilder/ # Form building UI (WYSIWYG)
β”‚ β”‚ β”œβ”€β”€ WorkflowEditor/ # Workflow building UI (ReactFlow)
β”‚ β”‚ β”œβ”€β”€ ConversationalForm/# AI chat interface
β”‚ β”‚ β”œβ”€β”€ DataBrowser/ # Data exploration UI
β”‚ β”‚ └── Navigation/ # Application-centric nav
β”‚ β”‚
β”‚ β”œβ”€β”€ lib/ # Core libraries
β”‚ β”‚ β”œβ”€β”€ ai/ # AI service layer, agents, RAG
β”‚ β”‚ β”œβ”€β”€ platform/ # Database connections (SERVER ONLY)
β”‚ β”‚ β”œβ”€β”€ conversational/ # Conversation state management
β”‚ β”‚ └── storage/ # Blob storage utilities
β”‚ β”‚
β”‚ β”œβ”€β”€ hooks/ # Client-side React hooks
β”‚ └── types/ # TypeScript definitions
β”‚
β”œβ”€β”€ packages/ # NPM packages (@netpad/*)
β”‚ β”œβ”€β”€ templates/ # @netpad/templates
β”‚ β”œβ”€β”€ mcp-server/ # MCP tools for AI assistants
β”‚ └── cli/ # CLI package (active)
β”‚
└── docs/ # Documentation (Docusaurus)

Core Modules​

Forms System​

src/components/FormBuilder/     # Visual form builder
β”œβ”€β”€ Canvas/ # WYSIWYG editing surface
β”œβ”€β”€ FieldPalette/ # Field type picker
β”œβ”€β”€ FieldConfig/ # Field property editor
β”œβ”€β”€ Preview/ # Form preview modes
└── ConditionalLogic/ # Logic rule builder

src/lib/platform/
β”œβ”€β”€ forms.ts # Form CRUD operations
β”œβ”€β”€ submissions.ts # Submission handling
└── validation.ts # Server-side validation

Key Concepts:

  • Forms have two modes: Traditional (field-based) and Conversational (AI chat)
  • Conditional logic controls field visibility
  • Computed fields calculate from other field values
  • Forms are scoped to Applications

Workflows System​

src/components/WorkflowEditor/  # Visual workflow builder
β”œβ”€β”€ Canvas/ # ReactFlow canvas
β”œβ”€β”€ NodePalette/ # Node type picker
β”œβ”€β”€ NodeConfig/ # Node property editor
└── ExecutionViewer/ # Run history display

src/lib/platform/
β”œβ”€β”€ workflows.ts # Workflow CRUD
β”œβ”€β”€ execution.ts # Execution engine
└── nodes/ # Node type implementations

Key Concepts:

  • Workflows are directed acyclic graphs (DAGs)
  • Triggered by: form submission, webhook, schedule, manual
  • Nodes process data and pass to next node
  • Execution is async with queue management

AI/Conversational System​

src/lib/ai/
β”œβ”€β”€ aiService.ts # Centralized LLM operations
β”œβ”€β”€ providers/ # Provider implementations
β”‚ β”œβ”€β”€ ollama.ts
β”‚ β”œβ”€β”€ openai.ts
β”‚ └── openrouter.ts
β”œβ”€β”€ agents/ # AI agents
β”‚ β”œβ”€β”€ formGenerator.ts
β”‚ β”œβ”€β”€ fieldOptimizer.ts
β”‚ └── complianceChecker.ts
└── rag/ # RAG implementation
β”œβ”€β”€ vectorStore.ts
β”œβ”€β”€ retriever.ts
└── embedding.ts

src/components/ConversationalForm/
β”œβ”€β”€ ChatInterface/ # Chat UI
β”œβ”€β”€ MessageBubble/ # Message display
β”œβ”€β”€ TopicProgress/ # Progress tracker
└── DataExtraction/ # Extracted data display

Key Concepts:

  • All LLM calls go through centralized aiService
  • Provider priority: Ollama β†’ OpenAI β†’ OpenRouter
  • RAG uses MongoDB Atlas Vector Search
  • Conversational forms extract structured data from natural language


Critical Architecture Rules​

1. Client/Server Boundary​

// ❌ WRONG - Will cause build error
// In a client component:
import { db } from '@/lib/platform/db';

// βœ… CORRECT - Use API routes
// In a client component:
const response = await fetch('/api/forms');

Why: MongoDB driver uses native modules that can't run in browser.

2. Centralized LLM Configuration​

// ❌ WRONG - Hardcoded model
const response = await openai.chat.completions.create({
model: 'gpt-4o-mini', // Don't do this!
messages: [...]
});

// βœ… CORRECT - Use centralized service
import { aiService } from '@/lib/ai/aiService';

const response = await aiService.complete({
messages: [...],
// Model selected automatically from provider config
});

Why: Ensures metrics tracking, respects user's provider preference (Ollama vs OpenAI).

3. Batch Operations for Forms​

// ❌ WRONG - Only adds last field
for (const field of fields) {
onAddField(field); // Triggers dialog each time
}

// βœ… CORRECT - Batch add
onAddTemplate(fields); // Adds all at once

Why: onAddField opens a dialog, loop causes repeated dialogs.

4. MongoDB Version​

// Minimum required: MongoDB 6.5+
// Required for:
// - Atlas Vector Search
// - Latest aggregation features
// - Performance improvements


API Structure​

Endpoint Organization​

/api/
β”œβ”€β”€ forms/ # Form management (~40 endpoints)
β”‚ β”œβ”€β”€ route.ts # GET (list), POST (create)
β”‚ β”œβ”€β”€ [formId]/
β”‚ β”‚ β”œβ”€β”€ route.ts # GET, PUT, DELETE
β”‚ β”‚ β”œβ”€β”€ submissions/ # Submission handling
β”‚ β”‚ └── analytics/ # Form analytics
β”‚ └── templates/ # Template operations
β”‚
β”œβ”€β”€ workflows/ # Workflow management (~15 endpoints)
β”‚ β”œβ”€β”€ route.ts
β”‚ β”œβ”€β”€ [workflowId]/
β”‚ β”‚ β”œβ”€β”€ route.ts
β”‚ β”‚ β”œβ”€β”€ execute/ # Trigger execution
β”‚ β”‚ └── history/ # Execution history
β”‚ └── nodes/ # Node type definitions
β”‚
β”œβ”€β”€ organizations/ # Org management (~30 endpoints)
β”‚ β”œβ”€β”€ route.ts
β”‚ β”œβ”€β”€ [orgId]/
β”‚ β”‚ β”œβ”€β”€ members/
β”‚ β”‚ β”œβ”€β”€ vault/ # Connection vault
β”‚ β”‚ └── templates/
β”‚ └── invitations/
β”‚
β”œβ”€β”€ applications/ # Application management (~10 endpoints)
β”‚ β”œβ”€β”€ route.ts
β”‚ β”œβ”€β”€ [appId]/
β”‚ β”‚ β”œβ”€β”€ releases/
β”‚ β”‚ └── export/
β”‚ └── import/
β”‚
β”œβ”€β”€ marketplace/ # Marketplace (~12 endpoints)
β”‚ β”œβ”€β”€ route.ts
β”‚ β”œβ”€β”€ [appId]/
β”‚ └── categories/
β”‚
β”œβ”€β”€ ai/ # AI operations (~12 endpoints)
β”‚ β”œβ”€β”€ generate/
β”‚ β”œβ”€β”€ optimize/
β”‚ └── agents/
β”‚
β”œβ”€β”€ rag/ # RAG operations (~5 endpoints)
β”‚ β”œβ”€β”€ documents/
β”‚ └── query/
β”‚
└── mongodb/ # Database operations (~10 endpoints)
β”œβ”€β”€ connections/
β”œβ”€β”€ collections/
└── query/

Authentication​

  • Session-based authentication
  • Organization-scoped permissions
  • Role-based access control (Owner, Admin, Member, Viewer)

Data Models​

Core Entities​

// Organization
interface Organization {
_id: ObjectId;
name: string;
slug: string;
members: OrganizationMember[];
settings: OrganizationSettings;
subscription: Subscription;
createdAt: Date;
}

// Application (groups forms + workflows)
interface Application {
_id: ObjectId;
organizationId: ObjectId;
projectId: ObjectId;
name: string;
slug: string;
description?: string;
icon?: string;
color?: string;
forms: ObjectId[];
workflows: ObjectId[];
releases: Release[];
createdAt: Date;
}

// Form
interface Form {
_id: ObjectId;
organizationId: ObjectId;
applicationId?: ObjectId;
name: string;
slug: string;
fields: FieldConfig[];
settings: FormSettings;
conditionalLogic?: ConditionalRule[];
computedFields?: ComputedFieldConfig[];
theme?: FormTheme;
createdAt: Date;
}

// Workflow
interface Workflow {
_id: ObjectId;
organizationId: ObjectId;
applicationId?: ObjectId;
name: string;
nodes: WorkflowNode[];
edges: WorkflowEdge[];
trigger: TriggerConfig;
status: 'draft' | 'active' | 'paused';
createdAt: Date;
}

Field Configuration​

interface FieldConfig {
type: FieldType; // 30+ types
path: string; // Unique identifier
label: string;
required?: boolean;
placeholder?: string;
helpText?: string;
defaultValue?: any;
width?: 'full' | 'half' | 'third' | 'quarter';
validation?: ValidationRules;
options?: SelectOption[]; // For dropdowns, radios, etc.
// Type-specific properties...
}

type FieldType =
| 'short_text' | 'long_text' | 'email' | 'phone' | 'number' | 'currency' | 'url'
| 'dropdown' | 'multi_select' | 'radio' | 'checkbox' | 'toggle'
| 'date' | 'time' | 'datetime'
| 'rating' | 'slider' | 'scale' | 'ranking' | 'matrix'
| 'file_upload' | 'signature' | 'color'
| 'address'
| 'section' | 'divider' | 'heading' | 'html' | 'hidden'
| 'computed';

NPM Packages​

Current Packages​

PackageStatusDescription
@netpad/templatesActive100+ form/workflow templates
@netpad/mcp-serverActiveMCP tools for AI assistants
@netpad/cliActiveCommand-line interface

Future Packages​

PackageStatusDescription
@netpad/workflow-rendererPlannedRead-only workflow visualization
@netpad/formsFutureForm rendering SDK
@netpad/workflowsFutureWorkflow execution SDK

Package Architecture​

packages/
β”œβ”€β”€ templates/
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”œβ”€β”€ forms/ # Form templates by category
β”‚ β”‚ β”œβ”€β”€ workflows/ # Workflow templates
β”‚ β”‚ └── index.ts # Exports
β”‚ └── package.json
β”‚
β”œβ”€β”€ mcp-server/
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”œβ”€β”€ tools/ # MCP tool implementations
β”‚ β”‚ β”œβ”€β”€ resources/ # Resource handlers
β”‚ β”‚ └── index.ts
β”‚ └── package.json
β”‚
└── cli/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ commands/ # CLI commands
β”‚ └── index.ts
└── package.json

MCP Server (AI Integration)​

The MCP server allows AI assistants (Claude, Cursor) to:

  • Generate forms from natural language descriptions
  • Create workflows programmatically
  • Browse and use templates
  • Validate configurations

Available Tools​

ToolDescription
generate_formCreate form config from description
generate_fieldCreate single field config
generate_conditional_logicCreate conditional rules
generate_computed_fieldCreate computed field formulas
browse_templatesSearch and list templates
get_referenceGet field types, operators, etc.
validate_form_configValidate configuration

Usage Example​

User: "Create a patient intake form with name, DOB, allergies, and current medications"

AI (via MCP): Calls generate_form tool with description
β†’ Returns complete FormConfig with appropriate field types

Development Patterns​

Adding a New Field Type​

  1. Add type to FieldType union in src/types/form.ts
  2. Create renderer in src/components/FormBuilder/Fields/
  3. Add validation logic in src/lib/platform/validation.ts
  4. Add to field palette in src/components/FormBuilder/FieldPalette/
  5. Update MCP server field type reference

Adding a New Workflow Node​

  1. Add type to NodeType union in src/types/workflow.ts
  2. Create node component in src/components/WorkflowEditor/Nodes/
  3. Implement execution logic in src/lib/platform/nodes/
  4. Add to node palette
  5. Update MCP server node reference

Adding a New API Endpoint​

  1. Create route file in appropriate src/app/api/ directory
  2. Use existing auth/org middleware patterns
  3. Add TypeScript types for request/response
  4. Document in API reference

Environment Variables​

Required​

# MongoDB
MONGODB_URI=mongodb+srv://...
MONGODB_DATABASE=netpad

# Auth
NEXTAUTH_SECRET=...
NEXTAUTH_URL=http://localhost:3000

AI Providers (at least one required)​

# Ollama (local, highest priority)
OLLAMA_BASE_URL=http://localhost:11434

# OpenAI
OPENAI_API_KEY=sk-...

# OpenRouter (fallback)
OPENROUTER_API_KEY=sk-or-...

Optional​

# Storage
BLOB_STORAGE_URL=...

# Email
SMTP_HOST=...
SMTP_PORT=...

# Integrations
SLACK_WEBHOOK_URL=...

Testing​

Backend Tests​

# Run all backend tests
npm run test

# Run specific test file
npm run test -- forms.test.ts

# Current status: 25/25 tests passing

E2E Tests​

# Run Playwright tests
npm run test:e2e

# 22 test cases across 7 user journeys

Manual QA​

Structured test cases exist for:

  • Form builder functionality
  • Workflow editor functionality
  • Conversational forms
  • Template operations
  • Application export/import

Performance Considerations​

MongoDB Indexes​

Key indexes for common queries:

// Forms
{ organizationId: 1 }
{ organizationId: 1, applicationId: 1 }
{ slug: 1 }

// Submissions
{ formId: 1, createdAt: -1 }

// Workflows
{ organizationId: 1 }
{ trigger.type: 1 }

Caching​

  • React Query for client-side caching
  • API route caching for template data
  • Vector embeddings cached in Atlas

Bundle Size​

  • Tree-shaking enabled
  • Dynamic imports for heavy components (ReactFlow)
  • Route-based code splitting

Security​

Data Protection​

  • Connection vault uses AES-256-GCM encryption
  • Credentials never logged or exposed in responses
  • Organization-scoped data isolation

Authentication​

  • Session-based auth with secure cookies
  • CSRF protection
  • Rate limiting on API endpoints

Input Validation​

  • Server-side validation on all inputs
  • MongoDB query sanitization
  • File upload type/size restrictions

Next Steps​

  1. Review Getting Started for setup instructions
  2. Explore the codebase with this architecture in mind
  3. Pick an area that interests you
  4. Ask questionsβ€”the codebase is large but navigable

Architecture questions? Open a GitHub discussion.