Venvs are named, reusable execution environments for
DAL. Each venv has a project root, a dependency
set (from that project’s dal.toml /
dal.lock), and a security profile. Running
a script “in a venv” uses that environment every time, so you get
consistent deps and clear security boundaries.
# Create a venv for the current directory (default profile: relaxed)
dal venv create myvenv
# Run a script inside that venv (script path is relative to your current directory)
dal venv run myvenv ./scripts/task.dal
# List venvs
dal venv list
# Show one venv
dal venv show myvenv
# Remove a venv (does not delete files on disk)
dal venv delete myvenvA venv is a named environment that defines:
| What | Meaning |
|---|---|
| Root | A project directory. Imports and dependency resolution use this as the project root. |
| Dependencies | Resolved from that root’s dal.toml and
dal.lock when you run a script. |
| Profile | Security rules: which built-in namespaces are allowed (see Profiles). |
When you run dal venv run myapp script.dal, DAL uses
myapp’s root and dependencies to resolve imports, and
applies myapp’s profile. The script file itself is
located relative to your current working directory;
only imports inside the script use the venv’s root and deps.
All venv commands live under dal venv:
| Command | Description |
|---|---|
dal venv create <name> [--dir <path>] [--profile strict|relaxed] |
Create a venv. --dir defaults to the current directory.
--profile defaults to relaxed. |
dal venv list |
List venvs (project-local, then global if configured). |
dal venv show <name> |
Show a venv’s root and profile. |
dal venv run <name> <script.dal> |
Run a script inside the venv. |
dal venv delete <name> |
Remove the venv from the registry (no files are deleted). |
Serve with a venv: You can run the HTTP server in a venv so that the served DAL file and its imports use the venv’s root and profile:
| Command | Description |
|---|---|
dal serve <file.dal> [--port N] --venv <name> |
Serve the DAL file’s HTTP handlers using the named venv (root for imports, profile for runtime). |
myapp, ci)../other-project)
or absolute.strict or
relaxed (default: relaxed).If the root has no dal.toml, you’ll get a warning;
dependency resolution may fail when you run scripts until you add one
(e.g. dal init).
dal, not relative to the venv root.Example: from /home/me, running
dal venv run myapp ./work/task.dal runs
/home/me/work/task.dal; any import foo in
task.dal is resolved from the myapp venv’s
project root and its lockfile.
| Profile | Use case | What’s allowed |
|---|---|---|
| relaxed | Normal development, trusted scripts | All stdlib namespaces (current default behavior). Shell and FFI follow your normal config. |
| strict | CI, untrusted code, least privilege | Only a fixed set of stdlib namespaces (e.g. chain,
crypto, log, config,
key, auth, evolve,
sync, json, test). No
sh, no stdlib service. User-defined services
(your own types) are still allowed. |
--profile.namespace 'X' not allowed in this venv profile (strict)..dal/venvs.json in the directory where you run
dal venv create. That file maps venv names to
root and profile.DAL_VENV_REGISTRY to a file path, or use the default
~/.config/dal/venvs.json (or your platform’s config dir).
When you run dal venv run <name>, DAL looks up the
name in project-local first, then in the global registry.So “create once, run many” means: create a venv (stored in
.dal/venvs.json or the global registry), then run any
script in that venv with
dal venv run <name> <script.dal>.
Create a venv for the current project (relaxed):
dal venv create myvenvCreate a strict venv for CI:
dal venv create ci-env --dir . --profile strict
dal venv run ci-env ./tests/suite.dalCreate a venv for another project:
dal venv create other --dir ../other-project --profile relaxed
dal venv run other ./scripts/run.dalList and inspect:
dal venv list
dal venv show myvenvDelete a venv:
dal venv delete myvenvServe an HTTP app in a venv:
dal venv create myapp
dal serve server.dal --port 4040 --venv myapp