scraggy
Version:
A safe JavaScript expression evaluator
123 lines (91 loc) • 3.84 kB
Markdown
<div align="center">
<img width="150" src="https://raw.githubusercontent.com/alii/scraggy/refs/heads/main/scraggy.png" />
<h1>Scraggy</h1>
</div>
A relatively safe JavaScript code evaluator that doesn't use `eval()` or `Function()`. This library parses and executes JavaScript code using an AST-based approach.
[](https://github.com/alii/scraggy/actions/workflows/bun-test.yml)
## Features
- Evaluates JavaScript code without using the built-in `eval()` or `Function()` constructor
- Supports a subset of common JavaScript language features
- Provides proper memory management and cleanup
- Uses Acorn for parsing JavaScript into an AST
## Installation
```bash
bun install scraggy
```
## Usage
```typescript
import {evaluate} from 'scraggy';
// Simple evaluation with an empty context
const result = await evaluate({}, '2 + 3'); // returns 5 (basic arithmetic works with no globals)
// Evaluation with a context object
const context = {x: 10, y: 20};
const result = await evaluate(context, 'x + y'); // returns 30
// More complex evaluations - no globals needed
const code = `
function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
factorial(5)
`;
const result = await evaluate({}, code); // returns 120
```
## Supported Features
- Literals (numbers, strings, booleans, null, undefined)
- Variables and scope handling (although there's no difference between var, const, let). There is also no hoisting
- Object and array literals
- Object property access (both dot notation and bracket notation)
- Array element access
- Function declarations and function expressions
- Arrow functions
- Rest parameters and spread operators
- Binary expressions (+, -, \*, /, %, etc.)
- Logical expressions (&&, ||, ??)
- Unary expressions (+, -, !, ~, typeof)
- if/else statements
- while loops
- for loops (for, for...in, for...of)
- try/catch/finally blocks
- async/await with Promises
- switch statements
- Class declarations and class expressions with inheritance
- Destructuring assignments (object and array)
- Super references in class methods
- Destructuring in function parameters
- Template literals with expression interpolation
- Optional chaining (?.)
## Security Features
This evaluator is designed with security in mind:
- **No Default Globals**: Unlike JavaScript's `eval()`, this evaluator does not provide ANY built-in global objects by default. This means features like `Promise`, `setTimeout`, `console` are not available unless you explicitly provide them.
- **Explicit Context**: You must explicitly provide any global objects that your code needs through the context parameter, giving you fine-grained control over what's accessible.
- **Sandboxed Execution**: The evaluator cannot access the host environment outside what you provide in the context.
## Limitations and Unsupported Features
To avoid running into unexpected issues, be aware of the following unsupported features:
### Unsupported Syntax
- Module import/export statements
- Private fields (#property)
- Generator functions and yield
- BigInt literals
- Default values in destructuring assignments
### Partially Supported
- Regular expression literals (should be provided via global context)
- Object method definitions use function expressions under the hood
- Only basic error handling is implemented
- Built-in objects like Promise, Error, Math, JSON, Date, etc. must be explicitly provided in the global context if needed
- Nullish coalescing (??) is supported in binary expressions
### Runtime Environment
- No DOM or Web API support
- Limited global object
- No access to Node.js or Bun built-in modules
## Development
To run tests:
```bash
bun test
```
To typecheck:
```bash
bun tsc --noEmit
```
## License
MIT