🌊 What is Dear Stranger?
I recently launched Dear Stranger (dearst.app) — a cozy, anonymous, collaborative pixel art web game.
The concept is inspired by the old tradition of casting a message in a bottle into the ocean:
- Cast a bottle: You start by drawing a few pixel strokes on a small canvas (or choose from 8 classic masterpieces like Van Gogh's Starry Night or Monet).
- Drift across the sea: Your bottle travels across the world to strangers.
- Collaborate: 2 to 4 strangers take turns painting their fair share.
- Returns home: Once complete, the bottle journeys back to everyone who participated, complete with a celebratory replay of each painter's strokes and a travel map showing the countries it sailed through!
Play it directly in your browser (no sign-up required):
👉 https://dearst.app
🛠️ The Tech Stack: Exactly 0 npm dependencies
As web developers in 2026, our node_modules folders often weigh hundreds of megabytes just to render a button. For Dear Stranger, I set a personal challenge:
Can we build a full-featured, persistent, real-time multiplayer collaborative web app with ZERO external npm dependencies?
The answer is yes.
1. Pure Vanilla JS on the Frontend
- Zero build tools: No Webpack, Vite, or Babel. Browsers have supported native ES modules for years.
- HTML5 Canvas & SVG: Custom pixel manipulation, touch-enabled zooming/panning, and color palette sampling.
- Dynamic Voyage Map: Natural Earth 1:50m geographic landmass rasterized into an ultra-compact dot grid rendered with pure SVG paths and beacons.
2. Node.js Built-in Standard Library on the Backend
- Built on Node's native HTTP server and
node:crypto. -
Pure Web Push: RFC 8291 payload encryption and RFC 8292 VAPID signatures implemented purely with
node:crypto— noweb-pushnpm package required. - SQLite with WAL mode: Fast, zero-config persistent storage with foreign keys and immediate transactions.
3. Internationalization (i18n) from Day One
The game natively supports 5 languages:
- 🇰🇷 Korean
- 🇺🇸 English
- 🇫🇷 French
- 🇯🇵 Japanese
- 🇨🇳 Chinese
Even the system NPC (Lighthouse · Keeper) and world country labels dynamically localize using the native Intl.DisplayNames API!
🎨 Game Design: Solving the "Trolling & Slacking" Problem
Collaborative art on the internet is notorious for two problems: trolls overwriting others' work and slackers drawing 1 pixel and dumping the rest on the next person.
Here is how Dear Stranger solves it through game mechanics:
- The 75% Fair Share Quota: Each painter receives an equal allocation of the remaining blank cells. You must fill at least 75% of your quota before the game lets you send the bottle onward.
- No Overwriting: Pixels already laid down by earlier strangers are immutable and locked.
- Report & Restoration (Kintsugi for pixels): If someone draws something offensive, any player can report that layer. The offender's layer is immediately hidden, and a blank space is created so another stranger can step in to restore the painting!
🖼️ What's next?
We launched with 8 classic museum masterpieces in both guided tracing mode and 64-pixel challenge mode. We plan to continuously add more classical artworks and community features.
Feel free to pick up a bottle, paint a few pixels, and see where your art travels:
🌊 Play the game: https://dearst.app
I’d love to hear your thoughts, feedback, and questions in the comments below!

Top comments (2)
0 npm dependenciesで、Web Pushの暗号化までnode:cryptoで実装された点に驚きました。依存関係を増やさない選択が、長期の運用やセキュリティ面でも効いてきそうです。75%のFair Share Quotaと上書き禁止の組み合わせも、「1ピクセルだけ描いて押し付ける」問題を仕組みで解決していて面白いと思いました。質問ですが、通報されたレイヤーの復旧は、参加者が任意のピクセルを描き直せる仕組みですか?それとも元の下絵に戻す形ですか?
温かいコメントと技術的な部分まで細かく見ていただき、本当にありがとうございます!Web Pushの暗号化(RFC 8291)も外部ライブラリに頼らず標準モジュールだけで組み上げたので、そこに気づいて評価していただけてとても嬉しいです。
ご質問の「通報されたレイヤーの復旧」についてですが、結論から言うと【参加者が任意のピクセルを描き直せる仕組み】になっています!
具体的には以下のような流れです:
機械的に下絵にロールバックするのではなく、「傷ついた作品を別の見知らぬ誰かが手作業で修復してあげる」という温かい協同体験を目指してこのような仕様にしました。
興味を持っていただき、重ねて感謝申し上げます!