Open-source project
TNTcraftHIM/Piik avatar
TNTcraftHIM/Piik

Piik and its twenty-viewer rooms: P2P-first screen sharing with a self-hosted Go server

Free, open-source screen sharing for private live streams with friends. Watch together in a browser or self-host Piik.

3,640 stars222 forksTypeScriptMIT

At a glance

What is it?
Piik turns private screen sharing into a room with an invitation, a room code and a hard ceiling of 20 viewers, served by a Go binary you can run yourself. Small friend groups fit it well, restrictive networks are the weak point.
Who is it for?
Adopt Piik when the audience is a handful of friends and you want the room on hardware you control, since the invitation model, the 20 viewer cap and SQLite storage all assume a small private group. Walk away when you need recording, a wider audience or a path through a network that blocks direct peer connections, because the P2P-only modes are the ones that fail there.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Invitation rooms with a hard ceiling of twenty viewers

Piik shares a screen with a fixed group rather than with the internet. One person picks a screen, a single window, a browser tab or the camera, sends an invitation link, and friends watch in a desktop or mobile browser. The room model has three controls, invitations, room codes and an optional room password, and a room holds one host plus up to 20 viewers.

The server enforces that ceiling as configuration rather than as a build choice. MAX_VIEWERS_PER_ROOM=20 ships as the default with a valid range of 1..20, and the count covers viewers only, so the host sits outside the number. Room lifetime is a second knob: ROOM_EMPTY_TIMEOUT_SECONDS=0 keeps rooms indefinitely, while 3600 expires a room after an hour with no authenticated participants, and when every code is already in use the oldest empty room may be reclaimed sooner. Left at the default, a quiet server accumulates its rooms without bound.

One Go binary that embeds the frontend it serves

The repository carries two toolchains in one tree. The top level holds src/ and vite.config.ts next to go.mod, cmd/ and internal/, and the Go module is named github.com/TNTcraftHIM/Piik. Piik Server is a standalone binary with the web interface built in, which is why one process serves the web UI, room management and the media forwarding together.

The build script makes that coupling explicit. build:web first runs scripts/package-licenses.mjs to write public/third-party-licenses.txt, then deletes every entry under internal/server/webassets/dist except .gitkeep through an inline node -e command, then hands off to vite build. The browser bundle lands in the directory the server embeds, so the site and the relay ship as a single file instead of two things to deploy side by side.

Pion peers, LiveKit relay, two vendored NAT-PMP forks

The direct path is github.com/pion/webrtc/v4 v4.2.19 with ice/v4 v4.4.0, stun/v3 v3.1.7 and turn/v5 v5.0.13 alongside the rtp, rtcp, sdp and transport packages. The forwarding path is not written from scratch: github.com/livekit/livekit-server v1.13.6 and server-sdk-go/v2 v2.14.0 sit in the same require block, so the SFU is LiveKit compiled into the Piik Server binary rather than a second service you install and watch.

Two dependencies have been replaced with in-tree copies. netbirdio/go-nat and jackpal/go-nat-pmp both point into internal/thirdparty/, and the comment above those lines records provenance and removal criteria at internal/thirdparty/README.md. Vendoring NAT traversal code is the kind of change made for one broken network and then kept, so those removal criteria are the only guide to when it can go.

Two more entries are pinned to untagged commits rather than tags: livekit/protocol v1.50.5-0.20260821144838-17c16cf496fd and netbirdio/go-nat v0.0.0-20260821095157-6b2c8c5c74e8. Neither moves by itself, which turns a routine dependency bump into a manual choice of commit.

Starting the server and the settings that decide who reaches it

Piik Server ships as a tar.gz for Linux x64 or ARM64. Extract the package and start it:

sh
./piik-server

Then open http://localhost:8787 to see the site locally. Before exposing it, the defaults in .env.example need attention:

sh
LISTEN_HOST=0.0.0.0
PORT=8787
PUBLIC_BASE_URL=http://localhost:8787

That trio is the first trap. The process binds every interface while the address carried inside your invitation links is localhost, so a viewer on the same network receives a link that resolves to their own machine. The same file says to replace localhost with this computer's LAN address for LAN viewers, and to use 127.0.0.1 instead when only a same-host reverse proxy should connect.

Access control is split across three more keys. ALLOWED_ORIGINS is empty by default and then follows PUBLIC_BASE_URL; once you list addresses yourself, every exact origin has to be included, scheme, host and port. SITE_ACCESS_PASSWORD is empty in every environment, which lets visitors enter without a site password, and a non-empty value is matched exactly with spaces and Unicode allowed. ROOM_DATABASE_PATH is blank, and blank still means rooms.sqlite under the working directory; :memory: is the only value that keeps rooms in process memory, and a deployment is advised to point the key at an access-restricted absolute path outside the folder you unpacked so an update does not overwrite the file.

Sharing a screen without installing anything at all

A first share needs no install. Open https://demo.piik.tv, select Start sharing, choose the picture and audio, then select Copy invite link and send it to your friends while keeping the sharing tab open. Viewers open the invitation and press Play if the picture does not start by itself. Turning on Microphone adds commentary, and its settings pick the input device and set voice volume.

The hosted path has hard limits. Browser capture requires HTTPS or localhost, so serving the site over plain HTTP on a LAN address will not start the capture. On a phone the online version offers Camera where the browser supports it.

