Skip to content

Configuration#

A leptoskit project is configured by one file, leptoskit.toml, at the project root. Every command looks for it in the current directory and then in each parent, so you can run leptoskit from anywhere inside a project.

Every section and every key is optional. Unknown keys are an error, so a typo fails loudly instead of being ignored. New projects include an editor schema directive and schema_version = 0. This schema is unstable: breaking changes are expected until the first version 1 schema.

#:schema https://leptoskit.dev/schemas/leptoskit.v0.schema.json

schema_version = 0

[app]
name = "my_app"
version = "0.1.0"
default_platform = "web"
platforms = ["web", "ios", "android", "macos", "windows", "linux"]
render = "islands"

[serve]
address = "127.0.0.1"
port = 3000

[build]
client_package = "my_app_app"
features = []
rustflags = []

[bundle]
optimize = "smallest"
split = true
wasm_opt = true
precompress = true
budget_kib = 80

[native]
package_id = "com.example.myapp"
viewport_width = 390.0
viewport_height = 844.0

[codepush]
enabled = true
server = "https://updates.example.com"
channel = "production"
mandatory = false
staging_dir = "codepush"
public_keys = [
	"3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
]

[[plugins]]
name = "leptos_meta"
leptos = true

[app]#

KeyDefaultMeaning
namethe directory nameThe root server package name, also used for the package id and release names.
version"0.1.0"The app's semantic version.
default_platform"web"The destination for build. dev runs every platform in platforms it can.
platforms["web", "ios", "android", "macos", "windows", "linux"]Enabled application destinations. Each build selects one destination.
render"csr"How the web build renders: "csr", "ssr", or "islands". New projects set "ssr".
iconnoneOne square PNG or SVG, 1024×1024 or larger, that every platform's icons are made from. See Publishing.

platforms lists the platforms you can build: leptoskit build --platform <platform> refuses one that isn't listed, before compiling anything. default_platform is the one leptoskit build uses without --platform, and it must be in platforms. The list can't be empty or repeat an entry.

Listing a platform doesn't compile anything for it. Each build turns on one platform feature in your app crate, such as ios, and with it that platform's per-platform files.

"harmonyos" is also accepted, for the experimental HarmonyOS starter. It is not in the default list, because the six-platform project has no HarmonyOS app. Older projects may also use "native", which builds the platform in native.targets, or "server", which builds only the web server.

Render modes#

render decides the cargo features each side of a web build gets, following the leptos convention that every leptos app already uses:

renderServer packageClient packageWho serves the app
"csr"no mode featureno mode featureyour server binary, or leptoskit's static server over dist/ without one
"ssr"ssrhydrateyour server binary, rendering each page
"islands"ssr, leptos/islandshydrate, leptos/islandsyour server binary, rendering each page

A client-rendered app with a server package, such as one with an API or sign-in, runs that server under leptoskit dev and leptoskit serve, and the server serves dist/ itself. Without a server package, leptoskit's static server serves dist/.

The server-rendering modes need the server package to declare an ssr feature and the client to declare a hydrate feature, and islands needs both to depend on leptos directly. When one is missing, the build stops and tells you which package needs what. The small bundles guide walks through each mode.

[serve]#

KeyDefaultMeaning
address"127.0.0.1"The IP address to bind. Use "0.0.0.0" to listen on all of them.
port3000The port to bind.

[build]#

KeyDefaultMeaning
client_packageauto-detectedThe wasm client crate. When unset, leptoskit uses the workspace member with a cdylib target; set it when there is more than one.
features[]Cargo features enabled for app builds.
rustflags[]Extra rustc flags for app builds.

[bundle]#

What a release build ships: how hard the wasm client is optimized, how the output is compressed, and how much it may weigh. The small bundles guide explains each setting.

KeyDefaultMeaning
optimize"fast"How hard release builds optimize the client: "fast" (your release profile, then wasm-opt) or "smallest" (adds fat LTO and one codegen unit). Override per build with --optimize.
cargo_profilenoneA cargo profile from your Cargo.toml to compile the release client with, in place of the one optimize picks.
splittrueSplit web #[lazy] code, lazy routes, and #[island(lazy)] into wasm chunks that load on demand. Clients without lazy code skip splitting.
wasm_opttrueWhether release builds run wasm-opt -Oz over the wasm bundle.
precompresstrueWhether release web builds write brotli (.br) and gzip (.gz) copies next to every compressible file.
budget_kibnoneThe most the initial load may weigh, in KiB, brotli-compressed. Release builds over it fail.

[theme]#

Design tokens for Tailwind var(--name) utilities. Omit the table when you don't use custom properties. Keys may be written with or without the leading --; both become --name at runtime.

[theme.colors]
brand = "#3b82f6"
ink = "black"

