Quick start
By the end of this guide you'll have two projects running side by side: an app shell (the host) and a pilet (a feature module) rendering inside it with hot reload. That pairing is the whole micro frontend pattern in miniature.
Prerequisites
You need Node.js 18 or newer. Everything else is fetched on demand by npm — there is no global CLI to install.
piral-cli
Older guides told you to run npm install -g piral-cli. That's no longer recommended. The scaffolders below add piral-cli as a local dev dependency, and you run it through your project's npm scripts (npm start, npm run build) or with npx. This keeps every project pinned to its own CLI version.
1. Create the app shell
Scaffold a new shell with an npm initializer. The --bundler flag picks (and installs) a bundler plugin — webpack5 is a safe default; esbuild, rspack, vite, and parcel2 are also available.
Start the development server:
Open http://localhost:1234. The shell is running — intentionally empty, because no pilets are loaded yet.
When you're ready to share the shell with pilet developers, build it:
That second output, the emulator, is what makes local pilet development possible without running the whole platform. More on that shortly.
2. Create your first pilet
Open a second terminal and keep the shell running. Scaffold a pilet that targets the shell you just built. During development, point --source at the freshly built emulator tarball so you don't need a published package yet:
Once the shell is published to a registry, pilets can instead use --source my-app-shell to pull the emulator by package name. That registry doesn't have to be public npm — a private/company or local registry works too, and you can skip registries entirely by debugging against an emulator website.
Open src/index.tsx and register a page:
Start the pilet's dev server:
Visit http://localhost:1234/hello. Your pilet's page renders inside the real app shell, with hot reload active.
3. Add navigation
A page nobody can reach isn't much use. Register a menu item too:
Save the file — the nav link appears immediately, no restart required.
What just happened
You now have two completely independent projects:
The app shell owns layout, authentication, navigation chrome, and the runtime. It has no knowledge of your pilet. The pilet registered itself at runtime through the Pilet API. It has no knowledge of how the shell renders it.
These can be deployed independently, owned by different teams, and versioned separately. That separation — one stable host, many independently shipped features — is the entire point of Piral.
You can load pilets from a real feed alongside your local one, which is handy for testing cross-pilet interactions:
Next steps
Now that the pieces are moving, a little theory goes a long way:
- See how everything fits together in the Architecture overview.
- Learn the project structure conventions for shells and pilets.
- Build a production-grade shell in Building your app shell.