https://github.com/aether-lang-dev/aesite
Aether web site
https://github.com/aether-lang-dev/aesite
Last synced: 4 days ago
JSON representation
Aether web site
- Host: GitHub
- URL: https://github.com/aether-lang-dev/aesite
- Owner: aether-lang-dev
- Created: 2026-03-23T19:31:28.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-07-31T20:08:42.000Z (8 days ago)
- Last Synced: 2026-07-31T20:22:02.375Z (8 days ago)
- Language: HTML
- Size: 3.01 MB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Aether Language, website and REPL
The website for the Aether programming language, and its interactive REPL,
served by Aether's own `std.http` server.
## Serving
`serve.ae` serves the static site and the REPL API. It replaces the original
Go/Echo backend entirely.
- Static pages and assets from `static/`.
- `GET /api/lesson/:nbr` returns a lesson `{ title, theory, starter_code }` from `resources/lessons/`.
- `PUT /api/exec` compiles and runs the submitted source with `ae run` and returns `{ stdout, stderr }`. This is the live playground backend.
- `GET /healthz` liveness.
It uses `std.http` (server, routing, zero-copy static files), `std.io`
(lesson files off disk), and `std.json` (escaped responses).
## Run
ae run serve.ae # http://localhost:1323/
or build a binary and run it from the repository root, so `static/` and
`resources/` resolve:
ae build serve.ae -o aesite-serve
./aesite-serve
## Test
./test.sh
Builds `serve.ae`, starts it, exercises every route, and exits non-zero on
any failure. CI runs exactly this.
## Deploy
Pushes to `main` run `.github/workflows/deploy.yml`:
1. build `serve.ae` and run `./test.sh`,
2. publish `static/` to GitHub Pages at **aether-lang.dev**.
The custom domain is set by `static/CNAME`. On the registrar, point the apex
at GitHub Pages with four `A` records: `185.199.108.153`, `185.199.109.153`,
`185.199.110.153`, `185.199.111.153`.
The live REPL backend (`/api/exec` running real Aether) is the next step. It
deploys as the `serve.ae` server on a host of its own, since Pages serves
static content only.
## Playground
`static/repl.html` is a self-contained playground. Lessons load from
`static/lessons.json` (baked by `tools/genlessons.ae`, which also stores each
lesson's real output), so lessons, theory, and a sample run work on a static
host such as GitHub Pages with no server.
On load it probes `/healthz`. If a live `serve.ae` backend answers, Run
executes whatever is in the editor against it; otherwise Run shows the
precomputed output for the unedited lesson and points you at `ae run` for
local execution. To target a backend on another origin, set its URL in the
`` tag and allow CORS there.
Regenerate lessons after editing `resources/lessons/`:
ae run tools/genlessons.ae
## Live backend (optional)
The static site works on its own. To make the playground run *edited* code, deploy
`serve.ae` as a backend and point the site at it.
Deploy with the included `Dockerfile` (the image keeps the Aether toolchain so
`/api/exec` can compile and run code). On Fly.io:
fly launch --no-deploy # once, creates the app from fly.toml
fly deploy
Then set the backend origin in `static/repl.html`:
The playground probes `/healthz` and, when it answers, runs the editor's code there.
`/api/exec` runs ARBITRARY submitted code, i.e. arbitrary native code on the
host. It is hardened, not sandboxed: each request compiles in a fresh temp dir,
then the binary runs as a non-root user in a private network namespace
(`unshare`, no outbound access) under ulimits (CPU, file size) and a 10s
timeout, with output capped. Aether's containment model is language-level and
does not constrain untrusted external programs, so that is deliberately not
relied on here. A public deployment MUST add real OS isolation, e.g.
docker run --rm --read-only --tmpfs /tmp --pids-limit=256 \
--memory=512m --cpus=1 -p 8080:8080 aesite
plus rate limiting, and ideally a per-request microVM (Firecracker/gVisor).
Run it somewhere disposable, never on a host with secrets or writable mounts.
## Docs
`static/Docs/` is generated from the language's markdown docs. Regenerate after
they change:
python3 tools/gendocs.py ~/Documents/git/aether/docs static/Docs
It converts every top-level `*.md` to a styled page (grouped sidebar, syntax
highlighting, cross-links rewritten to `/Docs/*.html`) and refreshes
`static/docs.html`. Output is committed and served as-is by Pages.
## Layout
serve.ae # the Aether server
test.sh # integration smoke test
static/ # HTML, CSS, Docs/, CNAME
resources/lessons// # content.html, code.ae, title.txt
tools/gendocs.py # markdown -> static/Docs/ generator
tools/genlessons.ae # resources/lessons -> static/lessons.json
Dockerfile, fly.toml # optional live exec backend
.github/workflows/ # CI + Pages deploy