CLI Reference
All valet-dev commands, flags, and environment variables.
# terminal
bunx valet-dev codegen --watchThe valet-dev CLI handles project initialization, code generation, deployment, and environment variable management. All commands run locally and communicate with the server for server-side operations.
valet-dev init
# terminal
bunx valet-dev initScaffolds a valet/ directory in the current project with a starter schema.ts and example function file. Appends _generated/ to .gitignore if present.
By default, init registers a new project on the managed platform (with an auto-generated name like brave-falcon-leaps) and writes the resulting VALET_PROJECT_URL and VALET_DEPLOY_KEY to a .env file in the project root. Subsequent commands like valet-dev codegen run with no flags.
If you already have a running valet-server (self-hosted or provisioned separately), use --project-url to skip registration and connect directly:
# terminal
bunx valet-dev init --project-url https://my-server.example.com --deploy-key abc123For Expo projects (detected by the presence of expo in package.json dependencies), init also writes EXPO_PUBLIC_VALET_PROJECT_URL to .env. Expo requires the EXPO_PUBLIC_ prefix for environment variables to be accessible in your app.
Flags
| Flag | Default | Description |
|---|---|---|
--dir <name> | valet | Name of the valet directory to create. |
--server <url> | https://fly.valet.host | Orchestrator URL to register a new project with. |
--project-url <url> | -- | Use an existing valet-server URL directly (skips registration). |
--deploy-key <key> | -- | Deploy key for the project (used with --project-url). |
--help, -h | -- | Show help. |
valet-dev codegen
# terminal
bunx valet-dev codegen --watchGenerates typed client code from your schema and functions, and pushes them to the server.
Codegen reads valet/schema.ts and all function files, then produces typed hooks, API references, and handler registries in the output directory. If a server URL and deploy key are available, it also pushes the schema and functions to the server.
Flags
| Flag | Default | Description |
|---|---|---|
--valet-dir <path> | ./valet | Path to your valet directory. |
--output-dir <path> | ./_generated/valet | Where to write generated files. |
--project-url <url> | $VALET_PROJECT_URL | Project URL to push schema and functions to. |
--deploy-key <key> | $VALET_DEPLOY_KEY | Deploy key for server push. |
--watch, -w | -- | Watch for changes and regenerate. |
--help, -h | -- | Show help. |
Custom directories
# terminal
bunx valet-dev codegen --valet-dir src/valet --output-dir src/_generated/valetvalet-dev deploy
# terminal
bunx valet-dev deployBuilds and pushes schema and functions to a production project.
For self-hosted valet-server instances, use --project-url to deploy directly:
# terminal
bunx valet-dev deploy --project-url https://my-prod.example.com --deploy-key abc123On the managed platform, deploy auto-registers a production project on first run and saves credentials to .env.production. Subsequent runs push to the existing production project.
Flags
| Flag | Default | Description |
|---|---|---|
--valet-dir <path> | ./valet | Path to your valet directory. |
--output-dir <path> | ./_generated/valet | Where to write generated files. |
--project-url <url> | -- | Deploy to this project URL directly (skips registration). |
--deploy-key <key> | -- | Deploy key for the project (used with --project-url). |
--help, -h | -- | Show help. |
CI usage
// package.json
{
"scripts": {
"prebuild": "bunx valet-dev deploy"
}
}In CI environments (Vercel, EAS, etc.), set VALET_PROJECT_URL and VALET_DEPLOY_KEY as environment variables instead of relying on .env.production.
Credential priority
Deploy resolves credentials in this order:
- Environment variables (
VALET_PROJECT_URL,VALET_DEPLOY_KEY) .env.production.env
valet-dev env
# terminal
bunx valet-dev env set GITHUB_CLIENT_ID=abc123
bunx valet-dev env set GITHUB_CLIENT_SECRET secret456
bunx valet-dev env list
bunx valet-dev env unset GITHUB_CLIENT_SECRETManages server-side environment variables (e.g., OAuth client secrets, API keys). These variables are available to your server-side query and mutation handlers.
Subcommands
| Subcommand | Description |
|---|---|
env set KEY=VALUE | Set an environment variable (single-argument form). |
env set KEY VALUE | Set an environment variable (two-argument form). |
env unset KEY | Remove an environment variable. |
env list | List all environment variables for the project. |
Flags
| Flag | Default | Description |
|---|---|---|
--project-url <url> | $VALET_PROJECT_URL | Project URL. |
--deploy-key <key> | $VALET_DEPLOY_KEY | Deploy key for authenticated requests. |
--project <id> | $VALET_PROJECT_ID | Project ID for scoped secrets. |
--help, -h | -- | Show help. |
valet-dev auth
# terminal
bunx valet-dev auth initAdds authentication to an existing Valet project.
Subcommands
auth init
Adds authTables to your schema.ts import and spreads it into defineSchema(). Creates a valet/auth.ts file with a starter defineAuth configuration.
If your schema already includes authTables, the import is skipped. If auth.ts already exists, it is left untouched.
Flags
| Flag | Default | Description |
|---|---|---|
--dir <name> | valet | Name of the valet directory. |
--external | -- | Skip authTables and auth.ts creation (for Firebase, Clerk, or other external JWT providers). |
--help, -h | -- | Show help. |
External auth providers
If you use Firebase, Clerk, Auth0, or another external auth provider, pass --external to skip authTables injection and auth.ts creation. ctx.auth is still populated from the validated JWT — no Valet-specific auth tables are needed.
# terminal
bunx valet-dev auth init --externalEnvironment variables
| Variable | Description |
|---|---|
VALET_PROJECT_URL | Full project URL for codegen server push. Overridden by --project-url. |
VALET_DEPLOY_KEY | Deploy key for authenticated pushes. Overridden by --deploy-key. |
If a .env file exists in the project root with VALET_PROJECT_URL and VALET_DEPLOY_KEY, all commands use them as defaults. After valet-dev init, you can run valet-dev codegen with no flags.
Generated files
After running codegen, _generated/valet/ contains:
Always generated
| File | Description |
|---|---|
api.js | Runtime API object with function references. |
api.d.ts | TypeScript types for the API and data model. |
schema.json | Serialized schema for the server. |
react.js | Pre-configured React provider and hooks. |
react.d.ts | React type declarations. |
Generated when functions are defined
| File | Description | Condition |
|---|---|---|
handlers.js | Handler registry for local query and mutation execution. | When local queries or mutations exist. |
handlers.d.ts | Handler type declarations. | When local queries or mutations exist. |
functions.json | Serialized handler code for the server. | When any queries or mutations are defined. |
Watch mode
# terminal
bunx valet-dev codegen --watchIn development, run with --watch to regenerate on file changes. The watcher:
- Runs initial code generation.
- Pushes schema and functions to the server.
- Watches
valet/for.tsfile changes. - Debounces rapid changes (100ms).
- Regenerates and re-pushes on each change.
Press Ctrl+C to stop.
Server push
Codegen pushes two payloads to the server:
/api/functions-- handler code for server-side execution./api/schema-- table definitions, indexes, and sync configurations.
The server responds with migration status:
Pushed schema (3 tables) to server
+ Created table: comments
+ Added column todos.priority
~ Backfilled todos.priority (150 rows)If there are breaking changes (type changes on existing columns), the push fails:
ERROR: Schema push failed — breaking changes detected:
x Type change on todos.completed: number -> boolean
Hint: Add new columns with the desired types and migrate data.Deprecated: valet-codegen
The standalone valet-codegen binary is deprecated. Use valet-dev codegen instead -- it accepts the same flags. The old binary prints a deprecation warning and continues to work.
Troubleshooting
"schema.ts not found"
Error: schema.ts not found in ./valetYour valet directory does not contain a schema.ts file. Verify the --valet-dir flag points to the correct directory, and that the directory contains a schema.ts file that exports a schema via defineSchema().
# terminal
ls valet/schema.ts"Could not reach server"
Error: Could not reach server at https://fly.valet.hostThe server URL is unreachable. Codegen still generates local files; only the server push fails. Check that the URL is correct and that the server is running.
# terminal
curl -s -o /dev/null -w "%{http_code}" https://fly.valet.host/health"401 Unauthorized"
Error: 401 UnauthorizedThe deploy key is missing or invalid. Set the --deploy-key flag or the VALET_DEPLOY_KEY environment variable.
# terminal
bunx valet-dev codegen --deploy-key your-deploy-key-here"409 Conflict"
Error: 409 Conflict — breaking schema changes detectedYou attempted a breaking schema change (e.g., changing a column's type from v.number() to v.boolean()). Breaking changes are not supported directly. Add a new column with the desired type and migrate data instead.
// valet/schema.ts
import { defineSchema, defineTable, v } from 'valet-dev/server'
// Instead of changing completed from number to boolean,
// add a new column and backfill it:
export default defineSchema({
todos: defineTable({
title: v.string(),
completed: v.number().deprecated(),
isCompleted: v.boolean(),
})
.backfill('isCompleted', (doc) => doc.completed === 1),
})