Valet

Deployment

Deploy to production, manage environment variables, and integrate with CI.

bunx valet-dev deploy

The deploy command runs codegen, pushes your schema and handlers to the server, and creates a production project if one does not exist yet. On first run it saves VALET_PROJECT_URL and VALET_DEPLOY_KEY to .env.production.

Deploy command

bunx valet-dev deploy

This does three things:

  1. Runs codegen to generate typed client code
  2. Pushes your schema and handler code to the orchestrator
  3. Applies any schema migrations (new tables, new fields, new indexes)

If the schema has breaking changes (changing a field's validator type), the push fails with an error. Add new fields and migrate data instead of changing existing field types.

Environment files

Valet uses two environment files:

FilePurpose
.envDevelopment credentials (from valet-dev init)
.env.productionProduction credentials (from valet-dev deploy)

Both files contain the same two variables:

# .env.production
VALET_PROJECT_URL=https://fly.valet.host/projects/brave-falcon-leaps-prod
VALET_DEPLOY_KEY=your_deploy_key_here

Credential priority: environment variables > .env.production > .env

Add .env and .env.production to .gitignore. Do not commit deploy keys.

Deploy keys

A deploy key authenticates CLI commands against the orchestrator. Each project has its own deploy key, generated during valet-dev init or valet-dev deploy.

Deploy keys are scoped to a single project. They authorize schema pushes, handler uploads, and environment variable management. They do not grant access to read or write application data.

To rotate a deploy key, contact the orchestrator admin or regenerate through the dashboard.

Project URLs

The project URL identifies your project on the orchestrator:

https://fly.valet.host/projects/brave-falcon-leaps

Pass this URL to ValetProvider in your app — the SDK automatically converts it to a WebSocket connection:

// App.tsx
import { ValetProvider } from './_generated/valet/react'

function App() {
    return (
        <ValetProvider url={process.env.VALET_PROJECT_URL!}>
            <TodoApp />
        </ValetProvider>
    )
}

Development and production projects have separate URLs and separate databases.

Hosted orchestrator

The hosted orchestrator at fly.valet.host manages server instances for your projects:

  • Scale-to-zero: idle projects shut down automatically
  • Scale-on-demand: first connection spawns a server in 1-3 seconds
  • Automatic backups and data persistence
  • No infrastructure to manage

Use the hosted orchestrator unless you have specific requirements for self-hosting.

Self-hosting

Run your own orchestrator for full control over data and infrastructure. The orchestrator is a single binary:

valet-orchestrator \
    --port 5555 \
    --data-dir /var/lib/valet \
    --idle-timeout 300

Point your CLI and app at the self-hosted instance:

bunx valet-dev init --server https://your-orchestrator.example.com
// App.tsx
import { ValetProvider } from './_generated/valet/react'

function App() {
    return (
        <ValetProvider url="https://your-orchestrator.example.com/projects/my-app">
            <TodoApp />
        </ValetProvider>
    )
}

Environment variables

Use valet-dev env to manage server-side environment variables. These are available in server-execution handlers through process.env:

# Set a variable
bunx valet-dev env set GITHUB_CLIENT_ID=abc123

# Set with a separate value argument
bunx valet-dev env set GITHUB_CLIENT_SECRET secret456

# List all variables
bunx valet-dev env list

# Remove a variable
bunx valet-dev env unset GITHUB_CLIENT_SECRET

Server-side environment variables are encrypted at rest and scoped to a single project. Use them for API keys, OAuth secrets, and other sensitive configuration that your server-execution handlers need.

CI integration

Use valet-dev deploy as a prebuild step in your CI pipeline. This ensures codegen runs and the schema is pushed before your app builds.

package.json prebuild script

{
    "scripts": {
        "prebuild": "bunx valet-dev deploy"
    }
}

CI environment variables

In CI environments (Vercel, EAS, GitHub Actions), set VALET_PROJECT_URL and VALET_DEPLOY_KEY as environment variables instead of relying on .env.production:

# .github/workflows/deploy.yml
env:
    VALET_PROJECT_URL: ${{ secrets.VALET_PROJECT_URL }}
    VALET_DEPLOY_KEY: ${{ secrets.VALET_DEPLOY_KEY }}

steps:
    - run: bun install
    - run: bunx valet-dev deploy
    - run: bun run build

The deploy command reads these environment variables automatically. No flags needed.

Vercel

Add VALET_PROJECT_URL and VALET_DEPLOY_KEY to your Vercel project's environment variables. Use the prebuild script in package.json -- Vercel runs it automatically before the build.

EAS (Expo Application Services)

Add the variables to your EAS secrets:

eas secret:create --name VALET_PROJECT_URL --value "https://fly.valet.host/projects/my-app"
eas secret:create --name VALET_DEPLOY_KEY --value "your_deploy_key_here"

Add the prebuild script to package.json. EAS runs it before building your app.

On this page