Project structure
App shell
piral.json configures the CLI for this shell — the entry file, bundler, dev port, and public URL. It's optional (sensible defaults apply) but it's where you tune how the shell builds and debugs. See the configuration reference.
src/index.tsx
The entry point creates the Piral instance and renders it:
package.json — importmap for central sharing
Declare centrally shared dependencies here so all pilets receive them as externals:
Pilet
pilet.json is the pilet-side counterpart to piral.json: it records which app shell this pilet targets, the bundler, dev port, pilet schema, and an optional feed URL for pilet publish. See the configuration reference.
src/index.tsx
Every pilet exports setup:
package.json — pilet fields
Key fields:
inherit
"inherit": ["my-app-shell"] is what tells the pilet to reuse the dependencies the app shell already shares (React, the router, your design system) instead of bundling its own copies. It's technically optional, but without it a pilet will bundle packages like React itself — bloating the bundle and risking duplicate React instances on the page. Scaffolded pilets include it by default; keep it.
Monorepo layout
For teams managing multiple pilets:
pnpm-workspace.yaml:
In each pilet's package.json, reference the local app shell directly:
workspace:* tells pnpm to use the local workspace copy — no npm publish needed during development. See Monorepo setup for a complete configuration.