# Scribble.rs: a self-hosted pictionary server you run yourself

> Scribble.rs is a free, account-free pictionary game written in Go, distributed as a Docker image or a single compiled binary. It is a practical fit if you want to host a drawing game on your own server, and the configuration surface is small enough to read in one sitting.

**scribble-rs/scribble.rs** — The free and privacy respecting pictionary game - Play at https://scribblers.bios-marcel.link

- Repository: https://github.com/scribble-rs/scribble.rs
- Stars: 663 · Forks: 218
- Language: Go
- License: BSD-3-Clause
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/scribble-rs-scribble-rs

## What Scribble.rs is for, and who should run it

Scribble.rs is a web-based pictionary game. One player draws, the rest guess in a shared lobby, and the README describes it as "a free and privacy respecting pictionary game" with no advertisements and no account requirement. It positions itself explicitly as an alternative to skribbl.io.

That framing matters more than it sounds. Most browser party games are centralised services: you visit a domain, you play on someone else's server, and your session lives inside their infrastructure. Scribble.rs inverts that. The repository is the product, the hosted instances are conveniences, and the README lists three of them (the official instance at scribblers.bios-marcel.link, plus community instances at scribble.bixilon.de and scribble.drifty.win) while inviting anyone to host their own.

The audience is therefore narrow and specific. It is for someone who wants to run a game server for a group: a company running an internal social hour, a community with a Discord server, a teacher who wants a drawing game on a machine they control. It is also for people who simply do not want an account, a tracker or an ad network between them and a guessing game. The official instance is documented as shutting down automatically when it receives no traffic, which tells you the maintainer treats hosting as a cost to be minimised rather than a business.

If you are a player rather than an operator, the README's answer is the play-now list. If you are an operator, the rest of this article is about you.

## How the Go server is put together

The repository is a Go module, github.com/scribble-rs/scribble.rs, targeting Go 1.25.0. The layout separates the entry point from the logic: cmd/ holds the binary you build, internal/ holds the packages, and tools/ holds auxiliary code. There are three Dockerfiles at the top level (linux.Dockerfile, windows.Dockerfile, fly.Dockerfile) plus fly.toml and fly_deploy.sh, which is a fairly direct statement that the official instance runs on fly.io.

The dependency list is short and readable, which is itself informative. github.com/lxzan/gws is the WebSocket library, and WebSockets are the transport the whole game depends on: drawing strokes and guesses have to move between players continuously, so the game is not a request-response application. github.com/go-chi/cors handles cross-origin policy, and the configuration keys CORS_ALLOWED_ORIGINS and CORS_ALLOW_CREDENTIALS exist because of it. github.com/caarlos0/env and github.com/subosito/gotenv are what let the same settings arrive either as environment variables or from a .env file in the working directory. github.com/gofrs/uuid/v5 generates identifiers, github.com/Bios-Marcel/go-petname generates player names, and github.com/Bios-Marcel/discordemojimap/v2 suggests emoji handling in chat or names. github.com/prometheus/client_golang backs the metrics endpoint.

Two configuration keys describe a lobby lifecycle rather than a game rule: LOBBY_CLEANUP_INTERVAL defaults to 90s and LOBBY_CLEANUP_PLAYER_INACTIVITY_THRESHOLD defaults to 75s. Read together, they say that idle players are dropped and that lobbies are swept on a timer. The README does not spell out the exact interaction between the two, and it points readers to internal/config/config.go for "more up-to-date configuration", which is an honest admission that the table in the README is a summary.

## Installing Scribble.rs with Docker and starting a first game

The README recommends Docker, on the grounds that it "will rule out almost all compatibility issues". Images are published to Docker Hub under biosmarcel/scribble.rs, and since v0.8.5 they are built only on tagged pushes: each git tag becomes a Docker tag, and latest tracks the most recent GitHub release.

Pull the Linux image first. This is the default mode even on Windows unless you specifically want a native Windows container.

```bash
docker pull biosmarcel/scribble.rs:latest
```

Run it with the internal port set through the PORT environment variable and mapped to whatever port you want to expose. The README's own example maps host port 80 to container port 8080.

```bash
docker run --pull always --env PORT=8080 -p 80:8080 biosmarcel/scribble.rs:latest
```

The README notes that 8080 is the container's internal port and that you should not normally need to change it; only the host-side number in -p needs to move. Once the container is up, open the mapped port in a browser and the game is served. There is no account step and no database to initialise, which is why the whole first-run experience is a single command.

If you prefer a native binary, the build path is two commands. Go 1.25.0 or later and git are the stated dependencies, and the output is a portable binary named scribblers (or scribblers.exe on Windows).

```bash
git clone https://github.com/scribble-rs/scribble.rs.git
cd scribble.rs
go build ./cmd/scribblers
```

Pre-compiled binaries also exist in the Releases section, and each commit uploads artifacts that remain available for a limited time. The README is explicit that these binaries "might not necessarily be compatible with your system" and that Docker or a local build is the fallback. Take that warning at face value.

## The settings that actually change behaviour

Configuration comes from environment variables or a .env file in the working directory. The README's table lists seven keys, and only PORT is marked required, with a default of 8080.

PORT is the HTTP port the server listens on. NETWORK_ADDRESS is the TCP address it binds to and has no default listed, which means the default binding behaviour is whatever the underlying server does when the value is empty. ROOT_PATH changes the path after your domain that the server listens on, which is the setting you want if the game must live at example.com/game rather than at the root. CORS_ALLOWED_ORIGINS defaults to * and CORS_ALLOW_CREDENTIALS has no default shown; together they are the knobs for running the frontend and the game server on different origins.

