vilan is a language for building full-stack web apps. It compiles to
JavaScript and runs on node and in the browser, but it is not JavaScript:
values are copied instead of shared, there is no null and no exceptions,
await is implicit, and the compiler checks the things you usually find
out at runtime.
It ships as one coherent stack. The language, a standard library, a fine-grained reactive UI layer, typed compile-time styling, an enum-based router, a service layer where the server exposes live-synced state and typed rpc methods from a single struct — no REST endpoints, no schema files, no client SDK to regenerate — and a dev loop to match: save a file and the running browser app updates in place, reactive state intact.
Status: fast-moving alpha. The language changes weekly and there are no stability promises yet. It is, however, real: the test suite holds ~1,500 tests, every example in the documentation is compiled by CI, the compiler front end is handwritten (a full build of the example client is ~0.2 s), and the repo contains a working full-stack example app.
Reactive state, from the first page of the guide:
import std::print;
import std::reactive::{ Signal, Owner, run_with_owner };
fun main() {
let count = Signal::new(0);
let owner = Owner::new();
run_with_owner(owner, || {
count.effect(|value: i32| print(value));
});
count.set(1);
count.set(2);
}
And the full-stack model — one struct is the entire client/server
contract. Exposed signals mirror live to every connected client, and
[rpc] methods are callable remotely with typed results:
[service(NotesClient)]
struct NotesStore {
[expose] notes: Signal<List<Note>>,
…
}
impl NotesStore {
[rpc]
fun add_note(self, token: str, title: str): i32 { … }
}
// browser side:
let client = NotesClient::connect("/", json_codec())!;
let _sync = client.notes.sub(|list| …); // live-synced, typed
The full-stack walkthrough builds a
working notes app — sign-in, live sync between windows, an editor that
saves as you type — in about 500 lines, and that app lives in
vilan/examples/walkthrough/ where the
test suite builds it on every run.
- Values copy. Assigning or passing data gives the receiver its own copy. Sharing is explicit and typed — a whole class of spooky-action-at-a-distance bugs doesn't exist.
- One law behind the memory model. Every alias is a claim on an owner;
views are the statically-proven claims, handles the checked ones — and a
resource(a database handle, a task nursery) has exactly one owner and cleans up deterministically at scope end, with the double-close family rejected at compile time. - No
null, no exceptions. Absence isOption, failure isResult, and the!and?.operators keep both ergonomic. awaitis implicit. Calling an async function just gives you the value. You only writeasyncto opt out of waiting.- Fine-grained reactive UI. Signals bind to individual DOM properties. No virtual DOM, no re-renders, and cleanup is automatic by construction.
- The wire is checked. Payload types derive
Wire; client and server compare a contract hash at connect; mirrors resync themselves after reconnects. - The loop is hot.
vilan run --watchrebuilds in a fraction of a second, hot-swaps the browser with module state carried across, shows compile errors in-page, and restarts the server leg while the client reconnects on its own. - Docs that can't rot. Every example in the book is compiled by the test suite.
Install the toolchain (Linux, macOS, or Windows; you'll also need node to run what you build) — on Linux and macOS:
curl -fsSL https://github.com/vilan-lang/vilan/releases/latest/download/install.sh | shand on Windows, in PowerShell:
irm https://github.com/vilan-lang/vilan/releases/latest/download/install.ps1 | iexThat puts vilan and vilan-lsp in ~/.vilan/bin — on Windows,
%USERPROFILE%\.vilan\bin. The unix script prints the PATH line to add;
the PowerShell one adds the directory to your user PATH itself, so open a
new terminal afterwards. Update any time with vilan upgrade (it only touches the
network when you run it). Each release
also carries vilan-vscode.vsix — the VS Code extension: highlighting,
diagnostics, hover with docs on everything (keywords included),
go-to-definition, rename, call-shaped completion with signatures, inlay
hints, semantic tokens, Organize Imports, and a formatter — all of it
still working while the file has errors. Installed via "Extensions:
Install from VSIX".
Or build the project from source (Rust required) with:
git clone https://github.com/vilan-lang/vilan
cd vilan
cargo install --path crates/vilan-cli # installs the `vilan` binaryThen put this in hello.vl:
import std::print;
fun main() {
print("hello");
}
and run it:
vilan run hello.vlFor a full-stack project, vilan run --watch . is the whole dev loop —
rebuild, hot-swap the browser, restart the server — described in
the dev-loop guide.
From there, read the book. It starts with Coming from JavaScript and ends with the full-stack walkthrough:
- Rendered (search + sidebar): https://vilan-lang.github.io/vilan/ —
or locally,
cargo install mdbook && mdbook serve vilan/docs. - As files: start at vilan/docs/README.md.
crates/
vilan-core/ the compiler: lexer → parser → analyzer → transformer
vilan-cli/ the `vilan` binary (build / check / run / fmt / test)
vilan-lsp/ the language server
editors/vscode/ the VS Code extension (grammar + LSP client)
vilan/
std/ the standard library, written in vilan
docs/ the book: tour, guides, reference, spec (mdBook)
examples/ runnable examples, incl. the walkthrough app
test/ the codegen corpus (byte-identical golden files)
proposal/ design documents — how and why things were built
.github/ CI: docs build + deploy to Pages
cargo test # the whole suite: compiler, corpus, docs gate, examplesThree test layers keep the project honest: unit and behavior pins in
crates/vilan-core/tests/, a golden-file codegen corpus in vilan/test/
(byte-identical, deliberately), and the docs gate, which extracts and
compiles every fenced example in vilan/docs/ — including the ones on
this page.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
The vilan logo, wordmark, and the other brand assets under assets/branding/ are excluded from the above and are covered by their own license instead.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in vilan by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.