Modules
What a module installs, how it reaches your page, and how to remove it.
What a module is
A module is a working feature in src/features/<name>: components, API functions, hooks, schemas and tests, in the same structure as the template and the ViraStack AI rules.
Modules run on a dummy API or dummy data. Connecting your real API and adapting the response model is your work.
Ready modules
| Module | What it does |
|---|---|
users | A user table with search, pagination, and actions to add, edit and delete users. |
checkout-address | The chosen address shows on the page; listing, adding and editing happen in a popup. Shipping and billing can differ. |
checkout-card | The chosen card shows on the page; saved cards are listed in a popup, where you can add a new one. The card number and CVV never reach the network, and you connect your payment provider in one place. |
All modules, with previews, are in the module catalog.
Add a module
Run it from the root of a project created with Start 2.0 or newer:
$ pnpm dlx virastack@latest add users- The module’s files go to
src/features/<name>. - Missing packages and
components/uicomponents are installed. - In i18n templates, its messages are merged into
src/messages. - If a file or message with the same name already exists, nothing changes and the CLI lists the conflicts.
- No page is created. Which page it goes on is your decision.
Add it to a page
After installing, the CLI prints the import line and the module’s link. On that page, choose your framework, i18n and page path, then copy the prompt for your AI coding tool or follow the manual steps.
Example: a checkout page
checkout-address and checkout-card are separate modules. Install both and render them on the same page:
$ pnpm dlx virastack@latest add checkout-address$ pnpm dlx virastack@latest add checkout-cardNext.js: src/app/checkout/page.tsx
import { CheckoutAddress } from "@/features/checkout-address/components/CheckoutAddress"
import { CheckoutCard } from "@/features/checkout-card/components/CheckoutCard"
export default function CheckoutPage() {
return (
<main className="mx-auto flex w-full max-w-xl flex-col gap-8 px-6 py-12">
<CheckoutAddress />
<CheckoutCard />
</main>
)
}TanStack Start: src/routes/checkout.tsx
import { createFileRoute } from "@tanstack/react-router"
import { CheckoutAddress } from "@/features/checkout-address/components/CheckoutAddress"
import { CheckoutCard } from "@/features/checkout-card/components/CheckoutCard"
export const Route = createFileRoute("/checkout")({
component: RouteComponent
})
function RouteComponent() {
return (
<main className="mx-auto flex w-full max-w-xl flex-col gap-8 px-6 py-12">
<CheckoutAddress />
<CheckoutCard />
</main>
)
}In i18n templates, the file goes to src/app/[locale]/checkout/page.tsx or src/routes/{-$lang}/checkout.tsx, whose route is /{-$lang}/checkout.
Features cannot import each other, and shared folders cannot import features, so the page connects them. Read the choices with these hooks in the page:
const { shipping, billing } = useCheckoutAddress()
const { card } = useCheckoutCard()card carries a token, the bank, the brand, the last four digits, the expiry and the name; the card number and CVV never leave the browser. On Next.js, call the hooks in a client component next to page.tsx; on TanStack Start, call them in RouteComponent.
Remove a module
$ pnpm dlx virastack@latest remove usersDeletes the module’s files, the folders they leave empty and its messages. Packages stay, because other code may use them.
If you changed any of those files, it lists them and asks first. In a script, pass --yes to delete them too; without it, nothing changes.
The page you wrote stays. Remove its import yourself.