
Research
/Security News
Two Joyfill npm Beta Releases Compromised to Deliver DEV#POPPER Remote Access Trojan
Two Joyfill npm beta releases contain an import-time implant that uses blockchain transactions to retrieve a remote-access trojan.
@memberjunction/code-execution
Advanced tools
Sandboxed code execution service for MemberJunction actions and agents
Sandboxed JavaScript code execution service for MemberJunction AI agents and workflows.
This package provides secure, isolated execution of JavaScript code in a sandboxed environment using isolated-vm with worker process isolation. It's designed to enable AI agents to generate and run code for data analysis, transformations, and calculations without compromising system security or stability.
⚠️ Security: This package handles untrusted code execution. Please review security-research.md for comprehensive security analysis, threat model, and implementation details.
npm install @memberjunction/code-execution
import { CodeExecutionService } from '@memberjunction/code-execution';
// Create service with optional worker pool configuration
const service = new CodeExecutionService({
poolSize: 2, // Number of worker processes (default: 2)
maxQueueSize: 100, // Max queued requests (default: 100)
maxCrashesPerWorker: 3, // Crashes before marking unhealthy (default: 3)
crashTimeWindow: 60000 // Time window for crash counting (default: 60s)
});
// Initialize the worker pool (can also be done automatically on first execute)
await service.initialize();
// Execute code
const result = await service.execute({
code: `
const sum = input.values.reduce((a, b) => a + b, 0);
const average = sum / input.values.length;
output = { sum, average };
`,
language: 'javascript',
inputData: { values: [10, 20, 30, 40, 50] },
timeoutSeconds: 30, // Optional: execution timeout (default: 30)
memoryLimitMB: 128 // Optional: memory limit (default: 128)
});
if (result.success) {
console.log(result.output); // { sum: 150, average: 30 }
console.log(result.logs); // Any console.log output from the code
} else {
console.error(result.error);
console.error(result.errorType); // 'TIMEOUT' | 'MEMORY_LIMIT' | 'SYNTAX_ERROR' | etc.
}
// Check worker pool health
const stats = service.getStats();
console.log('Active workers:', stats.activeWorkers);
console.log('Busy workers:', stats.busyWorkers);
console.log('Queue length:', stats.queueLength);
// Graceful shutdown (important for clean application exit)
await service.shutdown();
Agents use the "Execute Code" action:
{
"type": "Action",
"action": {
"name": "Execute Code",
"params": {
"code": "const total = input.prices.reduce((sum, p) => sum + p, 0); output = total;",
"language": "javascript",
"inputData": "{\"prices\": [10, 20, 30]}"
}
}
}
The sandbox includes these pre-approved npm packages:
const result = await service.execute({
code: `
const _ = require('lodash');
const { format, addDays } = require('date-fns');
const math = require('mathjs');
// Group data by category
const grouped = _.groupBy(input.data, 'category');
// Calculate statistics
const stats = {};
for (const [category, items] of Object.entries(grouped)) {
const values = items.map(i => i.value);
stats[category] = {
mean: math.mean(values),
median: math.median(values),
total: math.sum(values)
};
}
output = stats;
`,
language: 'javascript',
inputData: {
data: [
{ category: 'A', value: 10 },
{ category: 'B', value: 20 },
{ category: 'A', value: 15 }
]
}
});
For detailed security analysis, see security-research.md
This package uses a defense-in-depth approach with five independent security layers:
isolated-vm)input variableoutput variablefs, path modules blocked)http, https, net, axios modules blocked, fetch() API disabled)child_process, cluster blocked)os, process blocked)eval() or Function constructor (for user code)execute(params: CodeExecutionParams): Promise<CodeExecutionResult>Executes code in a sandboxed environment.
Parameters:
interface CodeExecutionParams {
code: string; // JavaScript code to execute
language: 'javascript'; // Currently only 'javascript' supported
inputData?: any; // Data available as 'input' variable
timeoutSeconds?: number; // Execution timeout (default: 30)
memoryLimitMB?: number; // Memory limit (default: 128)
}
Returns:
interface CodeExecutionResult {
success: boolean; // Whether execution succeeded
output?: any; // Value of 'output' variable
logs?: string[]; // Console output
error?: string; // Error message if failed
errorType?: 'TIMEOUT' | 'MEMORY_LIMIT' | 'SYNTAX_ERROR' | 'RUNTIME_ERROR' | 'SECURITY_ERROR';
executionTimeMs?: number; // Execution duration
}
The service handles various error conditions gracefully:
const result = await service.execute({
code: 'invalid syntax here',
language: 'javascript'
});
if (!result.success) {
switch (result.errorType) {
case 'SYNTAX_ERROR':
console.error('Code has syntax errors:', result.error);
break;
case 'TIMEOUT':
console.error('Code execution timed out');
break;
case 'RUNTIME_ERROR':
console.error('Runtime error:', result.error);
break;
case 'SECURITY_ERROR':
console.error('Security violation:', result.error);
break;
}
}
const result = await service.execute({
code: `
const _ = require('lodash');
// Calculate key metrics
const metrics = {
totalSales: _.sumBy(input.sales, 'amount'),
avgSale: _.meanBy(input.sales, 'amount'),
topProducts: _.chain(input.sales)
.groupBy('product')
.map((items, product) => ({
product,
revenue: _.sumBy(items, 'amount')
}))
.orderBy('revenue', 'desc')
.take(5)
.value()
};
output = metrics;
`,
language: 'javascript',
inputData: {
sales: [
{ product: 'Widget', amount: 100 },
{ product: 'Gadget', amount: 200 },
// ... more sales
]
}
});
const result = await service.execute({
code: `
const { format, addDays, differenceInDays } = require('date-fns');
const start = new Date(input.startDate);
const end = new Date(input.endDate);
output = {
duration: differenceInDays(end, start),
milestones: [
format(addDays(start, 30), 'yyyy-MM-dd'),
format(addDays(start, 60), 'yyyy-MM-dd'),
format(addDays(start, 90), 'yyyy-MM-dd')
]
};
`,
language: 'javascript',
inputData: {
startDate: '2025-01-01',
endDate: '2025-12-31'
}
});
const result = await service.execute({
code: `
const Papa = require('papaparse');
const parsed = Papa.parse(input.csvData, {
header: true,
dynamicTyping: true
});
// Filter and transform
const processed = parsed.data
.filter(row => row.status === 'active')
.map(row => ({
id: row.id,
name: row.name,
value: row.value * 1.1 // 10% markup
}));
output = processed;
`,
language: 'javascript',
inputData: {
csvData: 'id,name,value,status\n1,Item A,100,active\n2,Item B,200,inactive'
}
});
CodeExecutionService instance and reuse it (worker pool is shared)service.shutdown() during application shutdown to clean up workerstimeoutSeconds based on expected workloadresult.success before using result.outputservice.getStats() to monitor worker health and queue depthconsole.log() statements for debuggingThe service maintains a pool of worker processes for fault isolation:
┌─────────────────────────────────────┐
│ Main Application Process │
│ │
│ ┌────────────────────────────┐ │
│ │ CodeExecutionService │ │
│ │ │ │
│ │ ┌──────────────────────┐ │ │
│ │ │ WorkerPool │ │ │
│ │ │ - Queue Requests │ │ │
│ │ │ - Monitor Health │ │ │
│ │ │ - Auto Restart │ │ │
│ │ └──────────────────────┘ │ │
│ └────────────────────────────┘ │
│ │ │ │
└──────────┼──────────┼───────────────┘
│ │ IPC (JSON)
┌──────▼───┐ ┌───▼──────┐
│ Worker 1 │ │ Worker 2 │ (Separate OS Processes)
│ │ │ │
│ isolated │ │ isolated │
│ -vm │ │ -vm │
│ │ │ │
└──────────┘ └──────────┘
async/await or Promises (synchronous code only)This package is part of the MemberJunction project. See the main repository for contribution guidelines.
ISC
FAQs
Sandboxed code execution service for MemberJunction actions and agents
The npm package @memberjunction/code-execution receives a total of 1,187 weekly downloads. As such, @memberjunction/code-execution popularity was classified as popular.
We found that @memberjunction/code-execution demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 12 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Two Joyfill npm beta releases contain an import-time implant that uses blockchain transactions to retrieve a remote-access trojan.

Security News
Socket releases free Certified Patches for high-severity Nuxt vulnerabilities, including server-side remote code execution through server island props.

Security News
An open letter signed by 50 companies, from NVIDIA and Microsoft to Mistral and Hugging Face, urges Washington not to restrict open weight AI.