# ADR-0002: Choose Flying Squid as server core - **Status:** Accepted (amended by [ADR-0013](./0013-bare-pear-only-runtime-and-distribution.md)) - **Date:** 2026-07-30 - **Amended:** 2026-07-30 ## Context We need an embeddable Java Edition–compatible server that runs locally inside our app lifecycle, supports plugins, Anvil worlds, and modern protocol versions — without operating a central host. Production runtime must be **Bare/Pear only** (no app-level Node.js). ## Decision Use **[Flying Squid](https://github.com/PrismarineJS/flying-squid)** (`flying-squid` npm) as an **embedded library** via `createMCServer`, running **inside Bare** (in-process or Bare worker) via **`bare-node-runtime`** compatibility imports — **not** as a Node.js child process. - Plugins: `module.exports.server` / `player` / `entity` - Worlds: Anvil via `worldFolder` / prismarine-provider-anvil - Default product target version: latest Squid-tested (e.g. 1.21.4), configurable - Bind: always `127.0.0.1` ([ADR-0005](./0005-local-only-bind-invariant.md)) We will **not** fork Squid initially; prefer plugins, thin lifecycle wrapper, and Bare `imports` maps. Compatibility gaps → shims/patches, not Node spawn ([ADR-0013](./0013-bare-pear-only-runtime-and-distribution.md)). ## Consequences ### Positive - JS/Prismarine ecosystem retained under Bare via holepunch compat layers - Plugin surface for border detection, chat bridge, bind guard - Broad version support (1.8.8–1.21.4 tested upstream) - Fits single Bare executable / Pear OTA story ### Negative / tradeoffs - Gameplay parity ≠ full vanilla Paper/Spigot - Heavy dependency graph; Bare packaging + imports maps required - Squid is Node-authored — Bare load is a critical spike (not free) ### Follow-ups - [ ] Phase 1 Bare Squid manager + bind force under bare-node-runtime - [ ] Document imports map for Prismarine stack - [ ] Plugins `fj-bind-guard`, later mesh plugins