[theme.lengths]
gap = "1rem"
pad = "16px"
KeyDefaultMeaning
colors{}Color tokens as hex (#rgb, #rrggbb, #rrggbbaa), black, white, or transparent.
lengths{}Length tokens as px, rem, %, vw, or vh.

Install them once at app startup so native paint and the web :root sheet agree:

use leptoskit::prelude::*;

let (config, _) = LeptoskitConfig::load()?;
if let Some(theme) = &config.theme {
	Theme::install_maps(&theme.colors, &theme.lengths)?;
}

Theme::css() emits the same names as a :root rule; the web adapter prepends it automatically when anything is set. See CSS coverage.

[native]#

KeyDefaultMeaning
package_idcom.leptoskit.<name>The reverse-domain application id used by native hosts.
plugins[]Names of runtime plugins installed from direct dependencies of the selected host package.
missing-plugins"warn"What a build does with a listed plugin the platform can't run: "warn" leaves it out, "error" stops.
experimental-rust-pluginsfalseOpts into experimental pure-Rust plugin implementations (objc2 on iOS/macOS, jni on Android) where available.
targets["macos", "ios", "android"]The native platform for the HarmonyOS starter and older projects. Six-platform projects use app.platforms.
viewport_width390.0The initial viewport width for the headless layout pass.
viewport_height844.0The initial viewport height for the headless layout pass.
update_contract"mobile-v1"The native compatibility contract named by code-pushed bundles in runtime.json.

native.package_id defaults to com.leptoskit.<name>, with punctuation removed from the app name. Runtime plugin names belong in native.plugins. Each selected plugin must be a direct Cargo dependency of the selected platform's host package. See automatic plugin registration. A plugin left out of a platform's build answers every call with Unavailable there; set missing-plugins = "error" to fail the build instead, as described in plugins a platform can't run.

Each package id segment starts with an ASCII letter and contains only ASCII letters and digits. Change native.update_contract in a store release when plugin grants or native behavior change incompatibly. Shared app workspaces append the destination, such as mobile-v1/ios, so hosts reject another platform's update bundle.

[codepush]#

KeyDefaultMeaning
enabledfalseWhether the app checks for over-the-air updates.
server""The release registry's base URL. Required when enabled = true.
channel"production"The release channel this build tracks.
mandatoryfalseWhether updates install without asking. The generated mobile hosts don't read it yet; they always wait for the user to activate.
staging_dir"codepush"Where CodePushClient::sync stages updates. The generated mobile hosts keep releases in their own private, non-backed-up app directory instead.
public_keys[]The hex-encoded ed25519 publisher keys whose signed releases the app installs. At least one is required when enabled = true. List two to rotate keys.
allow_httpfalseLets debug native builds reach a plaintext http:// registry, for local development. Release builds always require HTTPS.
provenance—A table requiring independent source approvals before the native app installs a release. See below.

[codepush.provenance]#

Set it to make the iOS and Android apps install only code push releases that enough independent approvers rebuilt from your public GitHub source. Requiring source approvals walks through it.

KeyMeaning
repositoryThe public GitHub repository releases are built from, written as https://github.com/<owner>/<repo>.
approversThe approvers' hex-encoded public keys, as leptoskit codepush keygen --approver prints them. None of them may be in public_keys.
thresholdHow many different approvers must approve each release: at least 1, and at most the number of approvers.

All three keys are required. The app ships the policy, so changing it takes a store release.

[router]#

Deprecated: file routes are now a plugin, activated like any other:

[[plugins]]
name = "router"

[plugins.options]
dir = "src/routes" # optional, the default
output = "src/routes.rs" # optional; the default sits beside the directory

The [router] table still works and leptoskit migrate rewrites it into the plugin form. Without the plugin (or the table), leptoskit leaves src/routes/ alone.

OptionDefaultMeaning
dir"src/routes"The routes directory, relative to the project root. It must stay inside the project, written without . or .., with a module-friendly final segment.
outputbeside dirThe generated module's path, relative to the project root. The default sits beside the directory with the same name, so src/routes/ gets src/routes.rs.

[[plugins]]#

Each [[plugins]] table turns on one build plugin, which hooks into leptoskit build and leptoskit dev: it can generate code before cargo runs, adjust the build's cargo features, environment, and assets, run again before the dev and production servers start, answer its own plugin:<name> commands, and declare the native permissions and dependencies a generated host needs. These are not the runtime plugins that give native apps operating-system services; those are listed in native.plugins (see runtime plugins).

KeyDefaultMeaning
name—The plugin name. Names without a path resolve against the built-ins.
pathnoneA path to a local plugin crate.
leptosfalseMarks a leptos plugin, which is passed to the app build as a cargo feature.
commandnoneThe program answering this plugin's hooks; without it, leptoskit-plugin-<name> is looked up on PATH.
options{}A table of options handed to the plugin.

A plugin as a program#

A plugin with a command — or an executable named leptoskit-plugin-<name> on PATH — is a separate program rather than compiled-in tooling, so anyone can write one in any language. leptoskit runs it once per hook with a JSON envelope on standard input and reads one JSON reply from standard output: generate replies with the files it written, the build hooks reply with extra features, env, and rustflags, and the plugin's own plugin:<name> <command> commands reply with their exit code. A describe hook, asked once when the plugin resolves, declares the plugin's CLI namespace, supported platforms, and commands.

Scaffold one with leptoskit generate tool-plugin <dir>, install it with cargo install --path <dir>, and declare it:

[[plugins]]
name = "demo"
command = "leptoskit-plugin-demo"

Using the configuration from Rust#

leptoskit_config is the library behind the file, so tools and build scripts read exactly what the CLI reads:

use leptoskit_config::LeptoskitConfig;

let (config, root) = LeptoskitConfig::load().expect("a leptoskit.toml in this directory or a parent");
println!("{} at {}", config.app.name, root.display());
esc