The sandbox problem is eating AI agents alive. Every time an autonomous system needs to do something useful—call an API, transform data, forward a credential—engineers face the same lose-lose choice: give it a general-purpose language and pray nothing explodes, or lock it into a handful of hardcoded tools that don't scale. The standard band-aid is Docker, microVMs, Firecracker, E2B—spin up a container, wait for cold boot, run three API calls, tear it down, repeat thousands of times a day while burning compute and latency on infrastructure that's just there to babysit untrusted code. Safescript, a new language landing on Hacker News this week, takes a fundamentally different approach. The language is the sandbox. Programs compile to static directed acyclic graphs (DAGs) with a closed instruction set—no filesystem access, no shell exec, no eval, no dynamic imports. You can run safescript programs directly in your application process, in the same runtime as your server. No container spin-up, no VM overhead, no orchestration layer. Just execute and done.
The Language Won't Let Programs Run Forever
Safescript is explicitly not Turing-complete, and that's the entire point. There are no loops, no recursion—the parser builds a function call graph and rejects cycles at parse time, both direct recursion and mutual recursion. The only iteration constructs are map, filter, and reduce, and they operate exclusively on finite arrays. There's no lazy evaluation, no generators, no backdoor to construct unbounded data. The result is that every safescript program provably halts. You don't need to set timeouts as a safety net or reason about convergence. The language structurally cannot express a program that runs forever. This puts Safescript in the same category as Dhall and SQL (without recursive CTEs)—you give up the ability to express every computable function, but in exchange you get a hard guarantee that nothing will hang your system. For AI agent tasks where you're running thousands of automated operations daily, that's a trade most teams should make immediately.
Signatures Catch Supply Chain Attacks Before They Run
The more interesting security feature is the signature system. Every safescript program has a signature—a complete static description of what it does, computed without executing anything. The signature tells you exactly which hosts it contacts, which environment sources it reads (timestamp, randomBytes), and how data flows between all of them. Here's where it gets clever: if an agent skill receives your API key as input and sends it to api.example.com, that's fine—that's what the signature shows. But if a malicious update adds a second HTTP call forwarding that same key to evil.io, the signature changes. The new host appears in the diff. The data flow from param:apiKey to host:evil.io lights up red. You can detect this automatically before the program ever runs—no heuristic scanning, no runtime monitoring needed. It's a proof because the language is constrained enough that the analysis is exact.
Syntax That Looks Like JavaScript But Isn't
Safescript syntax resembles a subset of JavaScript, but under the hood it's a DAG description language. There's no runtime object model, no prototype chain, no closures—just operations and data flow. Top-level constructs like imports, function definitions, and doc() annotations have no evaluation order; a safescript file is a flat namespace where functions reference each other by name. Within function bodies, statement order is also irrelevant. Every function compiles to a DAG—the executor evaluates nodes based on data dependencies, not line numbers. That means return can appear before assignments: add = (x: number, y: number): number => { return result; result = x + y; } This works because the compiler resolves the dependency graph statically. The only constraint is scoping—names must be resolvable somewhere in the function as a parameter or assignment—but where they appear doesn't matter.
Built-in Operations and Architecture
All computation happens through op calls. Some highlights: httpRequest for HTTPS calls (with static host fields enforced at parse time), crypto operations including Ed25519 signing, AES-GCM encryption/decryption, X25519 key agreement, JSON parsing/stringifying, SHA-256 hashing, base64url encoding, and environment sources like timestamp() and randomBytes(). The op layer is a TypeScript library for defining typed operations with Zod input/output schemas, manifests declaring resource costs and tags, and run functions. Custom registries can extend the built-in ops. The language layer sits on top with lexer, parser, interpreter, and signature analyzer. Programs are .safescript files with custom syntax. Installation is a single curl command: curl -fsSL https://raw.githubusercontent.com/uriva/safescript/main/install.sh | sh, or pull it as a library via Deno (deno add jsr:@uri/safescript) or npm (npx jsr add @uri/safescript).
Key Takeaways
- Safescript runs AI agent code directly in your process—no containers, no cold starts, no orchestration overhead
- Every program provably halts; the language can't express infinite loops or unbounded data by construction
- Signature diffing catches supply chain attacks before execution—not heuristic scanning, formal analysis
- Complexity inference auto-generates Big-O formulas for resource planning and policy bounds
- The tradeoff: not Turing-complete means some algorithms are inexpressible, but for agent tasks that's almost always acceptable
The Bottom Line
Safescript is a clean solution to a real problem. Containers were never the right answer for running untrusted AI-generated code—they're too heavy, too slow, and they don't actually solve the supply chain problem when an update can phone home with your credentials at runtime. If you're building anything that lets LLMs write and execute code in production, this is worth evaluating seriously. The formal guarantees aren't marketing fluff; they're enforced by language design.