docs: answer the launch objections in the README - #16
Conversation
The first r/node thread asked two questions and raised one objection. Every one of them was about material the README implied but never stated plainly, so a reader had to ask instead of read. The top objection was the abstraction boundary: why not plain rows and transactions. That answer lived in "Good and poor fits", far below the code, so the README now states it before the first example. The comparison table listed Cloudflare, Rivet, DBOS, and Restate, but not celld, which is the project readers now compare against; celld is now a sourced row in both tables with a short paragraph on where each one fits. The quickstart described its assertions without printing them, so it now shows the verified output. The early release note repeats the one deployment maturity sentence that solidobjects.dev uses, so the two do not drift again. The quickstart command resolves @latest instead of a pinned version. The pin went stale one release after it was written.
Greptile SummaryAdds clearer guidance about project maturity and when SQL transactions are preferable, documents verified quickstart output using the latest published package, and expands the comparison material with celld.
Confidence Score: 5/5The documentation-only PR appears safe to merge. The quickstart output matches the current packaged executable contract, the comparison additions are internally consistent, and no concrete incorrect or broken documentation was established. Important Files Changed
Reviews (1): Last reviewed commit: "docs: answer the launch objections in th..." | Re-trigger Greptile |
celld launched on August 5 with the sentence "self-hosted, distributed Durable Objects". Four strangers reused it verbatim as a Hacker News title within nine days. Our first line started with those same four words, so it read as a derivative of a project with 4,000 stars. The first line now names what only this project does: the SQL database the application already runs, with no daemon, broker, or new datastore. celld also puts a table of measurements where most projects put adjectives. Our numbers already existed in docs/benchmarks.md, which nobody reads before deciding whether to try the package. The README now shows eight of them, including the two that are not flattering: MySQL throughput and the one-second polling-only wake-up. Each throughput range spans the synchronous and asynchronous handler shapes, so no row selects the better of the two.
|
Second commit, from the celld launch research. Tagline. The first line was "Self-hosted, distributed Durable Objects in Node without a daemon using your existing SQL database". celld's own line is "self-hosted, distributed Durable Objects", and four separate people reused it word for word as a Hacker News title between August 5 and August 13. Ours started with their four words. It now reads: "Durable Objects for Node, in the SQL database you already run. No daemon, no broker, and no new datastore." Measured behavior. celld's front page is a table of numbers where most projects put adjectives. Ours already existed in Each throughput range spans the synchronous and the asynchronous handler shape, so no row picks the better of the two. The section states the machine, the date, the operation count, and the concurrency, and links to the full matrix and the bias list. Two numbers celld publishes that we cannot yet: memory per resident actor, and recovery time after a kill. |
An audit against the published lists of AI-writing tells found no vocabulary problem. The word list matched 8 times in 18,112 words, and every hit was "harness" as a technical noun. There were no em dashes. The tells here were structural: 50 sentences longer than 25 words, and 16 comma-plus-participle clauses, which language models produce several times more often than people do. Both also break the Simplified Technical English rules this project writes to. The prose now splits at the semicolon, names the agent instead of using the passive, and puts complex conditions in vertical lists. The eight remaining long "sentences" are vertical lists that the audit script rejoins. The three remaining participles are "fencing" and "rendering", which are technical names. Tables, code blocks, and every technical claim are unchanged.
The quickstart printed four JSON fields and nothing else. A reader had to already know what sameIdentityFinalState meant, and the command created a database before it said what it would do. It now states its plan, prints the Counter class it runs, asks for permission, does the work, and then explains what each PASS proves. It ends with the install command and a prompt to ask a coding agent where the library fits. The question appears only when stdin is a terminal, so CI never waits. --yes skips it, and --json restores the original machine-readable output for scripts. End of input during the question counts as a refusal, which previously exited 1 with an unhandled readline error. The report module is pure text, so the tests cover the wording, the FAIL rendering, and the answer parsing without a runtime. The packaged smoke test asserts both output modes, the plan-before-results order, and the absence of a prompt without a terminal.
The published PostgreSQL and MySQL numbers came from Docker Desktop, so they measured the container as much as the database. MySQL read as 28 to 30 committed operations per second, which invited the reasonable conclusion that the library is slow on MySQL. The same server version now ran natively and in Docker on the same machine, on the same day, through the same harness. Native PostgreSQL 17.11 reached 266 to 331 operations per second on one hot identity across four processes, against 68 to 90 in the container. Native MySQL 9.7.1 reached 214 to 228, against 59 to 60. Across the matrix the container cost 1.0x to 7.8x. The observed results now come from native servers, a virtualization section records the cost, and the bias list states the measured range instead of a vague warning. The README table and the quickstart output follow the new run.
`solid-objects quickstart | head` crashed. The reader closes the pipe, the next write raises EPIPE on stdout, and an EPIPE with no listener is an unhandled error event, so Node printed a stack trace and exited 1. Piping a command into head, less, or grep -m is ordinary use, and a stack trace there reads like a defect in the library. The executable now listens on stdout and stderr, exits 0 on a broken pipe, and rethrows every other stream error, so a full disk still fails loudly. The quickstart prints its plan before it creates anything, and its report prints after cleanup, so an early exit cannot strand a temporary database. The packaged smoke test now runs the installed binary into head with pipefail set.
The first line said "for Node", but the package serves JavaScript and TypeScript applications, so it now says "for JavaScript". The quickstart section reprinted the whole command output. That output now explains itself when a reader runs it, so the copy is duplicated work that ages the moment the wording changes. Two sentences describe the behavior instead, and they keep the --yes and --json flags, which appear nowhere else outside the help text.
Why
The first r/node thread produced two questions and one objection. All three were about material the README implied but never stated plainly.
docs/comparisons.md, with a paragraph on where each one fits and a primary reference.Changes
solid-objects@latestin the quickstart command instead of a pinned version that goes stale each release.Verification
node scripts/check-documentation.mjspasses.prettier --check README.md docs/comparisons.mdis clean.npm exec --yes --package=solid-objects@latest -- solid-objects quickstartprinted the exact JSON now in the README.