Important
Because every runtime has its own FFI, this library is currently only compatible with Bun.
- Install the js library
bun add tailscale-js- Get the
libtailscaleshared library
bun x tailscale-js get-libtailscaleOr if you don't like downloading pre-built binaries from the internet, you can build it yourself.
Currently, the prebuilt libraries are available for macOS and linux, but they might not work on all platforms - in that case please file an issue or PR.
- Use the library where you have used
Bun.servebefore:
import Tailscale from "tailscale-js";
await Bun.$`echo LIBTAILSCALE_TAILNET_NAME=pango-lin > .env`;
Tailscale.serve({
routes: {
"/time": new Response(new Date().toISOString()),
},
fetch(req) {
return new Response("Bun through Tailscale!");
},
});Setting the LIBTAILSCALE_TAILNET_NAME env variable to your tailnet name
will give you nicer terminal message with a clickable link.
If you want to expose the server to the internet using a funnel,
you can use Tailscale.funnel instead of Tailscale.serve.
See Quick start section.
As mentioned in the docs, when bundling an application that uses a worker one has to include it in the CLI arguments:
bun build --compile index.ts ./node_modules/tailscale-js/dist/tailscale_worker.jsNote
Currently the libtailscale shared library is not bundled inside the executable.
So you have to put it next to the executable.
If you want to deploy Tailscale in a container (e.g., on fly.io),
you can use libtailscales docker container.
FROM ghcr.io/mastermakrela/tailscale-js:latest
COPY . .
RUN bun install
CMD ["bun","index.ts"]The container contains prebuilt libtailscale shared library
and already sets the LIBTAILSCALE_TAILNET_NAME env variable.
Because we are just wrapping Bun's http server,
almost all features from Bun's serve function are supported.
The biggest missing feature are websockets, which are AFAIK not currently supported by Tailscale Funnel.
The TLS options are also gone, because Tailscale Funnel provides own domain and certificates.
Additionally, to the Bun's serve options, you can pass a tailscale option to both serve and funnel functions.
It is defined as follows:
type TailscaleConfig = {
control_url?: string;
auth_key?: string;
ephemeral?: boolean;
dir?: string;
hostname?: string;
port?: string;
};They correspond to the options in tsnet, which is the base for libtailscale.
If both TailscaleConfig and Bun.serve options are provided, the TailscaleConfig options will be used
(e.g., port or hostname).
| Name | Description |
|---|---|
LIBTAILSCALE_SO_PATH |
Path to the shared library |
LIBTAILSCALE_TAILNET_NAME |
Tailnet name to use in the terminal message |
-
CTRL + C doesn't work
It seems to be a ffi bug, but I'm not sure. For now, use CTRL + </kbd> instead.
-
Bun types can get out of sync
The
Bun.servetypes aren't exported from the bun package, so we yoink them from bun's GitHub repo manually. This of course means that they might get out of sync with the latest version of bun, but hopefully that won't happen too often. -
The TLS resolution sometimes gets stuck on first request.
Not sure if we're doing something wrong or is it because the certificates need to be generated. If I find time, I'll try to diagnose this. In the meantime, it is what it is.