# JavaScript REPL Run `avril` or `avril repl` to start a persistent JavaScript session. The REPL supports top-level `await`, multiline syntax, persistent lexical bindings, recoverable syntax/runtime errors, and results formatted by `inspect` from `avril:std`, as `console.log` does; objects can customize this with a `Symbol.for("runtime.avril.inspect")` method. Results and `console` output are colored when written to a terminal, unless `NO_COLOR` is set. Use `.help` for the built-in commands and `.exit` (or EOF) to leave. Ctrl-C interrupts an active evaluation; at a terminal prompt it cancels the current line. Piped input is supported without prompts or banners: ```sh printf 'await Promise.resolve(42)\n' | avril ``` While evaluating or inspecting a foreground input at a terminal, the REPL reports package downloads and materialization to stderr. It stays quiet while waiting at the prompt. The REPL uses the same capability defaults as script execution: allow-all unless `-0` removes ambient grants. For a restricted session, grant only what it needs: ```sh avril repl -0 --allow-read=./data --allow-js-exec=./scripts --allow-net=example.com:443 ``` Unlike script execution, a `-0` REPL has no entry-file grant. `--deny-*`, registry/cache/lock options, and offline/frozen package settings retain their normal meanings. `--include` is not used by the REPL; imports entered in the session are prepared on demand. The REPL never creates or updates a lockfile. Importing JSR, npm, or remote modules resolves against an existing `avril.lock` where one is present — so its selections and integrity checks, and `--frozen`, still apply — but new selections are kept only in memory for the session. To record them, run the module with `avril run` or `avril cache` instead. Relative imports resolve from the current working directory. The REPL uses a virtual referrer for resolution; it does not create or load a filesystem entry module and grants no permission to that referrer. Dynamic imports use avril's normal module graph, package resolution, cache, and live capability checks. Built-in `avril:` modules remain available, while private `ext:` modules cannot be imported. Both import declarations and dynamic `import()` are supported; input is JavaScript, not TypeScript. Since the REPL owns standard input, guest reads from `avril:std.stdin` reject with an explicit “not yet implemented” error. Import declarations are a REPL convenience, rewritten to `await import()` with persistent `const` bindings: ```js import { inspect } from 'avril:std' inspect({ answer: 42 }) ``` Default, named, namespace, and side-effect imports are supported. Declarations run in input order rather than being hoisted as in an ES module. Default and named bindings capture exported values at import time; namespace imports retain the module's live properties. Import attributes remain unsupported, just as with dynamic imports. Background timers and native operations continue to make progress while the REPL waits for input; uncaught background errors are reported without ending the session. EOF and `.exit` end the session without draining pending background work. With piped input, an `await` that cannot progress because no host work remains is reported as an error so subsequent input can run. At a terminal, use Ctrl-C to interrupt a pending `await`; background work is left alone, except that a subprocess blocked in a synchronous wait is stopped so the evaluation can finish. Terminal history is held in memory for the current session.