A collection of the core tools that comprise the Patchwork system.
Tools in this collection should be reliable and maintained: these are the core tools, after all.
Within a given distribution, it is reasonable to assume these tools exist, however tools in this collection should never assume the existence of other tools.
Regardless, these tools should not depend on each other's implementations or their internal structure.
Each directory in this collection can be built completely independently. Tools do not share lockfiles, node modules, or even necessarily build systems or web frameworks.
Please be careful not to violate these isolation principles.
- External deps (
@inkandswitch/patchwork-*,solid-js, etc.) are pinned to normal published npm versions.
- A few tools depend on sibling tools in this repo
(
codemirror-markdown→codemirror-base,tenfold→codemirror-baseandcodemirror-markdown,account-picker→contact). Those are referenced aslink:../<sibling>in the sibling'spackage.json, which creates a live symlink intonode_modules. Building the sibling is enough — no publish step, noworkspace:*protocol.
cd history-view
pnpm install
pnpm buildFor tools that link: to a sibling, build the sibling first so its dist/
exists (e.g. codemirror-base before tenfold). Running pnpm -r build at
the root happens to go in alphabetical order, which puts dependencies ahead of
dependents for the current set of links.
From the repo root:
pnpm install # install in every tool
pnpm build # build every tool that has a build scriptThere is no root workspace — these just run pnpm recursively over each tool
directory. The filter (--filter './*' --filter '!./static-dist/**') excludes
the static-dist/ output folder, so they're safe to run even when a previous
bundle is still present. (A bare pnpm -r build would instead try to "build"
the copied bundles under static-dist/tools/* and fail, since those have no
node_modules.) Because install is a real script, plain pnpm install at the
root installs all the tools too.
The tools can be deployed as a static HTTP bundle and loaded by any Patchwork shell (the boot runtime). The two halves are independent:
- Tools bundle (lives here) —
static-dist/(modules.json+tools/<tool>/dist/…), produced byscripts/bundle.mjs. Deployed to Netlify (the repo is private, so GitHub Pages would need a paid plan).bundlealso writes a_headersfile grantingAccess-Control-Allow-Origin: *, which Netlify (and Cloudflare Pages) honour so a shell can load these tools cross-origin. - Shell (lives in
patchwork-next) — there is no separate shell in this repo. Any patchwork-next site is a shell;sites/tiny-patchworkis the canonical one (PWA-ready). The static-manifest support lives in the bootloader (ModuleWatcher/SiteConfig.defaultModules), so a shell just needs to point itsdefaultModulesat a tools host.
A shell can point at any tools host via PATCHWORK_SYSTEM_PACKAGE_LIST_URL (build time) or
localStorage.systemPackageListURL (runtime), so the same deployed shell can run
against an automerge: module-settings doc, this static tools bundle, a PR
preview, or a local tools server — no shell rebuild needed for the runtime
override.
pnpm install # install every tool (skips static-dist/)
pnpm build # build every tool (skips static-dist/)
pnpm bundle # aggregate built tool dist/ -> static-dist/ + modules.json
pnpm serve:tools # serve static-dist/ on :4455 with CORS (local tools host)
pnpm dev:tools # bundle + serve:tools
pnpm deploy:tools # bundle + netlify deploy --prod (static-dist/)A clean bundle from scratch is pnpm install && pnpm build && pnpm bundle
(which is exactly what Netlify runs).
modules.json uses relative ./tools/… URLs that resolve against the
manifest's own URL, so the bundle works at any host or base path.
The first pnpm deploy:tools will prompt you to log in and link/create a
Netlify site (netlify.toml sets the publish dir). After that it's one command.
Our production deployment goes to Netlify, so we have included a netlify.toml for
convenience.
To aid in branch review, we have configured deploy previews on the GitHub repo. The preview is of the tools bundle, so to test a PR's tools in any shell, point it at the preview's manifest — no shell rebuild needed:
localStorage.systemPackageListURL =
"https://deploy-preview-123--<site>.netlify.app/modules.json";Local development can deploy as usual via pushwork, but to test the build process you can always run a local webserver to host the JS and point your local shell at it.
# terminal 1 — tools host (in patchwork-base)
pnpm dev:tools
# terminal 2 — shell (in patchwork-next)
PATCHWORK_SYSTEM_PACKAGE_LIST_URL=http://localhost:4455/modules.json \
pnpm --filter tiny-patchwork devAt runtime you can also point an already-running/deployed shell at a tools host without a rebuild:
localStorage.systemPackageListURL = "http://localhost:4455/modules.json";To build a full set of modules for automerge-backed live development, run the usual install/build on all of them first. Once the tools are built, you can push each one to a module settings document using the following commands>
Right now this is a bit janky, but once you have the pushwork and the patchwork-modules CLI tool installed, you should be able to run:
export MODULE_SETTINGS_DOC_URL=`pw-modules init`
pnpm -r exec pushwork init
pnpm -r registerOf course, if you already have a patchwork modules document, you can supply it.