Skip to content

feat: lightweight HTTP server for Verso projects - #876

Merged
robsimmons merged 31 commits into
mainfrom
serve
Aug 7, 2026
Merged

feat: lightweight HTTP server for Verso projects#876
robsimmons merged 31 commits into
mainfrom
serve

Conversation

@david-christiansen

@david-christiansen david-christiansen commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Adds a lightweight HTTP server for previewing generated Verso HTML locally, run with lake exe serve. The server binds only 127.0.0.1, reducing the temptation to deploy it to production.

This replaces Python or Node local servers, with defaults that are better-suited to hosting Verso correctly. It also doesn't rely on users having any other programming language ecosystem available.

It can be configured from the command line, or for slightly more complex setups, via serve.toml.

Along the way, this branch encountered a bug in the TeX code generation that needed fixing in order to render the docs for the feature.

ahmedtadde pushed a commit to metroncorp/lean4-verso that referenced this pull request Jul 16, 2026
…r#900)

In writing leanprover#876, @david-christiansen noted "this branch encountered a
bug in the TeX code generation that needed fixing" — but I think the
issue was slightly misdiagnosed, it wasn't a fragility issue, a `]`
anywhere in an item description (including outside of verbatim) caused a
rendering issue because it was read as the description closer.

This fix fixes the bug from leanprover#876, also fixes bugs for `]` in literal
text, and adds a test for the behavior.
Comment thread README.md Outdated
You can preview the resulting files by running
`python3 -m http.server 8000 -d html` and pointing a web browser to
http://localhost:8000/
You can preview the resulting files by running `lake exe serve html`

@robsimmons robsimmons Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do lake exe verso-serve for this. (Todo for me: do the cli arguments to verso-serve make sense?)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Check that no-args serves .)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(it does)

@robsimmons robsimmons left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some documentation comments (which imply some code changes too, especially around removing command-line options to avoid duplication). I'm still not sure every configuration option makes sense for a development-only and/or verso-specific server, but that may be a failure of imagination — and these defaults seem reasonable.

Comment thread doc/UsersGuide/Serve.lean Outdated
Comment thread doc/UsersGuide/Serve.lean Outdated
%%%

Verso includes a small HTTP server for previewing generated HTML on your own machine.
Run it with `lake exe serve`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to verso-serve throughout.

Comment thread doc/UsersGuide/Serve.lean Outdated
Comment on lines +61 to +64
: `DIR`

The directory served at `/`, relative to the current directory. Defaults to the current directory.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is confusing without a USAGE-style line that explains that DIR is a positional argument. Maybe just start "in addition to the directory served, which is given as a positional argument, the following arguments are supported:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the new text addresses this

Comment thread doc/UsersGuide/Serve.lean Outdated

: `--config FILE`

Load configuration from `FILE`. Defaults to `./serve.toml` if it exists.

@robsimmons robsimmons Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Load configuration from `FILE`. Defaults to `./serve.toml` if it exists.
Load configuration from `FILE`. Defaults to `./serve.toml` if it exists. Otherwise uses defaults (see {ref "serve-config"}[Configuration file specification]).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with a somewhat more verbose (and grammatical) alternative.

Comment thread doc/UsersGuide/Serve.lean
Comment thread doc/UsersGuide/Serve.lean Outdated
tag := "serve-config"
%%%

For anything beyond serving a single directory, place a `serve.toml` file next to the project, or point at one with `--config`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Next to the project" assumes verso-serve is being invoked in the folder with lakefile.toml, which isn't necessarily the case.

Suggested change
For anything beyond serving a single directory, place a `serve.toml` file next to the project, or point at one with `--config`.
For anything beyond serving a single directory, create a `serve.toml` file. When `verso-serve` is invoked, it will look for `serve.toml` in the current working directory unless another location is specified with the `--config` {ref "serve-options"}[command line option].

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lake exe only works from the project root, so I think this is actually the right way to do things.

Comment thread doc/UsersGuide/Serve.lean Outdated
Comment thread doc/UsersGuide/Serve.lean Outdated
Comment thread doc/UsersGuide/Serve.lean Outdated
Comment on lines +47 to +55
:::paragraph
As requests arrive, each is logged with the active port, the method, the path, and the response status:

```
[8000] GET /index.html 200
[8000] GET /missing 404
```
:::

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would read better without this section — it's behavior description that will be either obvious to the user or still confusing with this explanation; it would be better to get on to the command-line options.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - it's gone.

@robsimmons robsimmons left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly comments on the docs / spec, i didn't review tests but the Config/Mime/Static/VersoServeMain quartet looks okay modulo questions about docs/spec.

Comment thread doc/UsersGuide/Serve.lean Outdated
Comment on lines +119 to +121
: `banner`

A line shown in the startup banner to identify the project. Must be a string. No banner is shown by default.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like a pretty high documentation-noise to user-value-signal ratio. Was there a use case for a configurable command-line banner you had in mind?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From conversation with @robsimmons: "banner" was initially understood as HTML injection rather than command-line dump. Be more specific here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Scalar flags override the corresponding config values. A positional directory replaces the `/`
mount. If no `/` mount remains, a default one serving the current directory is added, so `/` is
always mapped.
-/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mount-juggling is strange in a function called withCli, and I think if there are any mounts in the config file then lake exe verso-serve should not auto-mount the root directory — and possibly should reject a positional argument altogether. The port winning on the CLI makes sense, but the mount isn't anywhere near so obvious to me.

If the ServeConfig/CliArgs overlap is limited to mounts and ports this could probably be inlined.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The positional argument is now rejected when mounts are configured

Comment thread README.md Outdated
You can preview the resulting files by running
`python3 -m http.server 8000 -d html` and pointing a web browser to
http://localhost:8000/
You can preview the resulting files by running `lake exe serve html`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(it does)

david-christiansen and others added 6 commits August 7, 2026 16:32
Co-authored-by: Robert J. Simmons <442315+robsimmons@users.noreply.github.com>
Co-authored-by: Robert J. Simmons <442315+robsimmons@users.noreply.github.com>
david-christiansen and others added 5 commits August 7, 2026 16:43
Co-authored-by: Robert J. Simmons <442315+robsimmons@users.noreply.github.com>
# Conflicts:
#	test-projects/literate-config/lake-manifest.json
#	test-projects/literate-multi-root/lake-manifest.json
@robsimmons
robsimmons added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit 4ac0364 Aug 7, 2026
11 checks passed
@robsimmons
robsimmons deleted the serve branch August 7, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants