frontend
Five device-specific builds from one codebase
Five device-specific builds from one codebase
Five genuinely different surfaces from one codebase — admin dashboard, super-admin dashboard, kiosk (touchscreen), counter (operator), display (passive queue status, a TV in a waiting room). Each has different routes, different concerns and different hardware. A kiosk build has no reason to ship admin code; a display build has no reason to ship interactive form handling.
vite.config.ts
vite.config.admin.ts
vite.config.super-admin.ts
vite.config.kiosk.ts
vite.config.display.ts
vite.config.counter.ts
Each config points at a different entry and can apply its own build-time env vars, so the bundle shipped to a kiosk genuinely doesn't include admin-only code — real bundle-size and attack-surface reduction, not just routing convenience.
Why not one app with a runtime role check
A single app deciding "kiosk vs admin vs display" via a runtime check still ships all the code to every device; the browser just conditionally hides pieces. Fine for a normal web app where everyone has a real browser and reasonable bandwidth. For dedicated hardware — kiosk terminals and TV-mounted displays that might be older or bandwidth-constrained, and that shouldn't have any code path that could ever accidentally expose admin functionality even in a bug — genuinely separate minimal bundles are the more defensible choice.
Device identity is baked in at build time rather than resolved at runtime:
environment:
VITE_KIOSK_DEVICE_CODE: KIOSK-001
VITE_OPERATOR_DEVICE_CODE: COUNTER-001
Works well when a machine is provisioned once with a specific build and just runs — no "which device are you" login on every boot. The cost: reassigning which physical device is KIOSK-001 means rebuilding and redeploying that image, not changing a runtime value — a real operational cost if hardware gets swapped or relocated often.
The rule: when multiple frontend "roles" correspond to different physical hardware with different constraints and trust boundaries, separate builds are usually worth the added complexity. When it's genuinely the same kind of device — a browser, used by a person, just with different permissions — a single app with role-based routing is simpler and the better default.