Overview
Integrating Clash in a Go program means controlling or embedding Clash behavior from application code. The important part is to keep configuration, lifecycle and runtime state explicit.
Integration model
A Go application can start a core, load configuration, watch profile changes, query runtime state or interact with the external controller API.
Engineering notes
- Validate profiles before loading them.
- Keep logs accessible for user support.
- Handle shutdown so ports and TUN devices are released cleanly.
- Avoid hiding subscription URLs in crash reports or debug output.
Support Checks
Most integration bugs are lifecycle issues: ports not released, stale profiles, missing permissions, or controller calls made before the core is ready.
Related pages
Reference examples
These examples mirror the corresponding Chinese documentation page so the English page carries the same configuration material.
package main
import (
"context"
"fmt"
"io"
"net"
"github.com/Dreamacro/clash/adapter/outbound"
"github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/listener/socks"
)
func main() {
in := make(chan constant.ConnContext, 100)
defer close(in)
l, err := socks.New("127.0.0.1:10000", in)
if err != nil {
panic(err)
}
defer l.Close()
println("listen at:", l.Address())
direct := outbound.NewDirect()
for c := range in {
conn := c
metadata := conn.Metadata()
# reference note
go func () {
remote, err := direct.DialContext(context.Background(), metadata)
if err != nil {
# reference note
return
}
relay(remote, conn.Conn())
}()
}
}
func relay(l, r net.Conn) {
go io.Copy(l, r)
io.Copy(r, l)
}