Skip to content

vilan-lang/vilan

Repository files navigation

vilan

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.

A taste

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.

Why it feels different

  • 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 is Option, failure is Result, and the ! and ?. operators keep both ergonomic.
  • await is implicit. Calling an async function just gives you the value. You only write async to 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 --watch rebuilds 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.

Getting started

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 | sh

and on Windows, in PowerShell:

irm https://github.com/vilan-lang/vilan/releases/latest/download/install.ps1 | iex

That 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` binary

Then put this in hello.vl:

import std::print;

fun main() {
	print("hello");
}

and run it:

vilan run hello.vl

For 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:

Repository structure

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

Development

cargo test    # the whole suite: compiler, corpus, docs gate, examples

Three 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.

License

Licensed under either of

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.

About

Source for the Vilan language spec, compiler, and docs.

Topics

Resources

Code of conduct

Stars

Watchers

Forks

Releases

Contributors

Languages