For a room on your own machine, download a ZIP whose name begins piik-app, and read the rest of the filename as the platform: windows-amd64 for Windows x64, darwin-arm64 for Apple silicon and darwin-amd64 for Intel Mac, where native capture requires macOS 13+, then linux-amd64 and linux-arm64. Extract it, choose Public invite, then Open Piik to create a temporary room, and keep the App running while you share. Language follows the system setting, Chinese or English with English as fallback, and the header switcher also offers a visual mode.

Where the SFU stops being an optional fallback

Read the feature list and media forwarding sounds like a spare tyre: media travels between participants where possible, and a self-hosted server can provide automatic media forwarding as a fallback, packaged as optional media forwarding inside the one program. The comments in .env.example describe something firmer. One line says a bounded standard-WebRTC relay and SFU controller is active for every room. Another introduces SFU_UDP_PORT=7882 as an optional in-process automatic SFU fallback, where unset or empty disables it.

Those two comments cannot both be a plain description of the default. The switch governs the in-process SFU, while the bounded controller is claimed to be running regardless, and the word fallback understates what an operator ends up running.

ENDPOINT_MEDIA_COPY_CAPACITY=2 puts a number on the cost. Every non-server endpoint holds one steady outbound media-copy capacity, a peer child or a host SFU publication consumes one copy, and the valid values are 1, 2 or 3. Read only the feature list and you would size a server for a peer mesh; read .env.example and you are looking at a relay controller with a per-endpoint budget on every single room.

Devices the project has not exercised, networks that refuse peers

Two gaps are stated rather than hidden. Windows App and desktop browser sharing are named the primary tested paths, while physical-device coverage for the macOS and Linux apps is still limited, with results invited through the project issue tracker. Anyone planning a Linux server with Linux viewers is on unexercised ground at both ends.

The transport choice carries a matching failure mode. P2P-only modes, which include the App temporary public link and the online version, may not connect on restrictive networks, and the fallback that would rescue such a session lives on a server you control rather than on someone else's. The 20 viewer ceiling is a direct-connection statement as much as a configuration value, since twenty peers each holding an outbound copy is a different traffic shape from one host feeding a relay.

The README does not document bandwidth budgets, per-viewer bitrate caps or a recommended upstream for a full room. docs/standards/configuration.md is the file the project points operators to instead.

What an upgrade costs in this repository

Building from source wants both toolchains on the machine. package.json requires node >=24.0.0 <27 with [email protected], while go.mod declares go 1.26.0.

The check scripts show what an upgrade has to survive: check:go, check:go-core, check:go-race, check:container and check:native, plus gates for app media, the native host, browser fanout, the embedded SFU, the app link, the peer topology loopback, SFU admission and access privacy. gate:sfu-admission runs vitest over two test files and then go test ./internal/server/..., so a signalling change gets checked on both sides of the wire.

Two smaller costs are easy to miss. A plain npm run build does not stop at the web bundle, it fans out through build:web, and dev regenerates public/third-party-licenses.txt through scripts/package-licenses.mjs every time it starts vite, so third-party notices are produced rather than committed. Terms are split as well: Piik-owned code is MIT licensed while dependencies keep their own licenses and notices, tracked in licenses/README.md, and a fork carries both halves. The last push landed on 2026-10-06 and the repository is not archived.

Editorial conclusion

Adopt Piik when the audience is a handful of friends and you want the room on hardware you control, since the invitation model, the 20 viewer cap and SQLite storage all assume a small private group. Walk away when you need recording, a wider audience or a path through a network that blocks direct peer connections, because the P2P-only modes are the ones that fail there. Before deploying, set PUBLIC_BASE_URL to an address friends can reach, then settle whether ENDPOINT_MEDIA_COPY_CAPACITY and SFU_UDP_PORT match that fallback claim, and confirm the capture path on your own platform is one the project says it tested.

Frequently asked questions

What is Piik and who is it for?

Piik is a free, open-source screen sharing tool for private live streams with friends, covering games, movie nights, drawings and photos. One host shares a screen, window, browser tab or camera and up to 20 viewers watch in a desktop or mobile browser without installing anything.

How many people can watch a Piik stream at once?

One host and up to 20 viewers per room. The server setting MAX_VIEWERS_PER_ROOM defaults to 20 with a valid range of 1..20, and that count excludes the host.

Can I self-host Piik on my own server?

Yes. Piik Server is a standalone binary with the web interface built in, downloaded as a tar.gz package for Linux x64 or ARM64 and started with ./piik-server, then opened at http://localhost:8787. Room data is stored in SQLite.

Does Piik work on a restrictive network?

Not in every case. The P2P-only modes, which include the App temporary public link and the online version, may not connect on restrictive networks. A self-hosted server can provide automatic media forwarding as a fallback.

Which platforms has Piik actually been tested on?

Windows App and desktop browser sharing are named the primary tested paths, and physical-device coverage for the macOS and Linux apps is still limited. Native capture on the macOS builds requires macOS 13+.

What does it take to build Piik from source?

package.json requires node >=24.0.0 <27 with [email protected], and go.mod declares go 1.26.0. The scripts include check:go-race and a set of gates that run vitest and go test ./internal/server/..., so both toolchains have to be present.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. TNTcraftHIM/Piik on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tntcrafthim-piik.svg)](https://hysenlabs.com/projects/tntcrafthim-piik)

Was this useful?