# public urls for every worktree.

`tnl` gives your local app an encrypted HTTPS url. Start the same project in another Git worktree and it gets a different url by default. Keep both versions open while you work.

```text
┌──[ dev with parallel worktrees ]────────────────────────────────┐
│                                                                 │
│                             browser                             │
│                                |                                │
│                              HTTPS                              │
│                                v                                │
│                   tnld (hosted or self-hosted)                  │
│                                |                                │
│                        encrypted traffic                        │
│                                |                                │
│  +-----------------------------v-----------------------------+  │
│  |                       your machine                        |  │
│  |                                                           |  │
│  |  main repo                    perf worktree               |  │
│  |  web URL -> :5173             web URL -> :5174            |  │
│  |  api URL -> :3001             api URL -> :3002            |  │
│  |                                                           |  │
│  +-----------------------------------------------------------+  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
```

## start developing

**npm**

```bash
npm install -D @tnldotdev/tnl@next
npx tnl init
npx tnl dev
```

**pnpm**

```bash
pnpm add -D @tnldotdev/tnl@next
pnpm exec tnl init
pnpm exec tnl dev
```

**bun**

```bash
bun add -d @tnldotdev/tnl@next
bunx tnl init
bunx tnl dev
```

Sign in when prompted. `tnl` prints the url when your app is ready.

[Follow the quickstart](/docs) or [publish an app that's already running](/docs/publish).

## from browser to app

```text
┌──[ request path ]────────────────────────────────────────────┐
│                                                              │
│  browser (visitor)                                           │
│         | HTTPS                                              │
│         ↓                                                    │
│  tnl server (hosted or self-hosted)                          │
│         | encrypted visitor traffic                          │
│         ↓                                                    │
│  tnl (your machine)  <- visitor TLS ends here                │
│         | local HTTP                                         │
│         ↓                                                    │
│  local HTTP app                                              │
│                                                              │
└──────────────────────────────────────────────────────────────┘
```

See [how it works](/docs/how-it-works) for the full request path.

## questions

### does it deploy my app?

No. `tnl` publishes your running local HTTP app; it doesn't deploy it or replace your app's login.

### what if localhost is enough?

Keep using localhost. Use `tnl` when someone outside your machine needs to reach your local app.

### who can visit?

Only your current IP is allowed by default. [Allow reviewers or webhooks](/docs/development#who-can-visit) when you need them.

### can i use my own domain?

Yes. Claim a development subdomain and use it for new public urls. [Use a custom domain](/docs/domains).

### can i self-host?

Yes. Use the same client with your own tnl server. [Run your own server](/docs/self-hosting).

### how much does it cost?

tnl.dev is free for now. Teams have a soft limit of 50 GiB of transfer per month across their public URLs, counting traffic in both directions.

Accounts and teams created while it is free will keep a free plan if paid options arrive.
