Docs/Getting started

Projects & packages

Organize source files, choose a compiler version, and add dependencies.

On this page

A single file is enough for a small program. Once features need their own files, give the project a root directory and a valk.json configuration.

Create a project#

Use this directory structure:

Text
hello/
├── valk.json
└── src/
    ├── main.valk
    └── greetings/
        └── greeting.valk

For the following example, put this in valk.json:

JSON
{
    "use": "0.6.4",
    "namespaces": {
        "greetings": "src/greetings"
    }
}

use pins a compiler version so contributors use the same toolchain. Run vman use from the project root to install or select it. The example uses 0.6.4; choose the version your project targets.

Import a namespace#

Put the greeting function in src/greetings/greeting.valk:

Valk
fn message(name: String) String {
    return "Welcome, %name."
}

Then use that namespace in src/main.valk:

Valk
use greetings

fn main() {
    println(greetings.message("Ada"))
}

A namespace groups the declarations in a directory. Use a dot to access one of its declarations. An import can also introduce a shorter name, such as use greetings as hello.

Build from the project root:

Terminal
vman use
valk build src --run

Control what other code can access#

An unmarked declaration is available inside its package. Add + when a library should expose a declaration to other packages; add - when a helper should stay private to its source file.

Valk
+ fn public_message() String { return "Welcome" }
- fn local_message() String { return "Internal" }

A ~ marker allows other source files to read a declaration while preventing writes from those files. These markers also apply to class properties. Visibility is based on source boundaries, so - does not mean class-private.

Add a dependency#

Use vman from the project directory to manage packages:

Terminal
vman install

With no package argument, this installs the dependencies in valk.json. Use vman install package-url to install a package from its URL. To remove an installed package, use its name: vman remove package-name. Browse vpkg.dev for packages and their import instructions.

Include files in the executable#

#embed reads a file at compile time and places its contents in the program. Paths are relative to valk.json:

Valk
fn main() {
    let license = #embed("LICENSE.txt")
    println(license)
}

#embed_dir("public") does the same recursively for a directory, returning a map from relative filenames to file contents. Rebuild after changing an embedded file. This is useful for shipping templates or web assets with a single executable.