Sharkord: a self-hosted Discord alternative built on Bun and mediasoup
Lightweight, self-hosted, open-source chat server with voice, video, text, and screen sharing. Built for small groups who want privacy, simplicity, and full control over their data.
At a glance
- What is it?
- Sharkord bundles a server and web client into one standalone binary, with voice and screen sharing handled by a mediasoup SFU. It is explicitly alpha software, and its first-run owner token is the whole security model.
- Who is it for?
- Adopt Sharkord if you want a small, private server for a group you already trust, and if you are comfortable that the README labels it alpha with breaking changes expected. Do not adopt it if you need a stable API surface for automation, an audit trail of who has owner access, or a support contract.
- 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 last received commits 4 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Sharkord targets, and who it is actually for
The stated goal is a Discord-like set of features running on infrastructure you control, without what the README calls "the bloat or surveillance". That framing defines the audience narrowly. This is for a group that already has a place to run a process (a VPS, a home server, a NAS) and a reason to keep message history and voice traffic off a hosted service. Small teams, friend groups, and communities with a data-ownership requirement fit. Anyone who wants a hosted product with an uptime commitment does not.
The feature list is deliberately close to a chat app checklist: voice channels with video and screen sharing, text channels grouped into categories, threads, replies, reactions, pins, search, direct messages, roles with per-channel overrides, custom emoji, invites with usage limits and automatic role assignment, file uploads with per-user quotas, and optional signed URLs. Plugins extend both server and client through a plugin SDK in packages/plugin-sdk. Nothing on that list is novel on its own. The pitch is that all of it runs on one machine you own.
One binary, one SFU, and where the media actually flows
Sharkord ships as a standalone binary that bundles both server and client components. The client is a React application built with Radix UI, ShadCN UI, and Tailwind CSS. The server runs on Bun, exposes a tRPC API, and persists through Drizzle ORM. Realtime voice, video, and screen sharing go through a built-in mediasoup SFU (selective forwarding unit), which is the piece that distinguishes Sharkord from a plain websocket chat server.
An SFU receives each participant's stream once and forwards it to the others, rather than having every client upload to every other client. That is the architecture the Docker instructions imply: the container publishes TCP 4991 for the web and API traffic, and TCP plus UDP 40000 for the media path. The README does not document how many concurrent streams a given host can forward, what codecs are negotiated, or how the SFU behaves when the UDP port is blocked and traffic has to fall back to TCP. Those are exactly the numbers an operator needs before promising a group reliable screen sharing, and they are not in the material available.
The plugin SDK is the other structural commitment. The README describes plugins as extending both server and client, which means an extension point exists on both sides of the wire. It does not describe the sandboxing, permissions, or review process for a plugin, which matters if you ever install one written by someone else.
Getting a server up: the two supported paths
The README gives two installation routes. For Linux x64, download the release binary, mark it executable, and run it:
curl -L https://github.com/sharkord/sharkord/releases/latest/download/sharkord-linux-x64 -o sharkord chmod +x sharkord ./sharkord
The Docker path mounts a data directory and publishes the three ports:
docker run \ -p 4991:4991/tcp \ -p 40000:40000/tcp \ -p 40000:40000/udp \ -v ./data:/home/bun/.config/sharkord \ --name sharkord \ sharkord/sharkord:latest
Once running, the client is served at http://localhost:4991. Binaries are published for Windows, macOS, and Linux, and a live demo exists at demo.sharkord.com. The README points to sharkord.com/docs for configuration options beyond this, so the container above is the minimum, not the full set of knobs. If you are putting this behind a reverse proxy, note that the UDP port for media has no HTTP equivalent and needs its own path through your network.
The first-run token is the entire security boundary
On first launch Sharkord generates a secret token and prints it to the console. The README is blunt about what that value does: it is both the credential granting owner access and the key the server signs every session and file URL with. Anyone who obtains it can take ownership of the server and impersonate any account on it.
That is a single point of failure with two distinct consequences, and it deserves more attention than the warning box it currently gets. Because the same secret signs file URLs, leaking it does not just hand over admin rights; it lets someone mint valid signed URLs for files, which matters if you enabled the optional signed URL feature for uploads. There is no described rotation procedure, no second factor, and no indication that the token can be regenerated without losing existing sessions. The warning says not to lose it, which cuts both ways: losing it is also a problem.
For a group of five friends on a private network this is a reasonable trade. For anything reachable from the public internet, it means your entire access model rests on one string that was printed to a terminal once. Treat the console output of the first run as sensitive material, and check that it has not landed in a container log aggregator.
Alpha status, version numbers, and what upgrading costs you
The README carries a note that Sharkord is in alpha stage, with bugs, incomplete features, and breaking changes to be expected. The release history backs that up: v0.0.25, v0.0.24, and v0.0.23, all in the 0.0.x range, with the most recent published in September 2026. Three releases in roughly two months is a fast cadence for a project at this stage, and a 0.0.x version number is a fair signal that no compatibility promise is being made.
What that means in practice is that upgrading is not a background operation. The Docker example mounts ./data into /home/bun/.config/sharkord, and that directory holds whatever state the server keeps, including the owner token generated on first launch. A breaking change between releases could plausibly require a migration or a reset of that directory, and the README does not describe a migration path or a backup procedure. Before upgrading, copy that mounted directory somewhere else. If the release notes for the version you are moving to do not mention migrations, that is an absence of information, not a guarantee.
The licence is MIT, which is permissive and places few obligations on how you run or modify the software. That is a statement about the licence text, not about your situation; if you plan to redistribute a modified build, read the LICENSE file rather than this article.
Where Sharkord is the wrong tool, and what to use instead
Sharkord is the wrong choice when you need a stable integration surface. It is alpha, the API is tRPC over an internal client, and the plugin SDK is the documented extension route. If your plan is to drive the server from scripts or build bots against a versioned REST API, nothing in the material suggests that contract exists or will hold still.
It is also the wrong choice if you have no appetite for operating a media server. The UDP port on 40000 is not optional if you want voice and screen sharing to work well, and the README does not cover NAT traversal, TURN, or what happens on networks that block UDP. A group behind restrictive corporate networks may find that text works and voice does not.
The obvious alternative is Matrix, paired with a client such as Element. The difference in approach is architectural and worth stating plainly. Matrix is a federated protocol with a published specification, multiple independent server implementations, and a bridge ecosystem; Sharkord is a single application that bundles its own server and client with no federation and no spec to conform to. If you need to talk to people on other servers, or you want the option to switch server implementations without changing clients, Matrix is the category you want. If you want one process on one box that your group connects to, and you would rather not run a homeserver plus a separate SFU plus a TURN service, Sharkord's single-binary packaging is the reason to pick it. Mattermost and Rocket.Chat are the other common self-hosted options, and both are aimed at organisational deployments with more moving parts than the Docker command above.
Editorial conclusion
Adopt Sharkord if you want a small, private server for a group you already trust, and if you are comfortable that the README labels it alpha with breaking changes expected. Do not adopt it if you need a stable API surface for automation, an audit trail of who has owner access, or a support contract. Before you expose port 4991 to a network, verify that the first-run token has been captured somewhere durable and that it is not sitting in your shell history, container logs, or a screenshot; that single value grants owner access and signs every session and file URL.
Community notes