# Roadmap

Milestones are ordered; items within a milestone are not. Nothing here is a release commitment or a date. The [live roadmap](https://github.com/Varyk-Lang/varyk/blob/main/docs/roadmap.md) in the compiler repository tracks progress item by item.

## Milestone 1: compiler skeleton and the borrow-by-default proof

**Complete, released as 0.0.1.** A minimum viable compiler that validates the central idea with six small programs: the [examples](/learn/examples/). Lexer and parser, resolver, type checker and borrow analysis, the `println!` intrinsic, `mod` resolving to `.vr` or `.rs` files, import of top-level `pub fn` signatures from Rust modules, a Rust backend writing a Cargo project under `target/varyk/`, diagnostics with codes and fix-its, `--message-format=json`, and the `varyk check`, `build`, and `run` commands.

## Milestone 2: enums, matching, methods, and collections

**Complete, released as 0.0.2.** The language core a small program needs: enums with unit and tuple variants, `match` on enums, `Option`, and `Result`, with a forgotten variant caught by Varyk before cargo runs, `for` over ranges and `Vec`, `impl` blocks with `self` and `mut self` methods, `Option`, `Result`, and `Vec` with a small table of methods and indexing, `usize`, `?`, `format!` and `vec!`, `s.clone()` as the one explicit string copy, and the rule that a name taken from part of a value cannot outlive a change to the whole. Six more example programs.

## Milestone 3: packages and interop

**Complete, released as 0.1.0.** Varyk code never names a crate; a dependency is used from a `.rs` facade in the same package. `Cargo.toml` as the package manifest, with `src/main.vr` or `src/lib.vr` as the root, edition 2024, and `[package.metadata.varyk]` reserved; Cargo dependencies reached from `.rs` facades, with `Cargo.lock` shared with cargo; nested modules and `mod.vr` directories, `pub mod`, and `use` for paths inside the package; field-level `pub`; import of Rust structs, their inherent methods, and enums from `.rs` modules; errors rustc finds in the generated Rust mapped to Varyk source as V0900, the user's own `.rs` errors and warnings shown at their file, and item-level lint allows on generated code; `varyk init` with a `build.rs` so plain `cargo build` works, and `varyk emit`, both removed in milestone 5b2; `varyk publish`, which publishes binaries and libraries as plain Rust crates with the generated `.rs` and the `.vr` sources included; and three example packages. This site's pitch, install page, and language reference are part of it. Its release is 0.1.0, because private fields are a breaking change.

## Milestone 4: closures, iterators, and patterns

**Complete, released as 0.2.0.** The language only; the former milestone-4 tooling and interop items moved to milestones 5 and 6. Closures as the arguments of built-in calls, with untyped parameters and shared captures, never a value of their own; iterator chains on stored values, from `iter`, `split`, `keys`, and `values` through `map` and `filter` to `collect`, `count`, `sum`, `any`, `all`, and `find`, or as the head of a `for`; borrowed return values inferred from the body, with a lifetime in the generated Rust only where elision would not name it; `if let` and `while let`; enum variants with named fields, nested, literal, and `..=` range patterns, `match` on numbers, `bool`, and strings, with exhaustiveness and reachability checked by Varyk; `?` on `Option`; the `Option` and `Result` methods and new `Vec` and `string` calls, `parse` included; `HashMap`; `as` between number types; `Clone` and `PartialEq` derived where every field allows, so `.clone()` and `==` work on structs and enums; import of Rust signatures returning `&str` or `&S` where lifetime elision names the parameter; a test asserting the language reference mentions every keyword, built-in type, table call, and diagnostic code; and six new example programs.

## Milestone 5: batteries for services

Milestone 5 is six milestones. The bar for the whole of it is one golden path: a users API on a database is `varyk init`, `varyk add http sql`, one file, and `varyk run` away, within fifteen minutes of `cargo install varyk`, and `varyk build --release` leaves an ordinary native executable. It is met when 5b4 and 5c are done, and promotion waits for it.

### Milestone 5a: data, configuration, logging, and tests

**Complete, released as 0.3.0.** The `varyk-std` crate, and the `varyk-std` dependency in every package, whose version and lock `varyk check` reads; `Error`, one built-in error type with a message, and `parse` returning a `Result`; the attributes `#[rename]`, `#[default]`, `#[skip]`, and `#[test]`; serde derivation for the types a `json` or `env` call reaches; JSON through `json::parse` and `json::stringify`; configuration from the environment and `.env` through `env::parse`; logging via tracing, with `log::debug`, `info`, `warn`, and `error`; `varyk test`, with `assert` and `assert_eq`; `varyk add`, a pass-through to `cargo add`; and the examples `json`, `config`, and `logging` and the `users` package. Its release is 0.3.0, because `parse` returning a `Result` is a breaking change.

### Milestone 5b1: async

**Complete, released as 0.4.0.** `async fn` and `.await` on a built-in multi-threaded tokio runtime, with `Send`, `Sync`, and `Pin` kept out of the surface syntax; started calls, where a call to an async function without `.await` starts it at once and gives a `Task<T>`; tasks cancelled when dropped, `detach` to let one run on its own, `Task::all` and `Task::all_settled` to wait on many; `Shared<T>` for a read-only struct held by many tasks; `time::sleep`; `pub async fn` imported from `.rs` modules; and the examples `tasks`, `fanout`, and `shared`. Both questions it was gated on are answered: the runtime is multi-threaded, and ownership transfer needs no syntax, because the arguments of a started call are the one place a value is handed over. Its release is 0.4.0, because `Task`, `Shared`, and `time` become reserved names.

### Milestone 5b2: packages

**Complete, released as 0.5.0.** A Varyk package named from Varyk code by its `Cargo.toml` key, with `-` read as `_`, to any depth: `units::length::add(a, b)` calls into the package `units`, and packages may use packages. Varyk packages compiled by `varyk` from their `.vr` sources, each as a crate of its own, never from Rust a publisher shipped or a build script; a Varyk package reached any other way, through `[dev-dependencies]`, as an `optional` dependency, or through a Rust crate, refused. Packages built only by `varyk`: `Cargo.toml` names the `.vr` root as cargo's target, `varyk init` writes no `build.rs` or stub, and `varyk emit` is removed. The examples' Rust stops calling `expect`, and the examples `route` and `trip`. It also redraws milestone 5: HTTP and the database move to packages in 5b3 and 5b4, because `varyk-std` stays the small runtime every program has, and anything heavy is a package the writer adds. Official packages are named `varyk-*` and community packages `*-varyk`. Its release is 0.5.0, because a package's `Cargo.toml` must now name its `.vr` root and `varyk emit` is gone.

### Milestone 5b3: facades and `varyk-sql`

**Complete, released as 0.6.0, with `varyk-sql` released as 0.1.0.** What a `.rs` facade can say: a function or method with one type parameter standing for any Varyk data type, chosen from where the result goes; a last parameter that takes any number of scalar values (`varyk_std::Value`); a `&'static str` parameter that takes only text written in the program; and `varyk_std::Error` as the error type of a function's result. `pub use` in a `.vr` file, and `varyk add sql`. Then `varyk-sql`, in [its own repository](https://github.com/Varyk-Lang/varyk-sql), on sqlx, with SQLite, Postgres, and MySQL each a cargo feature: `connect` and `connect_with`, `migrate`, `begin` and `commit`, and on a pool or a transaction `one`, `first`, `all`, and `run`, each taking the query and its values; rows read into structs by column name; each database's own placeholders, passed through (since `varyk-sql` 0.4.0, released after milestone 5, `$1`, `$2`, and so on work on every database, and `?` still works on SQLite and MySQL); the query text a literal, so a query built from input is a compile error; and no secret in an error message. The `Serialize` half of the type parameter, for sending a Varyk value out, moves to 5b4, where the HTTP client needs it.

### Milestone 5b4: `varyk-http` and the golden path

**Complete, released as 0.7.0, with `varyk-http` released as 0.1.0.** The compiler: a route table, the `App` of the `varyk-http` package known to the compiler by its crate name; `get`, `post`, `put`, `patch`, and `delete` routes with `{name}` segments; a handler's parameters bound by name to the path and the query string, and by type to the JSON body, to the state (a `Shared<T>`), and to the package's own types; the return value as the response, `None` as 404, and `http::Response` for a custom status and headers; every route checked against its handler by `varyk check`; `before`, `before_on`, and `after` hooks, and `app.request` for tests; `Error` carrying an optional status, set by `Error::with_status` and the `http::` constructors written over it, where an error without one is a 500 whose message is logged and not sent; a `.rs` function with a type parameter `&T: Serialize` in a parameter (moved from 5b3), and a `.rs` function returning `varyk_std::Error`; and `varyk add http sql`, several official packages in one call. Then `varyk-http`, in [its own repository](https://github.com/Varyk-Lang/varyk-http): the server on axum and tower-http, with tracing, a body limit, a timeout, panic containment, and graceful shutdown on by default, and CORS, compression, metrics, the address (`127.0.0.1` unless set), the limits, and a maximum of requests in flight by one call; cookies with secure defaults and `Response::file`; the client on reqwest with rustls; WebSockets, server-sent events, and multipart uploads, text and files until a bytes type exists; and the `users` API on `varyk-sql` as its demo, with the fifteen-minute path in its README. `varyk-sql` 0.2.0 ships with it, on the same `varyk-std`. Still to come, as its own work in its own repository: an agent evaluation, the examples written by a model from the language reference alone with pass rates published, before any page claims that agents write Varyk well. After 5b4 come [the next packages](#the-next-packages).

### Milestone 5c: time, ids, and bytes

**Complete, released as 0.8.0, with `varyk-sql` released as 0.3.0 and `varyk-http` as 0.2.0.** What a production API needs that the language lacked, so that the users API does not ship `created_at` as a string. The compiler: three built-in types, reserved names as `Error` is. `Time`, one point in time in UTC to the microsecond: `now`, `from_iso`, `from_unix`, `from_unix_micros`, `to_iso`, `to_unix`, `to_unix_micros`, `add_seconds`, `seconds_since`, `parse`, comparison, and RFC 3339 in JSON and `env`. `Uuid`: `new`, a time-ordered version 7, `v7`, `v4`, the random one by name, `parse`, a map key, and the hyphenated form in JSON and `env`. `Bytes`, immutable: `from_text`, `from_base64`, `to_text`, `to_base64`, `len`, `is_empty`, and base64 in JSON. The three in trailing values, route parameters (`Time` and `Uuid`), and facade signatures; `varyk-std` 0.8; and the example `records`. Then the packages, each in its own repository: `varyk-sql` 0.3 drops sqlx's `Any` driver for concrete pools, and stores the three types as native columns, `timestamptz`, `uuid`, and `bytea` on Postgres; `varyk-http` 0.2 reads `Time` and `Uuid` path and query parameters, and adds bytes bodies, uploads, and binary WebSocket messages, and bytes for its client, with `created_at: Time` in its `users` demo. With both, 5b4 and 5c are done, and milestone 5's bar is met. A calendar date, a duration, and time zones are not in it; each waits for a program that needs it.

## The next packages

Not a milestone: packages that came after milestone 5, each in its own repository and released on its own.

- **`varyk-mongo`, released as 0.1.0**, in [its own repository](https://github.com/Varyk-Lang/varyk-mongo), on the official `mongodb` crate: the MongoDB package, with documents written from structs and read back into them; filters, updates, and aggregation pipelines in MongoDB's own syntax, as literal text with `?` where a value goes and the values beside it; `Time`, `Uuid`, and `Bytes` stored as native BSON dates and binaries; indexes; and transactions, which need a replica set. It needs Rust 1.88, for the driver. The compiler side came as two patch releases: Varyk 0.8.1, where `Time`, `Uuid`, and `Bytes` keep their type when a serializer is not JSON, and Varyk 0.8.2, with `varyk add mongo`.
- **`varyk-sql` 0.4.0**, in [its own repository](https://github.com/Varyk-Lang/varyk-sql): `$1`, `$2`, and so on, on every database, and `?` still on SQLite and MySQL.

`varyk-redis` is next.

## Milestone 6: tooling and beyond

In progress, and not scheduled.

- **Released as 0.9.0:** `varyk lsp`, the language server's first stage: diagnostics and quick fixes when a file is opened or saved, in any editor that speaks the Language Server Protocol, with extensions for VS Code and Zed in [`varyk-editors`](https://github.com/Varyk-Lang/varyk-editors); a package's `varyk-std` line names the oldest varyk it needs, so a minor varyk release does not stop it from building; and Rust 1.88 as the oldest supported Rust.

Still planned: `varyk fmt`, a deterministic formatter on `varyk-syntax`; the rest of the language server, hover, go-to-definition, and completion, which need error recovery in the parser; nested modules in `.rs` files; import of Rust tuple and unit structs; `Debug` on imported Rust structs, with a `{:?}` placeholder; and a decision on a native backend. Direct import of a published Varyk library from Varyk, once listed here, arrived in milestone 5b2.

## Unscheduled

Declaring generics, traits, and attributes of your own in Varyk code, and using a Rust crate directly from Varyk code, with no facade `.rs` module in between. Each waits on an open question in the specification; the four attributes milestone 5a added are the compiler's own, and only the compiler defines attributes. Using a crate directly is an experiment for after traits exist, because most crate APIs are generic; the facade rule stands until that experiment says otherwise. TOML is unscheduled too, beside the rest of the cuts the [language reference](/learn/reference/#not-in-milestone-5c) lists under "Not in milestone 5c": nothing on the golden path needs it, and the same machinery adds it later. Also unscheduled: `Box`, until a program needs a recursive type that `Vec` or `HashMap` cannot hold, and the rest of the milestone-4 cut list, a character type, closures as values, tuples, `HashSet`, and the remaining iterator adapters. `.rs` signatures naming Varyk-declared types moved here from milestone 5b2, because the type parameter of milestone 5b3 makes them unnecessary for what a facade needs. JWT verification and password hashing are facades over `jsonwebtoken` and `argon2` in the service that needs them, to become packages if people keep writing the same facade. A document literal in the language, with values written inline, for MongoDB and JSON, is unscheduled too: `varyk-mongo` builds its documents from structs until then, and the literal's shape is an open question. So is `{name}` capture in `println!` and `format!`, the Rust 1.58 form, inside the `{}` syntax the language has.
