Skip to main content

Dev commands

The dev block on a service lets you override the production command for local development. This is where you use hot-reload servers, watch modes, or any command optimized for a fast feedback loop.
service "web" {
  build = build.web

  command = "node server.js"

  dev {
    command = "npm run dev"
  }

  endpoint "default" {
    public = true
  }

  env = {
    PORT = port
  }
}
When specific dev runs, it uses npm run dev instead of node server.js. During deployment, the production command is used.

Dev-only services

A service with a dev.command but no top-level command only runs in local development. It is ignored during deployment. This is useful for running local infrastructure like a Temporal dev server or a mock API.
service "mock-api" {
  dev {
    command = "npx json-server --watch db.json --port $PORT"
  }

  endpoint "default" {
    public = true
  }

  env = {
    PORT = port
  }
}

Dev environment variable overrides

The dev.env block lets you override environment variables for local development. Variables defined in dev.env take precedence over the top-level env block when running locally.
service "worker" {
  build = build.worker

  command = "node worker.js"

  dev {
    command = "npx tsx watch worker.ts"
    env = {
      TEMPORAL_ADDRESS = "localhost:7233"
      TEMPORAL_NAMESPACE = "default"
    }
  }

  env = {
    TEMPORAL_ADDRESS = config.temporal_address
    TEMPORAL_NAMESPACE = config.temporal_namespace
    TEMPORAL_API_KEY  = secret.temporal_api_key
  }
}
In this example, the worker connects to a local Temporal server during development and to Temporal Cloud in production.

Port allocation

Specific automatically allocates stable ports for each service. Ports are consistent across restarts — the same service always gets the same port for a given project and instance key. Ports are injected through environment variables:
  • port — the port for the default endpoint
  • endpoint.<name>.port — the port for a named endpoint
service "api" {
  build = build.api

  command = "node server.js"

  endpoint "http" {
    public = true
  }

  endpoint "grpc" {}

  env = {
    HTTP_PORT = endpoint.http.port
    GRPC_PORT = endpoint.grpc.port
  }
}

Local URLs

Public services are accessible over HTTPS at:
https://<service>.local.spcf.app
Specific generates valid TLS certificates trusted by your system, so HTTPS works without browser warnings. For services with named endpoints, the URL uses the pattern https://<service>-<endpoint>.local.spcf.app.

Multi-instance support

Run isolated development environments side-by-side with the --key option. Each instance gets its own data, ports, and URLs.
specific dev --key feature-auth
With a key, service URLs become:
https://<service>.<key>.local.spcf.app
For example, https://web.feature-auth.local.spcf.app. Each instance stores its data separately under .specific/keys/<key>/, so databases and other state are fully isolated. Automatic git worktree detection: When working in a git worktree, Specific automatically detects the worktree name and uses it as the instance key. No --key flag needed.

Tunnel mode

Expose your local services to the internet with --tunnel. This gives each public service a publicly accessible URL — useful for sharing work with others, testing webhooks, or developing on machines where local DNS setup is not possible.
specific dev --tunnel
Services are available at:
https://<subdomain>.tunnel.spcf.app
Tunnel mode skips local TLS certificate and DNS setup entirely, so it works without any system configuration or password prompts.