The two cleanup keys are the ones most likely to surprise an operator. LOBBY_CLEANUP_INTERVAL defaults to 90s and LOBBY_CLEANUP_PLAYER_INACTIVITY_THRESHOLD defaults to 75s. A player who goes quiet for longer than the threshold is a candidate for removal, and lobbies are examined every interval. If your group plays slowly, or if someone is reading the chat rather than drawing, those defaults are the first thing to raise. The README does not document what happens to a lobby once every player has been removed, so treat that as an open question rather than an assumption.

Because the README defers to internal/config/config.go for the current list, an operator upgrading across versions should read that file rather than trust the table. That is a real maintenance cost, small but non-zero.

## Reverse proxies, WebSockets and what breaks first

The most common failure mode is not the game itself but the proxy in front of it. Scribble.rs uses WebSockets, and the README states plainly that when running behind nginx you must configure nginx to support that, pointing to a wiki page titled reverse-proxy-(nginx). Other reverse proxies "may require similar configuration", and the README invites contributions of working configurations to the wiki.

This is the point where a deployment that looked like one command turns into an afternoon. A default nginx location block that forwards HTTP will happily serve the page and then fail on the upgrade, and the symptom is a game that loads and then does nothing. If you have never configured WebSocket proxying, budget time for it.

The second limitation is observability. There is a Prometheus endpoint at /v1/metrics, but the README says it "currently doesn't expose a lot of information" and that the maintainer is willing to extend it on request as long as no personal data is exposed. The maintainer also runs a dashboard, but fly.io does not support public dashboards, so the data stays private. In practice you get an endpoint and not much to put on a graph.

The third is that this is a single-process game server with in-memory lobbies. Nothing in the README or the configuration table describes clustering, shared state between instances, or a database. If you need to serve a very large number of concurrent lobbies across machines, this is the wrong shape of tool, and no configuration key in the README changes that.

## Scribble.rs versus skribbl.io and other drawing games

The README names skribbl.io as the thing Scribble.rs is an alternative to, and the difference is structural rather than cosmetic. skribbl.io is a hosted service: you go to their site, you play on their servers, and the operator decides what runs, what is logged and what is shown alongside the game. Scribble.rs is a program you can run, with a BSD-3-Clause licence and a repository you can read.

That changes three things concretely. First, data locality: a self-hosted instance keeps game traffic on your machine, which is the entire point of the "privacy respecting" claim. Second, control over availability: the official instance is documented as shutting down when idle, so a self-hosted copy is the only way to guarantee the game is up when your group wants it. Third, the feature set is whatever the repository contains, and you can change it, because the source is there and the contributing guide asks you to open an issue before changing behaviour.

There is a cost to that. A hosted service gives you someone else's uptime and someone else's bug fixes. Running Scribble.rs means you own the reverse proxy, the container updates and the cleanup settings. The trade is straightforward and the README does not pretend otherwise.

## Licence, releases and what maintenance looks like

Scribble.rs is BSD-3-Clause. That is a permissive licence: it allows use, modification and redistribution, including in closed products, provided the copyright notice and licence text are retained. It does not impose a copyleft obligation on your own code. This is a description of the licence text, not legal advice; if you are embedding the project in something commercial, read the LICENSE file in the repository root and talk to someone qualified.

The release history listed in the repository is v0.9.12 (2026-02-09), v0.9.13 and v0.9.14, both on 2026-05-31. The last push to the repository was on 2026-09-06, which is recent, so the project is being worked on. The README also carries a hacktoberfest-accepted topic, which signals openness to outside contributions around that event.

Upgrade cost is low but not zero. Docker images are built on tagged pushes, so pinning a specific tag is possible and latest moves on its own. Because the README's configuration table defers to internal/config/config.go, a version bump can change the settings surface without the README changing. The honest operating procedure is to read that file after each upgrade rather than assuming the table is current. There is no documented migration or rollback procedure in the README, which is worth knowing before you upgrade a live instance that people are using.

## Conclusion

Adopt Scribble.rs if you want a small, self-hosted drawing game with no accounts, no ads and a configuration surface you can read in one file. Do not adopt it if you need horizontal scaling, a public metrics story, or a guarantee that a pre-compiled binary matches your platform. Verify three things before you commit: that your reverse proxy forwards WebSocket upgrades, which of the two current cleanup settings you actually need, and whether the latest release tag is the one you want to pin.

## FAQ

### Is Scribble.rs free to play and to host?

Yes. The README describes it as a free pictionary game with no advertisements and no account required, and the source is available under the BSD-3-Clause licence so you can host your own instance.

### How does the Scribble.rs game work?

It is a web-based pictionary game where players join a lobby, one player draws and the others guess, with the game state moving over WebSockets. The README positions it as an alternative to skribbl.io.

### Is Scribble.rs safe to play on?

The README states that the game requires no account and shows no advertisements, and that the Prometheus metrics endpoint is kept free of personal data. If you want full control over where game traffic goes, hosting your own instance is the option the project supports.

## Sources

- [Issues](https://github.com/scribble-rs/scribble.rs/issues)
- [License: BSD-3-Clause](https://github.com/scribble-rs/scribble.rs/blob/master/LICENSE)
- [README](https://github.com/scribble-rs/scribble.rs/blob/master/README.md)
- [Releases](https://github.com/scribble-rs/scribble.rs/releases)
- [scribble-rs/scribble.rs on GitHub](https://github.com/scribble-rs/scribble.rs)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/scribble-rs-scribble-rs
