Text, voice and video chat for a group of friends or a small community, running on a computer you own.
Download · Getting started · What's in it · Running it · Development · Docs
Current release: v3.1.1 — what changed
Paracord looks and works about how you'd expect from Discord: servers, text channels, voice channels, direct messages, roles, moderation. The difference is that there is no company in the middle. Somebody in your group runs the Paracord server on a computer that stays on, and everyone else joins it with a link.
Setting that up is one command. It downloads Paracord, sets it to start by itself, asks your router to let people in, and opens a link in your browser where you make your account and name your server. Friends open an invite link in any browser, or install the desktop app for Windows, Linux or macOS.
Inside a server you get text channels with replies, threads, reactions, polls, attachments and code that arrives readable, plus voice channels with video and screen sharing. Direct messages and group messages are encrypted end to end. There are roles and permissions, automatic moderation, bots and webhooks, and an optional link between two Paracord servers so their members can talk. The voice and video are Paracord's own code, so there is no third-party media service to sign up for.
It suits a group that has somebody willing to keep a machine on and read a docs page when something breaks. Nobody is hosting this for you, and it is a young project, so the things that don't work yet are worth reading before you move a community onto it.
Open it in any browser, press Create an account to join, pick a name and a password. That's the whole thing.
If you'd rather have the app, get it from Releases, open it, and paste the same link in.
One command, then one link.
Linux or macOS, in a terminal:
curl -fsSL https://raw.githubusercontent.com/Scdouglas1999/Paracord/main/scripts/install.sh | shWindows, in any PowerShell window (it asks for administrator permission itself):
irm https://raw.githubusercontent.com/Scdouglas1999/Paracord/main/scripts/install.ps1 | iex1. Finish setting up. The installer opens a link in your browser, and prints it as well. Choose your name and password, name your server, done. That link works once and only for you, so nobody who finds your server first can take it over. Your browser shows a one-time security warning on the way in, because the server made its own certificate: choose Advanced, then Continue. The desktop app never shows this.
2. Invite people. Open your server and press Invite. You get a link to send, and it tells you plainly whether the link will work for anyone or only for people on your Wi-Fi.
The server asks your router to let outside traffic through when it starts, and most routers say yes. If yours refuses, the Invite dialog and the server's startup message both say so, and Friends outside your network walks through the one router setting to change.
Running the same command again later updates Paracord and keeps all your data.
What the installer does, if you want to know before you run it
On Linux with sudo it installs under /opt/paracord, creates a paracord service user
and an auto-restarting systemd unit. Without root it installs under
~/.local/share/paracord with a per-user service. On macOS it installs a launchd job. On
Windows with administrator permission it installs under %ProgramFiles%\Paracord,
registers an auto-start task running as SYSTEM, and opens the firewall for the app and
voice ports; without it, it installs just for you under %LOCALAPPDATA%\Paracord.
Upgrades keep your config and data and back up the old binary. PARACORD_NO_BROWSER=1
prints the setup link instead of opening it, and the header of scripts/install.sh lists
the other overrides. The server maps its ports on the router with UPnP or NAT-PMP; turn
that off with auto_port_forward = false under [network].
Downloads are verified by TLS to the official GitHub releases and nothing else. The release pipeline does not publish checksums yet, and the installer says so while it runs.
Take paracord-server-linux-x64-*.tar.gz, paracord-server-windows-x64-*.zip or
paracord-server-macos-*.tar.gz from Releases, extract it, and
run it:
# Linux and macOS
./paracord-server init # optional: write the config and print what to do next
./paracord-server# Windows
.\paracord-server.exeFirst run creates its settings file, its database and its own certificate, then prints the
one-time link that finishes setup. The same link is saved next to the config as
first-owner-claim-link.txt.
curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/Scdouglas1999/Paracord/main/docker-compose.yml
PARACORD_PULL_POLICY=missing docker compose up -dThat pulls the image CI publishes to GHCR. Leave PARACORD_PULL_POLICY off to build the
image locally instead, or point PARACORD_BUILD_CONTEXT at
https://github.com/Scdouglas1999/Paracord.git#main to build from the remote repository
without cloning it. No .env file is needed.
The stack publishes the app on 127.0.0.1:8090 and voice on UDP 8443, and expects a
reverse proxy to handle HTTPS. Browsers only give a page the microphone, camera and screen
once it is served over HTTPS, so put the proxy in front before you send anyone the address;
Docker Setup has an example.
For the longer walk through a first run see Getting Started; for a domain name, PostgreSQL and backups see Deployment.
![]() |
![]() |
| Home opens on people and conversations: who's around, your servers, and where you left off. | A server's front page. Voice channels show who is in them before you join. |
It works at phone width too.
Talking. Text channels, announcement channels, forums and threads. Replies, mentions, reactions, pins and saved messages. Markdown, syntax-highlighted code, attachments, image previews and link embeds. Polls, scheduled messages, slash commands, GIFs, stickers and custom emoji. Search, an inbox, unread counts and per-channel notification settings.
Voice, video and screen sharing. Voice channels, video grids, screen sharing and device controls, over Paracord's own QUIC transport: raw QUIC in the desktop app, WebTransport in the browser. Opus audio with RNNoise noise suppression, VP9 video, speaker detection, and media frames the relay cannot read. A LiveKit path is still in the codebase for anyone who specifically wants a WebRTC SFU, but it is not the route that gets tested and it needs a LiveKit server of its own.
Direct messages. One-to-one and group conversations, encrypted end to end. Text and attachments are both encrypted on your device, so the server stores files it cannot read and does not learn their names or types. Group keys change whenever somebody joins or leaves, so a person who left cannot read what is said afterwards, and every message is signed, so one member cannot post as another.
Messages in a server's channels are a different matter: those are not encrypted end to end. Whoever runs the server can read them, as can anyone with access to its database or disk. Self-hosting decides where your conversations live, which is a smaller promise than encryption. The known limitations page sets out exactly what the server can and cannot see in each case.
Running a community. Roles and fine-grained permissions. Invites, discovery, templates, welcome screens and member onboarding. Bans, reports, moderation templates and audit logs. Events, custom emoji, storage limits, and a community economy if you want one. Automatic moderation covers keywords, patterns, links, invites, mention floods and spam, with block, timeout and moderator-alert actions (AutoMod has the details). There's also a health page that reports backups, database size, transport security and capacity, and says what to fix.
Bots and other servers. Bot applications with slash commands and interaction components, webhooks, and a bot SDK. One client can connect to several Paracord servers and move between them. Servers can also be linked to each other with signed server-to-server requests, which is off by default and is a trust decision rather than a switch to flip, so read Federation Protocol first.
There are four themes (Night, Daylight, AMOLED and High contrast), and you can set their base colour and accent to any hue you like without the text becoming unreadable. On top of those are three looks, each of which brings a whole palette of its own:
- Voices, the default, puts every message in a bubble tinted with its author's colour, with your own on the right.
- Dusk sky puts a sunset behind the app, with dark glass panels over it.
- Paper & ink is a light look: cream paper, dark ink, hard printed-style shadows.
A look supplies its own colours, so the base and accent pickers switch off while one is on; pick any of the four themes to get them back. Looks switch instantly and the colour changes as you drag. Names in chat are written in each person's own colour throughout, and the Friends list uses the same colours.
The same channel in each:
![]() |
![]() |
| Voices | Dusk sky |
![]() |
![]() |
| Paper & ink | Night |
Things that will come up, in rough order of how likely you are to hit them. The full list lives in known limitations and in the release notes.
- The browser shows a certificate warning the first time anyone visits, because a new
server makes its own certificate and browsers do not recognise it. Choose Advanced, then
Continue; it happens once per browser. The desktop app trusts the server's certificate by
itself and never asks. Pointing a domain name at the server and turning on automatic
certificates (
[tls.acme]) gets rid of the warning for good. - Joining a call from the browser needs a Chromium-based browser, such as Chrome or Edge. It depends on pinning that self-made certificate by fingerprint, which Chromium supports and Firefox and Safari do not. The desktop app is unaffected and works in any case; if a call fails, Settings → Voice & Video has a connection check that says which step broke.
- The desktop app does not update itself yet. That needs a signed update file published with each release, which isn't set up. Download the new version when there is one; for the server, re-run the install command.
- macOS builds are unsigned unless a Developer ID is configured, so the first launch needs right-click → Open. These packages are new in this release and were built by CI rather than run by hand, so expect rough edges. macOS system-audio capture isn't implemented, so a screen share from a Mac carries no system sound.
- Linux screen sharing works but leans on your desktop's PipeWire and portal setup, so try it before you need it.
- NVIDIA's proprietary driver and WebKit don't get along. On those machines the Linux app
turns off WebKit's GPU compositing at startup, because WebKitGTK crashes against that
driver and the window never paints. Video still decodes on the GPU; only the interface is
affected. The AppImage is a separate problem and is still broken there, so install the
.debor build from source.PARACORD_WEBKIT_ACCELERATION=ondemandoverrides the choice if your driver has since been fixed. - The Windows installer was rewritten for this release and has been checked by tools but
not run by hand on a Windows machine. If it misbehaves, download
install.ps1and run it withpowershell -ExecutionPolicy Bypass -File .\install.ps1. - After a long time away the desktop app sometimes opens as "Unknown user" with no servers, instead of taking you to the sign-in screen. Open Settings, log out, and sign in again.
- There is no way to publish a bot to the bot store, so it is empty. A bot can only be installed by whoever made it.
- Home and a server's front page look empty when a server is quiet. That's a layout job for a later release.
One port number covers everything, over both protocols:
| Carries | |
|---|---|
TCP 8443 |
the web client, the API and the realtime connection |
UDP 8443 |
voice, video and screen sharing |
The server asks the router to forward both when it starts, using UPnP or NAT-PMP. If the router refuses, forward both by hand. UDP is the half people forget, and calls are silent without it. Friends outside your network has the steps and a way to check it worked. Under Docker the app stays on loopback and a reverse proxy provides the public HTTPS.
| Default | Other option | |
|---|---|---|
| Database | SQLite | PostgreSQL |
| Uploads | local filesystem | S3-compatible storage, in a build that enables it |
| Media | Paracord's QUIC/WebTransport stack | LiveKit, if you want a WebRTC SFU |
| HTTPS | a certificate the server makes itself | a reverse proxy, or ACME certificates |
SQLite carries a small server fine. PostgreSQL is the one to move to for sustained
day-to-day use; the offline migrate-to-postgres command copies an existing SQLite
database across, has a dry-run mode, and verifies row counts before you commit to it.
Desktop builds are on the releases page, or you can just open the web client the server already serves.
| File | Notes | |
|---|---|---|
| Windows | Paracord-Setup-<ver>.exe |
the guided installer, and the one to use. Paracord_<ver>_x64_en-US.msi is there too |
| Linux | Paracord_<ver>_amd64.AppImage |
portable, no install. Or Paracord_<ver>_amd64.deb / Paracord-<ver>-1.x86_64.rpm |
| macOS | Paracord_<ver>_aarch64.dmg |
Apple Silicon. Paracord_<ver>_x64.dmg for Intel. Unsigned: right-click → Open the first time |
| Browser | nothing to install | open https://<your-server>:8443, which the server serves itself |
Server packages are on the same page: paracord-server-linux-x64-<ver>.tar.gz,
paracord-server-windows-x64-<ver>.zip, paracord-server-macos-arm64-<ver>.tar.gz and
paracord-server-macos-x64-<ver>.tar.gz.
The desktop app asks for your invite link on first launch. A plain server address works too.
The server is a Rust workspace: axum on Tokio, SQLx over SQLite or PostgreSQL, a REST API and a WebSocket gateway, with Argon2 passwords, JWT sessions and Ed25519 identity keys. The client is React 19, TypeScript, Tailwind CSS v4 and Zustand, wrapped in a Tauri v2 shell for the desktop builds.
crates/
├── paracord-server # the binary: config, TLS, embedded web client
├── paracord-api # HTTP API
├── paracord-ws # realtime gateway
├── paracord-core # permissions, services, event bus
├── paracord-db # SQLite and PostgreSQL persistence
├── paracord-models # shared types and permission flags
├── paracord-transport # QUIC and WebTransport
├── paracord-relay # encrypted media routing
├── paracord-codec # Opus, RNNoise and VP9
├── paracord-media # file storage, optional LiveKit
└── paracord-federation # signed server-to-server protocol
client/ # React web app and Tauri desktop shell
packages/paracord-bot-sdk # bot SDK
Release builds compile client/dist into paracord-server, so the single binary serves
the web client itself.
You need Rust 1.88 or newer, Node 22 or
newer, libvpx for VP9 video and screen sharing, and Tauri's platform
dependencies if you're building the desktop app. CLAUDE.md has the per-platform notes for
libvpx.
Run the client against a local server:
# terminal 1
cd client && npm install && npm run dev
# terminal 2
cargo run --bin paracord-server --no-default-featuresVite serves http://localhost:1420 and proxies the API to the server. The
--no-default-features flag skips embedding the web client, which you have no build of yet.
Check and test:
cargo fmt --all -- --check
cargo clippy --workspace -- -D warnings
cargo test --workspace
cd client
npm run typecheck
npm test # typecheck plus unit tests
npm run test:e2e # PlaywrightBuild a release server with the current web client inside it, then the desktop app:
cd client && npm install && npm run build && cd ..
cargo build --release --bin paracord-server
cd client && npx tauri buildThe vpx feature in paracord-codec is on by default and turning it off to get past a
build error is the wrong move: the build succeeds and video and screen sharing then fail at
runtime with nothing to explain why. Fix the libvpx setup instead. On recent Linux
toolchains the AppImage build needs NO_STRIP=1, because linuxdeploy's bundled strip
cannot read the relocation sections a modern linker emits.
| Guide | Covers |
|---|---|
| Getting Started | first run, the setup link, invites, media choices |
| Friends outside your network | what to change on the router, and how to check it |
| Deployment | a domain name, TLS at a proxy, PostgreSQL, backups |
| Docker Setup | compose services, volumes, reverse proxy |
| Known Limitations | the full list of what does and doesn't work |
| AutoMod | rules, triggers, actions, exemptions, the rule API |
| Bot Development | bots, commands, interactions, webhooks |
| Federation Protocol | signed requests between servers and the trust model |
| Backup Recovery | restoring an archive, and what it can't restore |
| Release Notes | what changed in v3.1.0 |
Paracord is source-available rather than open source, under the Paracord Source-Available License. You can run it for anything, including a business. You can read the source, modify it for your own machines, and pass the official releases around unchanged. Publishing a modified version, or a fork for other people to use, needs written permission from the author.
Issues and pull requests are welcome. For a bug, say what you did and what happened. If it involves voice, screen sharing or encryption, include the platform and whether you were in the browser or the desktop app, because those behave differently.













