English (default) | 中文 | Changelog
tturn is a high-performance TURN server package for Node.js.
It embeds a native Rust core via N-API, so you can install from npm and run directly.
- No Docker runtime required.
- No external
turnserver.exeruntime dependency. - Programmatic API and CLI are both included.
- Embedded TURN service for Node.js applications.
- Native data plane implemented in Rust.
- Dynamic TURN credentials using HMAC-SHA1 (TURN REST style).
- Direct ICE payload output (
urls,username,credential).
npm i tturnimport { Tturn } from "tturn";
const turn = new Tturn({
realm: "turn.example.com",
password: "replace-with-your-password",
publicIp: "1.2.3.4",
listenPort: 3478,
username: "user-1001",
disableCredentialExpiry: true
});
const ice = await turn.start();
console.log(ice);
await turn.stop();start() now returns one ICE payload directly, so bootstrap can be only new Tturn(...) + start().
For long-running sessions, set disableCredentialExpiry: true to issue non-expiring credentials.
With static password mode (password + username), what you set is what clients use:
- output
usernameis exactly your configured username - output
credentialis exactly your configured password
issueCredential(options) supports:
ttlSec(optional, default3600, minimum60)username(optional): pass a custom TURN usernameuserId(optional): legacy prefix mode (userId:expiresAt)
Username behavior:
- If
usernamealready ends with a future unix timestamp (for examplealice:1730000000), it is used as-is. - Otherwise,
tturnappends:<expiresAt>automatically so TURN auth remains valid. - If both
usernameanduserIdare provided,usernametakes priority.
# Start embedded TURN service
TURN_REALM=turn.example.com TURN_SECRET=replace-with-your-secret tturn start
# Print one ICE credential payload
TURN_REALM=turn.example.com TURN_SECRET=replace-with-your-secret tturn credential
# Optional: provide custom username
TURN_REALM=turn.example.com TURN_SECRET=replace-with-your-secret TTURN_USERNAME=alice tturn credential
# Optional: disable credential expiry (long-lived credentials)
TURN_REALM=turn.example.com TURN_SECRET=replace-with-your-secret TTURN_USERNAME=alice TTURN_DISABLE_CREDENTIAL_EXPIRY=1 tturn credential
# Static account/password (exact value, no rewrite)
TURN_REALM=turn.example.com TURN_USERNAME=alice TURN_PASSWORD=alice-pass TTURN_DISABLE_CREDENTIAL_EXPIRY=1 tturn startRequired env:
TURN_REALMTURN_SECRETorTURN_PASSWORD
Optional env:
TURN_PUBLIC_IPTURN_PORTTURN_MIN_PORT(must be provided together withTURN_MAX_PORT)TURN_MAX_PORT(must be provided together withTURN_MIN_PORT)TTURN_TTL_SECTTURN_USER_IDTTURN_USERNAME(orTURN_USERNAME)TTURN_DISABLE_CREDENTIAL_EXPIRY(1/truekeeps credentials non-expiring; set0/falseto enable expiry)
realm(required): TURN realm/domain.authSecret(optional): shared secret for dynamic credentials.password(optional): static TURN password (when set, returned credential stays fixed).listenPort(default3478): TURN listening port.publicIp(optional, recommended): public relay IP exposed to clients.listeningIp(default0.0.0.0): bind address.username/userId(optional): default credential username seed.usernamehas higher priority.ttlSec(optional): default credential TTL used bystart()andissueCredential().disableCredentialExpiry(optional, defaulttrue): disable timestamp expiry check and issue non-expiring credentials. Set tofalseto enforce expiry.minPort/maxPort: relay allocation port range (must be configured as a pair).
Transport note:
- Current native implementation exposes UDP relay URLs only (
turn:...?...transport=udp).
At least one of authSecret or password must be provided.
npm install
npm run build
TURN_REALM=turn.example.com TURN_PUBLIC_IP=1.2.3.4 TURN_USERNAME=alice TURN_PASSWORD=alice-pass TTURN_DISABLE_CREDENTIAL_EXPIRY=1 node dist/cli.js credentialThe returned JSON should keep username = "alice" and credential = "alice-pass".
Requirements:
- Node.js >= 18
- Rust toolchain (stable)
npm install
npm run build:native
npm run build:tsRun demo:
node dist/app.js- Use plain semantic version tags without
vprefix. - Example:
0.1.4(correct),v0.1.4(do not use).