tpmjs/services/sandbox-executor/README.md
Ajax Davis 0296433980 feat: add Railway-based sandbox executor microservice
**New Sandbox Service:**
- Separate microservice for secure npm package execution
- Uses isolated-vm for V8-level isolation
- 128MB memory limit, 10s timeout
- Package caching for performance
- Express API with /execute, /health, /cache/clear endpoints

**Why Microservice:**
- VM2 doesn't work with Next.js Turbopack (requires runtime file access)
- isolated-vm doesn't work in Vercel serverless (native bindings)
- Microservice allows full Node environment with proper sandboxing
- Industry standard approach (Replit, CodeSandbox, RunKit)

**Deployment:**
- Dockerfile with isolated-vm build dependencies
- Railway.json configuration
- Health checks and auto-restart policies
- CORS configuration for Next.js integration

**Next Steps:**
1. Deploy to Railway:
   cd services/sandbox-executor
   railway init
   railway up
2. Set SANDBOX_EXECUTOR_URL in Next.js env
3. Update API routes to call sandbox service

This provides secure, production-ready package execution outside Vercel's constraints.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 01:07:24 +10:00

2.6 KiB

TPMJS Sandbox Executor Service

Isolated microservice for securely executing TPMJS npm packages using isolated-vm.

Architecture

This service runs separately from the main Next.js application to provide:

  • Secure sandboxing using V8 isolates
  • Resource limits (128MB memory, 10s timeout)
  • Package caching for faster subsequent executions
  • Isolation from main app - no risk of compromising the web app

API Endpoints

POST /execute

Execute an npm package function.

Request:

{
  "packageName": "@tpmjs/createblogpost",
  "functionName": "default",
  "params": {
    "topic": "TypeScript best practices",
    "length": "medium"
  }
}

Response:

{
  "success": true,
  "output": "Generated blog post content...",
  "executionTimeMs": 1234,
  "logs": []
}

GET /health

Health check endpoint.

Response:

{
  "status": "healthy",
  "service": "tpmjs-sandbox-executor",
  "version": "1.0.0",
  "memoryLimit": "128MB",
  "timeout": "10000ms"
}

POST /cache/clear

Clear the npm package cache.

Environment Variables

  • PORT - Server port (default: 3000)
  • PACKAGE_CACHE_DIR - Package cache directory (default: /tmp/.tpmjs-cache)
  • ALLOWED_ORIGINS - Comma-separated list of allowed CORS origins (default: *)

Deployment

Railway

  1. Initialize Railway project:
railway init
  1. Link to existing project or create new:
railway link
  1. Deploy:
railway up
  1. Set environment variables:
railway variables set ALLOWED_ORIGINS=https://tpmjs.com,https://tpmjs-web.vercel.app
  1. Get the service URL:
railway domain

Local Development

npm install
npm run dev

Test locally:

curl -X POST http://localhost:3000/execute \
  -H "Content-Type: application/json" \
  -d '{
    "packageName": "@tpmjs/createblogpost",
    "params": {"topic": "TypeScript"}
  }'

Security

  • Runs in isolated V8 context
  • 128MB memory limit per execution
  • 10 second timeout
  • No filesystem access from sandbox
  • No network access from sandbox
  • Packages cached in /tmp

Integration with Next.js

Update the Next.js API route to call this service:

// apps/web/src/app/api/tools/execute/[...slug]/route.ts

const SANDBOX_URL = process.env.SANDBOX_EXECUTOR_URL;

const response = await fetch(`${SANDBOX_URL}/execute`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    packageName,
    functionName: 'default',
    params
  })
});

const result = await response.json();

Monitoring

Check logs:

railway logs

Monitor resource usage:

railway status