A production-ready REST API for executing code in multiple programming languages without Docker. Built with Node.js, it provides secure, isolated code execution with timeout protection and resource limits.
- β 5 Languages Supported: Python, C++, Java, Go, C
- β No Docker Required: Native execution using installed compilers/interpreters
- β Security First: Timeout protection, resource limits, isolated workspaces
- β Fast Execution: No container overhead
- β Production Ready: Error handling, logging, API documentation
- β Easy Integration: Simple REST API, works anywhere
- β Batch Processing: Execute multiple programs simultaneously
- β Runtime Detection: Automatically detects installed compilers
Install the languages you want to support:
# Windows
winget install Python.Python.3.12
# Verify
python --version
# Windows - Install MinGW
# Download from: https://sourceforge.net/projects/mingw-w64/
# Verify
gcc --version
g++ --version
# Windows
winget install Oracle.JDK.21
# Verify
java -version
javac -version
# Windows
winget install GoLang.Go
# Verify
go version
cd backend
npm install
npm start
You'll see:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Code Execution API v1.0.0 β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β Server running on: http://localhost:3000 β
β Documentation: /api/docs β
β Health Check: /api/health β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β Supported Languages: Python, C++, Java, Go, C β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Runtime Status:
β
Python: Python 3.12.0
β
C++: g++ (MinGW-W64 x86_64-ucrt-posix-seh) 13.1.0
β
Java: Java 21.0.1
β
Go: go version go1.21.5 windows/amd64
β
C: gcc (MinGW-W64 x86_64-ucrt-posix-seh) 13.1.0
# Execute Python code
curl -X POST http://localhost:3000/api/execute \
-H "Content-Type: application/json" \
-d "{\"language\": \"python\", \"code\": \"print('Hello, World!')\"}"
http://localhost:3000
GET /api/health
Response:
{
"api": "Code Execution API",
"version": "1.0.0",
"status": "online",
"runtimes": {
"python": { "available": true, "version": "Python 3.12.0" },
"cpp": { "available": true, "version": "g++ 13.1.0" },
"java": { "available": true, "version": "Java 21.0.1" },
"go": { "available": true, "version": "go1.21.5" },
"c": { "available": true, "version": "gcc 13.1.0" }
},
"summary": "5/5 language runtimes available"
}
GET /api/languages
Response:
{
"languages": [
{ "id": "python", "name": "Python", "available": true, "version": "Python 3.12.0" },
{ "id": "cpp", "name": "C++", "available": true, "version": "g++ 13.1.0" },
{ "id": "java", "name": "Java", "available": true, "version": "Java 21.0.1" },
{ "id": "go", "name": "Go", "available": true, "version": "go1.21.5" },
{ "id": "c", "name": "C", "available": true, "version": "gcc 13.1.0" }
],
"total": 5,
"available": 5
}
POST /api/execute
Request Body:
{
"language": "python",
"code": "name = input()\nprint(f'Hello, {name}!')",
"input": "Alice"
}
Response (Success):
{
"success": true,
"stdout": "Hello, Alice!\n",
"stderr": "",
"executionTime": 145,
"language": "Python",
"version": "Python 3.12.0",
"timestamp": "2024-10-08T12:34:56.789Z",
"totalTime": 156
}
Response (Error):
{
"success": false,
"error": "Time Limit Exceeded",
"stdout": "",
"stderr": "Execution timeout after 5000ms",
"executionTime": 5000,
"language": "Python"
}
POST /api/execute/batch
Request Body:
{
"executions": [
{ "language": "python", "code": "print(2 + 2)", "input": "" },
{ "language": "cpp", "code": "#include <iostream>\nint main() { std::cout << 2 + 2; }", "input": "" },
{ "language": "java", "code": "public class Main { public static void main(String[] args) { System.out.println(2 + 2); } }", "input": "" }
]
}
Response:
{
"success": true,
"results": [
{ "success": true, "stdout": "4\n", "language": "Python" },
{ "success": true, "stdout": "4", "language": "C++" },
{ "success": true, "stdout": "4\n", "language": "Java" }
],
"total": 3
}
{
"language": "python",
"code": "numbers = [1, 2, 3, 4, 5]\nprint(sum(numbers))",
"input": ""
}
{
"language": "cpp",
"code": "#include <iostream>\nusing namespace std;\n\nint main() {\n int a, b;\n cin >> a >> b;\n cout << a + b;\n return 0;\n}",
"input": "10 20"
}
{
"language": "java",
"code": "import java.util.*;\npublic class Main {\n public static void main(String[] args) {\n Scanner sc = new Scanner(System.in);\n int n = sc.nextInt();\n System.out.println(n * n);\n }\n}",
"input": "5"
}
{
"language": "go",
"code": "package main\nimport \"fmt\"\n\nfunc main() {\n var name string\n fmt.Scan(&name)\n fmt.Printf(\"Hello, %s!\\n\", name)\n}",
"input": "World"
}
{
"language": "c",
"code": "#include <stdio.h>\nint main() {\n int n;\n scanf(\"%d\", &n);\n printf(\"%d\\n\", n * n);\n return 0;\n}",
"input": "7"
}
- Execution Timeout: Kills processes after 5 seconds
- Output Size Limit: Maximum 1MB output
- Isolated Workspaces: Each execution in separate temporary directory
- Automatic Cleanup: Temporary files deleted after execution
- Input Sanitization: Prevents shell injection
- Resource Limits: Prevents infinite loops and memory bombs
ββββββββββββββββββββ
β Client App β
β (Frontend/API) β
ββββββββββ¬ββββββββββ
β HTTP POST /api/execute
βΌ
βββββββββββββββββββββββββββββββββββ
β Express REST API Server β
β (backend/app.js) β
ββββββββββ¬βββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββ
β Code Executor β
β (backend/executors/index.js) β
ββββββ¬βββββ¬βββββ¬βββββ¬βββββ¬βββββββββ
β β β β β
βΌ βΌ βΌ βΌ βΌ
Python C++ Java Go C
Executor (Native Execution)
β β β β β
βΌ βΌ βΌ βΌ βΌ
Temp Workspace (Isolated)
- Write code to file
- Execute with timeout
- Capture output
- Cleanup
backend/
βββ app.js # Main Express server
βββ package.json # Dependencies
βββ executors/
β βββ index.js # Main executor (routes to language)
β βββ base.js # Base executor class
β βββ python.js # Python executor
β βββ cpp.js # C++ executor
β βββ java.js # Java executor
β βββ go.js # Go executor
β βββ c.js # C executor
βββ temp/ # Temporary execution workspaces (auto-created)
Edit the configuration in app.js
:
const codeExecutor = new CodeExecutor({
timeout: 5000, // Execution timeout (ms)
maxOutputSize: 1024 * 1024 // Max output size (bytes)
});
# Test Python
curl -X POST http://localhost:3000/api/execute \
-H "Content-Type: application/json" \
-d '{"language":"python","code":"print(\"Hello\")"}'
# Test C++
curl -X POST http://localhost:3000/api/execute \
-H "Content-Type: application/json" \
-d '{"language":"cpp","code":"#include <iostream>\nint main() { std::cout << \"Hello\"; }"}'
# Test with input
curl -X POST http://localhost:3000/api/execute \
-H "Content-Type: application/json" \
-d '{"language":"python","code":"name=input();print(f\"Hello, {name}\")","input":"World"}'
- Import the collection from
/api/docs
- Create requests for each language
- Test with various inputs
async function runCode(language, code, input = '') {
const response = await fetch('http://localhost:3000/api/execute', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ language, code, input })
});
const result = await response.json();
console.log(result.stdout);
}
// Usage
runCode('python', 'print("Hello, World!")');
function CodeEditor() {
const [output, setOutput] = useState('');
const executeCode = async (language, code) => {
const response = await fetch('http://localhost:3000/api/execute', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ language, code })
});
const result = await response.json();
setOutput(result.stdout || result.stderr);
};
return (
<div>
<button onClick={() => executeCode('python', 'print("Hi")')}>
Run Code
</button>
<pre>{output}</pre>
</div>
);
}
# Install Python
winget install Python.Python.3.12
# Add to PATH (Windows)
# System Properties > Environment Variables > Path > Add Python path
# Install MinGW-w64
# Download: https://sourceforge.net/projects/mingw-w64/
# Add C:\mingw64\bin to PATH
# Install Java
winget install Oracle.JDK.21
# Verify installation
java -version
javac -version
- Increase timeout in
app.js
- Check for infinite loops in code
- Optimize algorithm
Language | Startup Time | Execution Speed | Memory Usage |
---|---|---|---|
Python | ~100ms | Fast | Low |
C++ | ~500ms | Very Fast | Low |
Java | ~800ms | Fast | Medium |
Go | ~600ms | Very Fast | Low |
C | ~500ms | Very Fast | Low |
PORT=3000 # API port
NODE_ENV=production # Production mode
npm install -g pm2
pm2 start app.js --name code-api
pm2 save
pm2 startup
server {
listen 80;
server_name api.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
MIT License - Feel free to use in any project!
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature
) - Commit changes (
git commit -m 'Add amazing feature'
) - Push to branch (
git push origin feature/amazing-feature
) - Open Pull Request
- Documentation: http://localhost:3000/api/docs
- Issues: Create an issue on GitHub
- Email: your-email@example.com
Your Code Execution API is now ready to use!
Next Steps:
- Install the compilers you need
- Start the server with
npm start
- Test with
curl
or Postman - Integrate into your application
Happy Coding! π