Cruciverb
v0.1.0 - Self-hosted · Web · Docker

Cruciverb - self-hosted daily crossword server with handwriting input and federation. A crossword a day,
written in your own hand.

A self-hosted daily crossword server where you can draw the letters with a pen.
No ads. No tracking. No accounts. No algorithm deciding what you see.

Zero telemetry No email or password CC0 Public Domain
Cruciverb main page with the custom puzzle builder open
5 Daily difficulty tiers
668K Clue pool
30 Achievements
CC0 Public domain

Crosswords belong
to the commons.

Crosswords have been a public pleasure for over a century. Cruciverb keeps them that way - a grid, a pen, and a deadline, run the way a co-op should run. Each community owns its own instance, shares with its neighbors, and answers to no head office, because there isn't one.

Collects nothing

No analytics, no telemetry, no tracking scripts. Your solves and streaks are yours.

Costs nothing

No paywall, no premium tier, no coins. Free, unconditionally, for everyone.

Requires no account

You're an anonymous session the moment you arrive. Optional passkey if you want it.

Owns nothing

CC0 - the most complete relinquishment of rights possible. The code belongs to everyone.

A proper crossword,
built for real solvers.

Handwriting Input

Draw the letters, don't just type them.

Write answers with your finger or stylus. Recognition runs entirely in your browser through ONNX, the browser's own handwriting API, and a tesseract fallback - fused by an ensemble. An ink overlay with a zoom strip and a disambiguation popup makes a touchscreen feel like pen on paper.

In-browser recognition
Stylus with pressure
Ink overlay + zoom strip
Daily Puzzles

Five tiers, one grid a day.

From a 5x5 warm-up to a punishing 21x21, seeded so every solver on the instance gets the same puzzle and the same bragging rights. Speedrun, blind, and marathon modes, plus a rotating daily challenge.

Streaks & solve history
Daily challenges
Federation

Instances that talk to each other.

Cruciverb speaks ActivityPub. Remote puzzles appear on your boards, community clues flow both ways, leaderboards federate, and solves are cryptographically signed so they follow you between instances.

Signed solve receipts
No central server
Community

A clue pool everyone shapes.

Anyone can submit a clue and vote on others. Approved clues flow into future generations. Build a puzzle in the editor, publish it, and watch it land on everyone's boards. A clue trainer sharpens your solving.

Submit & vote on clues
Community puzzle editor
Play Together

Share a grid, live.

Multiplayer rooms with visible cursors for the people solving beside you. Co-op, race, and party modes - submit a fake answer, vote on which is real, then race to type the actual one.

Live shared grid
Co-op, race & party
Accessibility

Built for every solver.

WCAG 2.2 AAA with a screen-reader narrator, keyboard-only play, colorblind palettes, text scaling to 200%, reduced-motion animations, and a tor-friendly mode that keeps the page light.

WCAG 2.2 AAA
Screen-reader narrator

See it in action.

Questions, answered.

Do I need an account to play?

No. You're an anonymous session the moment you arrive - no email, no password, no signup wall. If you want a durable identity across devices, you can optionally add a passkey. Otherwise nothing is asked of you.

Does it track me or show ads?

No. There are no ads, no analytics, no trackers, and no engagement dark patterns anywhere on the page. Your solves and streaks stay on your instance and your device.

How do I run my own instance?

It's a single Docker image. Pull it from the repo, copy the example docker-compose.yml and .env, set your domain, and docker compose up -d. No build step - the image is prebuilt. You can also run from source with Cargo and a Vite frontend.

What does "federated" mean here?

Instances connect over ActivityPub (the protocol behind Mastodon). Once federated, remote puzzles show up on your boards, community clues flow between instances, leaderboards span the network, and signed solve receipts let you carry your history to a new instance.

Everything else
you'd expect.

Signed Solve Receipts

Portable, cryptographically signed records of your solves that verify - not trust - when you move between instances.

PWA Offline Support

An IndexedDB cache and offline progress sync mean a dropped connection never eats a solve.

Speedrun & Marathon

Per-preset time limits, plus a marathon mode of 120-second grids where one failed puzzle ends the run.

Daily Challenges

A rotating per-preset challenge - purist, speed demon, surgeon, night owl - on top of the regular grid.

Pencil Marks & Undo

Pencil marks, undo and redo stacks, and cell animations that reserve space instead of shifting the grid.

Import & Export

Read and write IPUZ and PUZ, export to PDF, share puzzles with QR codes and og-image cards.

RSS & Atom Feeds

Feeds of your solves, plus an embeddable player build you can drop into any page.

Real Admin Tools

Clue queue moderation, word blocklists, audit logging, bans, and fine-grained federation controls with a freeze switch.

Three steps.
Your own instance.

a

Pull the image

The server image is published on the repo. Nothing to compile - docker login git.lashman.live and pull.

b

Configure

Copy docker-compose.example.yml and .env.example, set your domain and federation names, add a DATA_ENC_KEY if you want storage encryption.

c

Up & federate

docker compose up -d. It serves on port 8484. Then follow a neighbor instance and the puzzles start flowing.

A Rust engine,
a React grid.

A Rust backend (Axum + SQLite) with a CSP grid generator, an ActivityPub layer for federation, and a Vite + React 19 + TypeScript frontend. Handwriting runs in the browser with ONNX and a tesseract fallback. Encrypted at rest, no telemetry, no third-party requests.

Rust Axum SQLite React 19 TypeScript Vite ONNX Tesseract ActivityPub WebAuthn Docker

Run your own
crossword server.

No ads. No tracking. No engagement tricks. Just a grid, a pen, and a deadline - on a server you control.

Self-hosted · Docker Any browser v0.1.0