modules/<kebab-name>/ like any other module, and its <name>.yml declares type: "spa".
What sets a spa module apart
A spa module is the browser application, the UI users see and interact with. It does not register controllers or run on the server alongside your API. Each spa is a standalone Vite app with its owndev, build, and preview scripts and its own dev port, so you run and ship it independently. Routing is file-based, with routes as folders and files under src/routes/, and server state is fetched and cached with TanStack Query, so there is no manual route table or ad-hoc fetch glue. A spa builds its UI on top of a design module, the shared design system; the chosen design is recorded in the spa’s yml, so components and tokens come from one place. Code is organized as vertical slices under src/features/, with cross-cutting code in src/shared/, so a domain’s routes, components, and hooks live together.
How it differs from a backend module
A regular module (or a microservice) is server-side: it registers intoAppModule or SharedModule, exposes path aliases in the root tsconfig, and runs as part of the API. A spa module does none of that. It is a browser app that the API serves to the client.
How it works
talos spa:create scaffolds a base module, marks it type: "spa", and clones the upstream skeleton-spa repository into the module’s src/. It then installs the spa dependencies and assigns a free dev port (3030 by default, or the next free port if that is taken) by adding dev, build, and preview Vite scripts to the module’s package.json. During creation you also pick the design module the spa composes (an existing type: "design" module or a new one), recorded as design: "<kebab>" in the spa’s yml.
A spa module’s tree therefore looks like this:
Working with a spa
Once created, you build the app out with the generators:- Add a feature slice with
talos spa:feature:create— see Features. - Add a translation hook with
talos translation:create— see Internationalization. - Remove a spa with
talos spa:remove— see Remove.
Next steps
- Structure — the full layout of a spa module.
- Features — vertical slices and
spa:feature:create. - Routing — file-based routing with TanStack Router.
- Data fetching — server state with TanStack Query.
- Internationalization — translation hooks in a spa.
- Create —
spa:createin full. - Remove —
spa:removein full. - Design System — the design module a spa composes.
- Modules — how backend modules differ.