vlt
vlt is a fast, offline-first Rust CLI for managing .env files across environments using plain text files and project-local rules.
What is in this repo
- The CLI source lives in
src/. - Repo tooling is configured with
rust-toolchain.toml,rustfmt.toml,clippy.toml,.cargo/config.toml, and.github/workflows/ci.yml. - A TypeScript smoke-test fixture lives in
examples/ts-smoke/.
Prerequisites
- Rust stable
clippyandrustfmtcomponents
If you use rustup, the pinned toolchain file will install the right components automatically.
Common commands
Building the CLI
For an optimized binary:
Using vlt
Run vlt from the root of the project whose environment files you want to manage.
1. Initialize a project
This sets up .vlt/, patches .gitignore, adds vlt to .gitignore, and then asks for the first setup step:
Scan all variablesSkip for now
If you scan right away, vlt walks the codebase immediately and builds .env.base.
If you skip, no environment template is created yet.
2. Scan source code for env vars
vlt scan now prompts one variable at a time with an arrow-key selector.
In a real terminal, this prompt uses an arrow-key selector similar to Claude Code:
↑/↓to moveEnterto confirm- choices:
Yes,No,Add all remaining
Approved variables are added to:
.env.basefirst.vlt/env.rulesas discovered string rules so the rest of the CLI can keep working
--apply skips the selector and adds every discovered missing variable automatically.
If scan is run in a non-interactive context, use --apply.
.env.base includes a warning comment because it is the template vlt uses when scaffolding environment files.
3. Create another environment
4. Generate an example file
This writes .env.example with all known keys and comment metadata from .vlt/env.rules.
5. Activate an environment
This copies .vlt/env.<name> to .env and records the active environment in .vlt/config.toml.
6. Inspect status
This shows:
- the active environment
- available environments
- missing values in the active environment
- drift between
.envand.vlt/env.rules
7. Compare environments
This compares keys only and never prints secret values.
8. Sync missing keys
This adds keys that exist in the source environment but not in the target environment. New keys are added as blank placeholders so you can fill them safely.
9. Validate the active .env
This checks required values, booleans, ints, floats, and enums against .vlt/env.rules.
10. Import or export environment files
import loads values from an existing env file into .vlt/env.<name> and updates project templates for any new keys.
export writes .vlt/env.<name> to a standalone env file at the path you choose.
Testing with the included TypeScript fixture
Yes, you can absolutely keep a TypeScript project inside this repo to test vlt.
The safest pattern is to keep test apps under examples/ or fixtures/ so they are clearly separate from the Rust crate. This repo includes one already:
You can also use cargo run instead of building first:
The included fixture already contains a committed .env.base and .vlt/ directory, so you can inspect a realistic nested project immediately and rerun init or scan safely because init is idempotent.
Notes on nested test apps
- Running
vltalways affects the current working directory, not the Rust repo root, so nested test apps are fine. - The scanner already skips
.git,target,node_modules, and.vlt. - If you scaffold additional test apps, prefer
examples/<name>/so they stay isolated. - If you later create large fixtures, consider adding per-fixture
.gitignorefiles fornode_modulesand build output.