# kernelshard/expose architecture

> Architecture diagram of the GitHub repository kernelshard/expose, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/kernelshard/expose
- Repository: https://github.com/kernelshard/expose

## Overview

Expose is a Go CLI for publishing a local development server through LocalTunnel, Cloudflare, or a self-hosted server. The main workflow loads the configured or overridden local port, selects a provider, starts a tunnel service, displays its public URL, and closes it on shutdown. Configuration initialization and inspection are separate CLI capabilities; self-hosting adds server startup, client registration, and public request forwarding. The graph follows documented capabilities and sampled call paths; Cloudflare’s implementation and several CLI handlers were not sampled, so their internal wiring is limited.

Main entry points: [`internal/server/server.go`](https://github.com/kernelshard/expose/blob/develop/internal/server/server.go) (Tunnel server), [`internal/provider/selfhosted.go`](https://github.com/kernelshard/expose/blob/develop/internal/provider/selfhosted.go) (Self-hosted provider), [`internal/cli/root.go`](https://github.com/kernelshard/expose/blob/develop/internal/cli/root.go) (CLI commands), [`internal/cli/tunnel.go`](https://github.com/kernelshard/expose/blob/develop/internal/cli/tunnel.go) (Tunnel command)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_cli["CLI and configuration"]
  node_entry["CLI entry<br/>[main.go]"]
  node_commands["CLI commands<br/>[root.go]"]
  node_tunnelcmd["Tunnel command<br/>[tunnel.go]"]
  node_configcmd["Config commands"]
  node_initcmd["Init command<br/>[init.go]"]
  node_config["YAML config<br/>[config.go]"]
end

subgraph group_tunnel["Tunnel lifecycle"]
  node_service["Tunnel service<br/>[service.go]"]
  node_provideriface["Provider interface<br/>[provider.go]"]
end

subgraph group_providers["Provider integrations"]
  node_localtunnel["LocalTunnel provider<br/>[localtunnel.go]"]
  node_cloudflare["Cloudflare provider<br/>[cloudflare.go]"]
  node_selfprovider["Self-hosted provider<br/>[selfhosted.go]"]
end

subgraph group_selfhost["Self-hosted server"]
  node_servercmd["Server command<br/>[server.go]"]
  node_server["Tunnel server<br/>[server.go]"]
  node_protocol["Tunnel protocol<br/>[protocol.go]"]
  node_subdomain["Subdomain assignment<br/>[subdomain.go]"]
  node_tunnelstate[("Active tunnels<br/>[server.go]")]
  node_dataqueue["Data connections<br/>[server.go]"]
end

node_developer(("Developer"))
node_localserver(("Local HTTP server"))
node_localtunnelnet{{"LocalTunnel service"}}
node_cloudflarenet{{"Cloudflare service"}}
node_publicclient(("Public HTTP client"))

node_developer -->|"runs CLI"| node_entry
node_entry -->|"executes"| node_commands
node_commands -->|"dispatches"| node_tunnelcmd
node_commands -->|"dispatches"| node_configcmd
node_commands -->|"dispatches"| node_initcmd
node_initcmd -->|"creates config"| node_config
node_configcmd -->|"reads or updates"| node_config
node_tunnelcmd -->|"loads port"| node_config
node_tunnelcmd -->|"starts service"| node_service
node_service -->|"calls provider"| node_provideriface
node_provideriface -->|"implemented by"| node_localtunnel
node_provideriface -.->|"implemented by"| node_cloudflare
node_provideriface -->|"implemented by"| node_selfprovider
node_localtunnel -->|"requests tunnel"| node_localtunnelnet
node_localtunnelnet -->|"returns tunnel details"| node_localtunnel
node_localtunnel -->|"forwards traffic"| node_localserver
node_cloudflare -.->|"connects to"| node_cloudflarenet
node_cloudflare -.->|"forwards traffic"| node_localserver
node_tunnelcmd -->|"starts separately"| node_servercmd
node_servercmd -->|"starts server"| node_server
node_selfprovider -->|"registers tunnel"| node_server
node_selfprovider -->|"encodes request"| node_protocol
node_server -->|"decodes request"| node_protocol
node_server -->|"assigns subdomain"| node_subdomain
node_server -->|"registers tunnel"| node_tunnelstate
node_server -->|"queues data connection"| node_dataqueue
node_selfprovider -->|"opens data connection"| node_dataqueue
node_publicclient -->|"sends HTTP request"| node_server
node_server -->|"takes connection"| node_dataqueue
node_server -->|"forwards request"| node_selfprovider
node_selfprovider -->|"proxies request"| node_localserver
node_selfprovider -->|"returns response"| node_server
node_server -->|"forwards response"| node_publicclient

click node_entry "https://github.com/kernelshard/expose/blob/develop/cmd/expose/main.go"
click node_commands "https://github.com/kernelshard/expose/blob/develop/internal/cli/root.go"
click node_tunnelcmd "https://github.com/kernelshard/expose/blob/develop/internal/cli/tunnel.go"
click node_configcmd "https://github.com/kernelshard/expose/tree/develop/internal/cli"
click node_initcmd "https://github.com/kernelshard/expose/blob/develop/internal/cli/init.go"
click node_config "https://github.com/kernelshard/expose/blob/develop/internal/config/config.go"
click node_service "https://github.com/kernelshard/expose/blob/develop/internal/tunnel/service.go"
click node_provideriface "https://github.com/kernelshard/expose/blob/develop/internal/tunnel/provider.go"
click node_localtunnel "https://github.com/kernelshard/expose/blob/develop/internal/provider/localtunnel.go"
click node_cloudflare "https://github.com/kernelshard/expose/blob/develop/internal/provider/cloudflare.go"
click node_selfprovider "https://github.com/kernelshard/expose/blob/develop/internal/provider/selfhosted.go"
click node_servercmd "https://github.com/kernelshard/expose/blob/develop/internal/cli/server.go"
click node_server "https://github.com/kernelshard/expose/blob/develop/internal/server/server.go"
click node_protocol "https://github.com/kernelshard/expose/blob/develop/internal/server/protocol/protocol.go"
click node_subdomain "https://github.com/kernelshard/expose/blob/develop/internal/server/subdomain.go"
click node_tunnelstate "https://github.com/kernelshard/expose/blob/develop/internal/server/server.go"
click node_dataqueue "https://github.com/kernelshard/expose/blob/develop/internal/server/server.go"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry,node_commands,node_tunnelcmd,node_configcmd,node_initcmd,node_config,node_publicclient toneBlue
class node_service,node_provideriface toneAmber
class node_localtunnel,node_cloudflare,node_selfprovider,node_localserver toneMint
class node_servercmd,node_server,node_protocol,node_subdomain,node_tunnelstate,node_dataqueue toneRose
class node_developer,node_localtunnelnet,node_cloudflarenet toneIndigo
```

## Components

### CLI and configuration

- [CLI entry](https://github.com/kernelshard/expose/blob/develop/cmd/expose/main.go): `cmd/expose/main.go`
- [CLI commands](https://github.com/kernelshard/expose/blob/develop/internal/cli/root.go): `internal/cli/root.go`
- [Tunnel command](https://github.com/kernelshard/expose/blob/develop/internal/cli/tunnel.go): `internal/cli/tunnel.go`
- [Config commands](https://github.com/kernelshard/expose/tree/develop/internal/cli): `internal/cli`
- [Init command](https://github.com/kernelshard/expose/blob/develop/internal/cli/init.go): `internal/cli/init.go`
- [YAML config](https://github.com/kernelshard/expose/blob/develop/internal/config/config.go): `internal/config/config.go`

### Tunnel lifecycle

- [Tunnel service](https://github.com/kernelshard/expose/blob/develop/internal/tunnel/service.go): `internal/tunnel/service.go`
- [Provider interface](https://github.com/kernelshard/expose/blob/develop/internal/tunnel/provider.go): `internal/tunnel/provider.go`

### Provider integrations

- [LocalTunnel provider](https://github.com/kernelshard/expose/blob/develop/internal/provider/localtunnel.go): `internal/provider/localtunnel.go`
- [Cloudflare provider](https://github.com/kernelshard/expose/blob/develop/internal/provider/cloudflare.go): `internal/provider/cloudflare.go`
- [Self-hosted provider](https://github.com/kernelshard/expose/blob/develop/internal/provider/selfhosted.go): `internal/provider/selfhosted.go`

### Self-hosted server

- [Server command](https://github.com/kernelshard/expose/blob/develop/internal/cli/server.go): `internal/cli/server.go`
- [Tunnel server](https://github.com/kernelshard/expose/blob/develop/internal/server/server.go): `internal/server/server.go`
- [Tunnel protocol](https://github.com/kernelshard/expose/blob/develop/internal/server/protocol/protocol.go): `internal/server/protocol/protocol.go`
- [Subdomain assignment](https://github.com/kernelshard/expose/blob/develop/internal/server/subdomain.go): `internal/server/subdomain.go`
- [Active tunnels](https://github.com/kernelshard/expose/blob/develop/internal/server/server.go): `internal/server/server.go`
- [Data connections](https://github.com/kernelshard/expose/blob/develop/internal/server/server.go): `internal/server/server.go`

### Other components

- **Developer**
- **Local HTTP server**
- **LocalTunnel service**
- **Cloudflare service**
- **Public HTTP client**

## Connections

- Developer → CLI entry: runs CLI
- CLI entry → CLI commands: executes
- CLI commands → Tunnel command: dispatches
- CLI commands → Config commands: dispatches
- CLI commands → Init command: dispatches
- Init command → YAML config: creates config
- Config commands → YAML config: reads or updates
- Tunnel command → YAML config: loads port
- Tunnel command → Tunnel service: starts service
- Tunnel service → Provider interface: calls provider
- Provider interface → LocalTunnel provider: implemented by
- Provider interface → Cloudflare provider: implemented by
- Provider interface → Self-hosted provider: implemented by
- LocalTunnel provider → LocalTunnel service: requests tunnel
- LocalTunnel service → LocalTunnel provider: returns tunnel details
- LocalTunnel provider → Local HTTP server: forwards traffic
- Cloudflare provider → Cloudflare service: connects to
- Cloudflare provider → Local HTTP server: forwards traffic
- Tunnel command → Server command: starts separately
- Server command → Tunnel server: starts server
- Self-hosted provider → Tunnel server: registers tunnel
- Self-hosted provider → Tunnel protocol: encodes request
- Tunnel server → Tunnel protocol: decodes request
- Tunnel server → Subdomain assignment: assigns subdomain
- Tunnel server → Active tunnels: registers tunnel
- Tunnel server → Data connections: queues data connection
- Self-hosted provider → Data connections: opens data connection
- Public HTTP client → Tunnel server: sends HTTP request
- Tunnel server → Data connections: takes connection
- Tunnel server → Self-hosted provider: forwards request
- Self-hosted provider → Local HTTP server: proxies request
- Self-hosted provider → Tunnel server: returns response
- Tunnel server → Public HTTP client: forwards response
