Use this file to discover all available pages before exploring further.
Claude Code is Anthropic’s CLI coding agent — it reads your code, writes changes, runs commands, and iterates on errors. That power comes with risk: it has full shell access. Running it inside a BoxLite sandbox means it can do its job without touching your host system.
The core workflow: mount your project read-only into the sandbox, let Claude Code work on a writable copy, and collect the results on your host.
Python
Node.js
claude_code.py
import asyncioimport boxliteasync def main(): async with boxlite.SimpleBox( image="node:20-slim", memory_mib=4096, cpus=2, env=[("ANTHROPIC_API_KEY", "sk-ant-...")], volumes=[ ("./my-project", "/workspace/src", True), # Your code (read-only) ("./output", "/workspace/output", False), # Results (writable) ], working_dir="/workspace/output", ) as box: # Install Claude Code await box.exec("npm", "install", "-g", "@anthropic-ai/claude-code") # Copy source to a writable location so Claude Code can modify it await box.exec("cp", "-r", "/workspace/src/.", "/workspace/output/") # Let Claude Code work on the copy result = await box.exec( "claude", "--print", "Add unit tests for the main module. Write them to tests/. Use pytest.", ) print(result.stdout) if result.exit_code != 0: print(f"Claude Code failed (exit {result.exit_code})") print(result.stderr)if __name__ == "__main__": asyncio.run(main())
claude_code.js
import { SimpleBox } from '@boxlite-ai/boxlite';async function main() { const box = new SimpleBox({ image: 'node:20-slim', memoryMib: 4096, cpus: 2, env: { ANTHROPIC_API_KEY: 'sk-ant-...' }, volumes: [ { hostPath: './my-project', guestPath: '/workspace/src', readOnly: true }, { hostPath: './output', guestPath: '/workspace/output' }, ], workingDir: '/workspace/output', }); try { // Install Claude Code await box.exec('npm', 'install', '-g', '@anthropic-ai/claude-code'); // Copy source to a writable location so Claude Code can modify it await box.exec('cp', '-r', '/workspace/src/.', '/workspace/output/'); // Let Claude Code work on the copy const result = await box.exec( 'claude', '--print', 'Add unit tests for the main module. Write them to tests/. Use pytest.', ); console.log(result.stdout); if (result.exitCode !== 0) { console.error(`Claude Code failed (exit ${result.exitCode})`); console.error(result.stderr); } } finally { await box.stop(); }}main();
After running, check ./output/ on your host — Claude Code’s changes are already there via the volume mount. You can review them, diff against the original, and merge what you want:
diff -r ./my-project ./output
Always mount your source code as read-only. Let Claude Code work on a copy inside the sandbox. This way your original files are never modified until you explicitly merge the changes.
Installing Claude Code at runtime takes 30-60 seconds. For repeated use, build a custom Docker image with Claude Code pre-installed and use it as image="your-registry/claude-code:latest".
Reuse the same sandbox for a multi-step pipeline. Files persist between claude --print invocations, so each step builds on the previous one.
Python
Node.js
claude_code_pipeline.py
import asyncioimport boxliteasync def main(): async with boxlite.SimpleBox( image="node:20-slim", memory_mib=4096, cpus=2, env=[("ANTHROPIC_API_KEY", "sk-ant-...")], volumes=[("./output", "/workspace", False)], working_dir="/workspace", ) as box: await box.exec("npm", "install", "-g", "@anthropic-ai/claude-code") # Task 1: Generate an Express API await box.exec( "claude", "--print", "Create a REST API with Express.js: GET /health returns {status: 'ok'}, POST /echo returns the request body. Save to app.js and package.json." ) # Task 2: Add tests (app.js from task 1 is still on disk) await box.exec( "claude", "--print", "Write tests for app.js using the Node.js built-in test runner. Save to app.test.js." ) # Task 3: Install dependencies and run the tests await box.exec("npm", "install") result = await box.exec("node", "--test", "app.test.js") print(f"Test results (exit code {result.exit_code}):") print(result.stdout) if result.stderr: print(result.stderr)if __name__ == "__main__": asyncio.run(main())
claude_code_pipeline.js
import { SimpleBox } from '@boxlite-ai/boxlite';async function main() { const box = new SimpleBox({ image: 'node:20-slim', memoryMib: 4096, cpus: 2, env: { ANTHROPIC_API_KEY: 'sk-ant-...' }, volumes: [ { hostPath: './output', guestPath: '/workspace' }, ], workingDir: '/workspace', }); try { await box.exec('npm', 'install', '-g', '@anthropic-ai/claude-code'); // Task 1: Generate an Express API await box.exec( 'claude', '--print', 'Create a REST API with Express.js: GET /health returns {status: "ok"}, POST /echo returns the request body. Save to app.js and package.json.' ); // Task 2: Add tests (app.js from task 1 is still on disk) await box.exec( 'claude', '--print', 'Write tests for app.js using the Node.js built-in test runner. Save to app.test.js.' ); // Task 3: Install dependencies and run the tests await box.exec('npm', 'install'); const result = await box.exec('node', '--test', 'app.test.js'); console.log(`Test results (exit code ${result.exitCode}):`); console.log(result.stdout); if (result.stderr) console.error(result.stderr); } finally { await box.stop(); }}main();
All generated files land in ./output/ on your host.