This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Standard build
cargo build
# Run all tests
cargo test
# Run tests with all features
cargo test --all-features
# Run specific test by name
cargo test test_name
# Check code without building
cargo check
# Format code
cargo fmt
# Run clippy linter
cargo clippy
# Build documentation
cargo doc --open
# Update README from lib.rs docs
cargo rdme# Test with web features
cargo test --features "web_stub,url,crypto,json,console"
# Test with filesystem access
cargo test --features "fs"
# Test all safe features (no sandbox-breaking)
cargo test --features "console,crypto,url,json,broadcast_channel,cache,cron,kv,webgpu,webstorage,webidl"RustyScript is a Rust library for executing JavaScript in a secure, sandboxed environment. The architecture follows a layered design:
Runtime: Public API with sync/async/immediate execution variantsInnerRuntime: Private implementation wrapping Deno's V8 runtimeStaticRuntime: Thread-safe wrapper for concurrent accessRuntimeBuilder: Configurable runtime construction with security policies
ModuleLoader: Handles module resolution, transpilation, and cachingModule: Represents compiled JavaScript/TypeScript modulesModuleHandle: Safe reference to loaded modules with lifecycle management
Extensions are feature-gated Deno ops that provide JavaScript APIs:
- Safe extensions (included by default):
console,crypto,url,json - Sandbox-breaking extensions (opt-in):
fs,io,http,ffi,net - Experimental:
node(Node.js compatibility layer)
JsValue: Primary interface for Rust-JavaScript interop- Serde integration: Automatic serialization/deserialization between Rust and JS types
- Type-safe conversions:
from_value<T>()andto_value()for structured data
Most functionality is available in three variants:
- Sync: Blocking execution (
eval_sync,call_sync) - Async: Non-blocking with futures (
eval,call) - Immediate: Direct V8 execution without microtask processing (
eval_immediate)
- Sandboxed by default: No access to filesystem, network, or system APIs
- Explicit capability grants: Enable features through Cargo features or runtime options
- Extension-based permissions: Fine-grained control over available JavaScript APIs
- Custom
Errortype wrapping V8 JavaScript errors - Automatic error conversion between Rust and JavaScript contexts
- Stack trace preservation across language boundaries
- Extensions are in
src/ext/with feature gates inCargo.toml - Each extension has
mod.rs,init_*.js, and optional Rust implementation - Use
RuntimeBuilder::with_*()methods to enable extensions programmatically
- Tests are primarily inline with
#[cfg(test)]modules in source files - Examples in
examples/serve as integration tests and documentation - Use
RuntimeBuilder::new_with_defaults()for basic test setups - Test different feature combinations to ensure proper isolation
- JavaScript/TypeScript files can be loaded from filesystem or embedded as strings
- Use
include_str!()macro for embedding JS code in Rust - TypeScript is automatically transpiled using SWC
- Module caching is handled automatically but can be controlled via
ModuleLoader
- Use
console.log()in JavaScript code (requiresconsolefeature) - Enable
logfeature and useenv_loggerto see internal Deno logs - V8 errors include JavaScript stack traces when available
- Use
Runtime::take_snapshot()to inspect runtime state
Runtimeis!Send + !Sync- must stay on creating threadStaticRuntimeprovidesSend + Syncwrapper for multi-threaded scenarios- Workers (
workerfeature) provide isolated per-thread runtimes
- V8 heap size can be configured via
RuntimeBuilder::max_heap_size() - Automatic garbage collection with manual
Runtime::run_gc()option - JavaScript values are automatically cleaned up when
JsValueis dropped
- Snapshots can significantly improve startup time for repeated runtime creation
- Module caching reduces repeated compilation overhead
- Use
eval_immediatefor CPU-bound operations that don't need microtasks