tnl.dev :: docs
quickstart.
install one package, initialize a project, and run tnl dev.
tnl gives a local HTTP service a public HTTPS URL. The project workflow uses one package, one initializer, and one command whether the application runs on Vite, Next.js, or a fixed loopback port.
install one package
Add the project-local client and framework integrations as one development dependency:
npm install --save-dev @tnldotdev/tnl@nextThe package provides the native tnl command, configuration types, and the
@tnldotdev/tnl/vite and @tnldotdev/tnl/next integration subpaths. There are no separate Vite or
Next.js packages to install. Node.js 22.18 or newer is required.
Homebrew and verified release archives remain available when a project-local npm installation is not appropriate:
brew install tnldotdev/tap/tnlFollow the release verification guide before running a downloaded archive.
initialize the project
Run the initializer from the project root:
npm exec -- tnl inittnl init detects the package manager, supported framework, package scripts, and existing config.
It installs the consolidated dependency, creates a named-service config when one is absent, and
creates a framework config when one is absent. Existing Next.js, Vite, and TypeScript configuration
is preserved, and the result reports the exact integration actions still needed.
Review the selected team and named service before the first run.
The generated configuration names each service. That name keeps status output understandable and participates in the default hostname when a project publishes more than one service.
start public development
Start the configured development workflow:
npm exec -- tnl devOn the first command that needs an account, tnl starts browser authentication automatically. Finish sign-in in the opened browser and return to the terminal; there is no separate login step in the normal hosted workflow. If a browser cannot be opened, the same frame prints the exact URL and the command to retry. Saved authentication is reused and refreshed by later commands.
With one configured service, tnl selects it automatically, waits for its actual loopback port, reconciles its route, and prints the URL when it is ready. Select by name in a multi-service project:
npm exec -- tnl dev apiThe Next.js and Vite integrations preserve framework defaults and explicit host or port settings.
They register the actual target after the server binds, so an occupied-port retry cannot tunnel an
unrelated process still using the preferred port. tnl dev --port instead requires that exact port.
A user host setting can independently expose the development server on the LAN; tnl does not enable
or disable that access.
Each tunnel uses deterministic lifecycle states such as
starting, provisioning, ready, and draining; repeated status output describes current state
rather than an estimated progress bar. After two minutes in one route version's provisioning state,
tnl emits one actionable warning and keeps retrying.
understand the defaults
With no explicit hostname, tnl derives a DNS-safe label from the current Git worktree. This lets the main checkout and feature worktrees run concurrently without sharing a route. A configured service name prefixes that worktree label to distinguish named services. Its short hash is stable for the current client state but differs on another installation. The resulting hostname remains beneath the selected membership's namespace on the selected team's default domain.
Hostname values resolve from highest to lowest precedence:
Routes are safe for the current network by default. The control API adds the public IP it observes
to the route's IP policy. Use --public only when every visitor address should be accepted:
npm exec -- tnl dev --publicDenied visitor connections are counted and reported as aggregate warnings. tnl does not print a line containing source information for every denied connection.
Routes are durable by default, so a later run reuses and reconciles the same hostname. Use
--ephemeral for a preview route that should be deleted when the tunnel ends:
npm exec -- tnl dev --ephemeralinspect and recover
Run tnl status from another terminal for tunnels in the current worktree project. Each entry shows
the named service, target, hostname, route version, and lifecycle state when available;
tnl status --all adds each worktree project root. Errors include a stable diagnostic code and a
relevant help URL when tnl can offer a specific recovery path.
Continue with development workflow for reconciliation and troubleshooting, project configuration for TypeScript, YAML, and JSON examples, or publish for an already-running local service.