zigapagos
v0.5.0
Published
Zigapagos static site generator — alias for @zigapagos/cli.
Downloads
936
Maintainers
Readme
zigapagos
This package is an alias. It exists so that npx zigapagos works and the
unscoped name belongs to the project; it contains one three-line launcher and
nothing else.
The canonical package is
@zigapagos/cli — this package
depends on it at the exact same version (0.5.0) and re-exposes its zigapagos
bin. Platform resolution, the binary, and the documentation all live there.
npx zigapagos init # scaffold a site
npx zigapagos dev # dev loop on http://127.0.0.1:1990For programmatic use, depend on @zigapagos/cli directly — this package exports
nothing.
Supported platforms
| Host | Package | Status |
| --- | --- | --- |
| macOS x64 | @zigapagos/cli-darwin-x64 | native |
| macOS arm64 | @zigapagos/cli-darwin-arm64 | native |
| Linux x64 | @zigapagos/cli-linux-x64 | native |
| Linux arm64 | @zigapagos/cli-linux-arm64 | native |
| Windows x64 | — | not supported yet — use WSL2 |
Requirements
- Node.js >= 18 — runs the launcher; the binary itself is native.
- One of the platforms in the table above.
Nothing else. No Zig toolchain, and no separately-installed Bun.
What this package can build
Everything, from npm i zigapagos alone:
- the whole content pipeline —
init,migrate(the Astro importer),doctor,validate,explainandrelease; - islands (
.island.tsx) — server-rendered through the bundled Bun sidecar and hydrated in the browser from a client bundle built by the same Bun; - native SPAs (
.spa.tsx) — prerendered route skeletons plus a code-split client bundle, including lazy routes, per-routemodulepreloadand the per-deployable runtime slice; zigapagos dev— the watch/rebuild loop, served by zigbase.
To make that true the package carries three things beyond the binary: the
@z/runtime sources and the Bun build tools (in runtime/), and dependencies on
bun, @zigbase/server and typescript so the tools it shells out to are
installed rather than asked for. The last three are OPTIONAL dependencies:
--omit=optional still builds, it just loses dev's server, and the SPA runtime
slicer falls back to the shared runtime.
This is not a reduced build. There is no other kind: zigapagos release is
what builds every zigapagos site, including this project's own, and it is this
binary. Both runtime slices are computed — the per-SITE islands one and the
per-deployable SPA one — and the host-config and strict-CSP artifacts are
emitted with the rest of the tree.
The size, and where it goes
npm i zigapagos is ~535 MB installed on linux-x64. Measured, not estimated:
| Component | Installed | Why |
| --- | --- | --- |
| @oven/bun-* + bun | ~347 MB | the Bun binary — SSR and client bundling |
| @zigapagos/cli-<platform> | ~156 MB | the zigapagos binary |
| typescript | ~24 MB | the compiler API the SPA runtime slicer parses with |
| @zigbase/server-<platform> | ~4.8 MB | the server dev runs |
| preact + preact-render-to-string | ~3.1 MB | imported by the bundled runtime |
| @zigapagos/cli (launcher + runtime/) | ~0.7 MB | the sidecar and @z/runtime sources |
Two thirds of that is Bun, and most of Bun's share is npm over-fetching rather
than Bun itself: the @oven/bun-linux-x64* packages declare no libc, so on a
linux-x64 host npm installs the glibc, musl, baseline and musl-baseline builds —
four ~87 MB binaries where one is used. That is upstream packaging, not something
this package can select around.
There is no smaller supported install. --omit=optional does not give you a
lean content-only CLI: the per-platform @zigapagos/cli-<platform> package is
itself an optional dependency (that is how one binary is fetched instead of all
of them), so omitting optional dependencies removes the zigapagos binary too and
leaves an install that cannot run at all — binaryPath() says exactly that if
you try. If you need a build-only footprint, use the
release archives rather than npm.
Building a site with islands
Nothing special:
npm i zigapagos
npx zigapagos init
npx zigapagos release --output=public --forceThe build finds your *.island.tsx entries by scanning the site root, so there is
no list to keep up to date. --island=SRC (repeatable) overrides the scan when
you want an exact set — worth doing once a project is more than a few files: the
scan's order follows the filesystem, and it does not skip a vendored tree.
That scan is not a convenience. The two halves of an island come from different places — the SSR'd markup from the Bun sidecar, the client bundle from Bun — and only the first is automatic. A page whose bundle was never built renders perfectly and then 404s on hydration, with nothing wrong-looking in the output tree, so the entries are discovered rather than left to be forgotten.
Your components import @z/runtime by its bare name: the sidecar serves that
specifier from the copy inside this package, and on the client an import map
points it at the one shared /zigapagos-runtime.js, so the page ends up with a
single Preact instance.
See docs/islands.md.
Worth turning on: --island-props-check=error (the tsc gate that typechecks
island props against their Props interface) is off by default. Pass it to opt
in; the typescript this package already installs is the one bun x tsc will
find.
Building a native SPA
Also nothing special. Write a *.spa.tsx exporting spa and routes and run
the same release: the scan that finds islands finds SPA entries too, and each
one's spa.base decides where it mounts. --spa=SRC|BASE (repeatable) overrides
the scan, and |BASE there is a base restated for the build to check against the
module — omit it and the module is simply believed.
Each SPA gets prerendered route skeletons and
a _shell.html per dynamic pattern, a per-namespace routing-manifest.json, a
code-split client bundle under /spa/ (one entry chunk plus one content-hashed
chunk per lazy(() => import(…))), a modulepreload for the chunk each route
needs, and the per-deployable runtime slice — /spa/<name>-runtime.js when the
slicer can prove which host.* members the SPA uses, the shared
/zigapagos-runtime.js when it cannot. @z/runtime stays external in every
bundle, so a page carrying both a SPA and islands still has one Preact.
See docs/spa.md. The routing manifest is also
what the host-config emitters read, and release runs them, so the .spa marker
(zigbase), nginx.nginx.conf or .htaccess your deploy needs is already in the
output tree.
zigapagos dev
npm pkg set scripts.dev="zigapagos dev --site=public"
npm run dev # dev: zigbase = …/node_modules/.bin/zigbase (path_env)The zigbase that dev serves through is
installed with this package, at the exact version the CLI pins — so the npm path
and the --download-zigbase fallback can never disagree. The launcher adds this
install's node_modules/.bin to the child's PATH, so a bare zigapagos dev
finds it too, not just npm run and npx.
A zigbase already on your PATH still wins, and --zigbase=PATH still overrides
both.
License
MIT — see the repository.
