# avril
a v8 runtime i like
(aka: apostate v8 runtime for infrastructure lesbians)
software you can love. the world's number 1 (alphabetically) typescript-first runtime
avril is heavily, _heavily_ inspired by Deno. it's a love letter, really. i'll miss Deno so much
## avril as a web citizen
i love the open web. avril is _for_ web-centric infrastructure: i will use it for my static-site generator; i will write web application backends in it; i will use it as a `comptime` runtime for javascript code which ends up on the web.
avril's package management is open-web-first: you can add an `https://` URL to your `avril.conf` `deps`, and you're good to go. this nets us decentralized package management, patched dependencies as easy as swapping out the URL, and inspectable self-contained scripts.
unlike Deno, avril's https dependencies can be _full packages_, with their own contextual import map: in my opinion the biggest benefit of jsr-first packaging in Deno 2.0 is shaking free from the ergonomic headache that is `_deps.ts`, but this costs you a centralized package repository. of course, avril supports importing code from `jsr:` and `npm:` specifiers, too, but `https` is _just as good!_
as table stakes, avril is ECMA-429 compliant. this is the _Minimum common web API_, defining everything a runtime-agnostic piece of JavaScript can safely expect in its environment. this means avril is compatible with all reasonably-agnostic code! :D
avril also additionally implements the Web Storage API (for `sessionStorage` and persistent `localStorage`), WebSockets (both outgoing and incoming!), and Web Workers.
## avril as a sandbox
avril supports running in `-0` ("zero-by-default") mode, which opts out of all capabilities (akin to Deno's security model). you may then pass `--allow-{net,read,write,run,…}=` to build up capabilities required for doing your useful application work. unlike Deno, you pass multiple `--allow` flags to allow multiple resources of the same category - this solves e.g. allowing read access to a directory whose name contains a comma
without `-0`, you can also pass `--deny-*` flags to do denylist-based capabilities, which may be convenient in some situations. because of Deno's lack of convenience, everyone just uses `-A` anyway, so this is a sort of remedy.
avril also supports `pledge(..)` in `avril:std`, an API for reducing the exposed capability surface area after initialization: this lets you, for example, read a secrets file and then deny future reads, or listen on a port and then deny further networking.
avril's Web Workers implementation allows you to define the worker's capabilities (via `[avril]: { caps: { ... } }` in `WorkerOptions`, provided you `import { avril } from "avril:std"`.)
## avril as modern infrastructure
i'm so lucky to have such a better Rust+ECMAScript ecosystem around me than Deno did in 2018/2019 ^-^
- we use `rusty_v8`, as Cloudflare pledge to continue `rusty_v8`
- we use `cap-std` for capability-based security "all the way down"
- we use the Oxc family of projects for analyzing and transpiling TypeScript
- we use `redb` for `localStorage` and `avril:kv`
## usage
### compiling the runtime
you will need:
- latest stable rust (via rustup is good)
- a C compiler toolchain
- curl (to fetch prebuilt V8 binaries)
- OR a python3 + C++ build tools (gn, ninja, clang) for building v8 via `V8_FROM_SOURCE=1`
- see [rusty_v8](https://github.com/denoland/rusty_v8) <3
you can build the runtime like so:
```sh
cargo build --release --locked -p avril-cli --bin avril
./target/release/avril --help
```
you can also use `cargo install --locked --path cli --bin avril` to install to cargo's binary dir
### tests
```sh
cargo nextest run --workspace
cargo test --workspace --doc # run doctests
```
tests requiring the native TypeScript backend (lsp, check) will be skipped unless the `AVRIL_TEST_TYPESCRIPT` environment var is defined
### setting up VS Code
build the patched TypeScript compiler from the avril repository root, with Go on PATH:
```sh
typescript_src=$(mktemp -d)
git clone --filter=blob:none --no-checkout https://github.com/microsoft/TypeScript.git "$typescript_src"
git -C "$typescript_src" checkout --detach b5c34ba0c61a756c8abaf133236dddf982c27f45
bash lib/lsp/typescript/build.sh "$typescript_src" "/absolute/path/to/avril-tsc"
```
package the extension (Node.js 22.13+, npm, pnpm 11.27.0, VS Code 1.90+):
```sh
cd editors/vscode
pnpm install --frozen-lockfile --prod=false --ignore-scripts
pnpm run package
code --install-extension avril.vsix --force
```
in your user settings, set the actual absolute paths:
```json
{
"avril.lsp.executable": "/absolute/path/to/avril",
"avril.lsp.backend": "/absolute/path/to/avril-tsc"
}
```
keep VS Code's built-in TypeScript extension enabled. the avril language server
should auto start if there's an `avril.conf` in your workspace root.
## docs
- [config format](docs/config.md)
- [friendly JSON](docs/fjson.md)
there are also several more ai generated docs (sorry) in the docs directory.