Build Web Apps with
JavaScript & Python
in One File

PureMix is an HTML-first full-stack framework that lets you mix JavaScript, TypeScript, and Python in the same file. Native Python integration, server-side rendering, simple development.

npm install -g puremix@alpha
puremix create my-app
cd my-app && npm run dev
app/routes/index.puremix
<loader>
  async function loadDashboard(request) {
    // Fetch sales data from database
    const salesData = await getSalesData(
      request.query.timeframe || 'month'
    );

    // Call Python for ML analysis
    const analysis = await analyzeSales(salesData);

    return {
      data: {
        sales: analysis.predictions,
        confidence: analysis.confidence_score
      }
    };
  }
</loader>

<div class="dashboard">
  <h1>Sales Forecast: ${loadDashboard.data.sales}</h1>
  <p>Confidence: {loadDashboard.data.confidence}%</p>
</div>

<script server lang="python">
  def analyzeSales(data, js_context=None):
    import pandas as pd
    import numpy as np

    df = pd.DataFrame(data)
    predictions = float(df['sales'].mean())
    std_dev = float(df['sales'].std())

    return {
      'predictions': predictions,
      'confidence_score': round(95 - (std_dev / predictions * 100), 2)
    }
</script>

Why PureMix?

🐍 Python Integration

Mix Python and JavaScript seamlessly. Call NumPy, Pandas, and ML libraries directly from your web app.

Simple Development

Node.js 22+ runs TypeScript natively. No webpack, no bundlers, no complex configuration.

🎯 HTML-First

Write familiar HTML with server-side logic. No JSX compilation, no virtual DOM, just pure web development.

🧩 Component System

React-style components with props and selective updates. Smart DOM diffing for zero-flicker UI.

🚀 Server-Side Rendering

Fast initial page loads with complete SSR. Loader/action pattern for data fetching and mutations.

🔥 Hot Reload

Instant feedback during development. File watching with automatic server restart and browser refresh.

Native Python Integration

PureMix is a framework that lets you use Python using familiar ES6 import syntax. Multiple ways to use Python, from inline execution to ES6 imports.

1

Script Tag Functions

Embed Python functions directly in .puremix files

<script server lang="python">
  def calculate_roi(data, js_context=None):
    import numpy as np

    investment = np.array([d['cost'] for d in data])
    revenue = np.array([d['revenue'] for d in data])
    roi = ((revenue - investment) / investment) * 100

    return {
      'success': True,
      'roi': float(roi.mean()),
      'breakdown': roi.tolist()
    }
</script>

<form onsubmit="calculate_roi">
  <button type="submit">Calculate ROI</button>
</form>
2

Inline Execution

Execute Python code dynamically within loaders

const result = await request.python.call('analyze', data, `
  import pandas as pd

  def analyze(data, js_context=None):
    df = pd.DataFrame(data)
    stats = df.describe()
    return {
      'success': True,
      'statistics': stats.to_dict()
    }
`);
3

ES6 Import Syntax 🎉

Native

Import Python functions like JavaScript modules!

// Import Python functions using standard ES6 syntax!
import { validate_data, analyze_portfolio } from '../lib/data_processor'
import { calculate_loan } from '../services/financial_analyzer'

async function loadPage(request) {
  // Call Python functions using familiar ES6 import syntax!
  const validation = await validate_data({ userId: 123 });
  const analysis = await analyze_portfolio(portfolioData);
  const loan = await calculate_loan({ principal: 300000 });

  return { data: { validation, analysis, loan } };
}
4

Global Functions (Auto-Discovery)

Zero imports needed - Python functions available everywhere

// No imports required! All Python modules auto-discovered
async function loadPage(request) {
  // Call any Python function globally
  const result = await validate_data({ userId: 123 });
  const processed = await process_data(result);
  const formatted = await format_text({ text: 'hello' });

  return { data: { result, processed, formatted } };
}

Why Python Integration Matters

📊

Data Science

Use Pandas, NumPy, Matplotlib directly in your web apps

🤖

Machine Learning

Integrate Scikit-learn, TensorFlow, PyTorch models

🔬

Scientific Computing

Leverage SciPy, SymPy for complex calculations

📈

Financial Analysis

Build trading platforms, risk models, portfolio analyzers

Loader/Action Flow

Understanding PureMix's data fetching and mutation pattern (inspired by Remix)

⚠️ Important: Action results are passed to the loader. When a form submits and calls an action (<script server>), the action's return value becomes available as actionResult in the loader function. The loader then runs again with this data.
1

HTTP Request

User visits /products/123 or submits a form

GET /products/123
POST /products/123
2

Route Resolution

File-based routing matches URL to .puremix file

app/routes/products/[id].puremix
3

Action Execution (POST only)

Server function processes form data or API mutations

<script server>
  async function updateProduct(formData, request) {
    const product = await saveProduct({
      id: request.params.id,
      name: formData.get('name'),
      price: formData.get('price')
    });

    return {
      success: true,
      product,
      message: 'Product updated!'
    };
  }
</script>
4

Loader Execution

Fetch data for rendering (receives action result if POST)

<loader>
  async function loadProduct(request, actionResult) {
    const productId = request.params.id;
    const product = await getProduct(productId);

    return {
      data: {
        product,
        // Include action result for feedback
        updateSuccess: actionResult?.success,
        message: actionResult?.message
      }
    };
  }
</loader>
5

Template Rendering

Server-side rendering with loader data

<div>
  {loadProduct.data.updateSuccess ?
    <div class="success">{loadProduct.data.message}</div> :
    null
  }

  <h1>{loadProduct.data.product.name}</h1>
  <p>Price: ${loadProduct.data.product.price}</p>

  <form onsubmit="updateProduct">
    <input name="name" value="{loadProduct.data.product.name}">
    <input name="price" value="{loadProduct.data.product.price}">
    <button type="submit">Update</button>
  </form>
</div>
6

HTML Response

Complete rendered page sent to browser

HTTP/1.1 200 OK
Content-Type: text/html

<!DOCTYPE html>
<html>...</html>

Key Benefits of This Pattern

Progressive Enhancement

Works without JavaScript, enhanced with JavaScript

Type-Safe

TypeScript support for request, formData, and responses

SEO-Friendly

Complete HTML rendered server-side

Fast Initial Load

No client-side data fetching waterfall

Get Started in 3 Minutes

Step 1

Install PureMix

npm install -g puremix@alpha

Requires Node.js 22+ for native TypeScript support

Step 2

Create Your App

puremix create my-app

# Choose template:
# - basic: Tailwind CSS with animations
# - minimal: Zero dependencies
# - advanced: MongoDB + authentication
Step 3

Start Development

cd my-app
npm run dev

# Server starts at http://localhost:3000
# Hot reload enabled - changes reflect instantly!