Vimo
One site, one portal and one login for a suite of SaaS products for small businesses in Argentina.

Vimo groups seven products, and each one lived in its own repo. There was no site that sold them together, no portal after sign-in and no shared brand. The design repeated each product's price and color on four different screens.
Three decisions that shaped it.
- 01
One login across subdomains
Why. Each product deploys on its own subdomain. One Clerk instance shares the session through the parent domain. The contracted modules travel in the session token, so apps check access without a database call.
Trade-off. The token has a size limit, so only module ids go in it. A product on its own domain stays outside the shared login.
- 02
Brand and pricing as code, not copy
Why. Colors, names and prices live once in TypeScript packages. The pricing calculator and the plan recommender call the same pure functions. Design tokens compile to CSS, so a React Native app can import the same values later.
Trade-off. Tokens need a generation step. If someone edits the TypeScript and skips it, the CSS is stale.
- 03
Local dev on subdomains, not ports
Why. Browsers share cookies across ports, so a login test on localhost passes for the wrong reason. A Caddy proxy serves each app on a vimo.localhost subdomain. Tests now see the same cookie rules as production.
Trade-off. Running locally needs Docker and a few more steps. The E2E suite also starts four sibling repos.




Vimo
One site, one portal and one login for a suite of SaaS products for small businesses in Argentina.
- Role
- Design implementation, architecture and frontend
- Stack
- Next.js 16, React 19, TypeScript, Clerk, Turborepo, Playwright

Vimo groups seven products, and each one lived in its own repo. There was no site that sold them together, no portal after sign-in and no shared brand. The design repeated each product's price and color on four different screens.
Three decisions that shaped it.
One login across subdomains
Why. Each product deploys on its own subdomain. One Clerk instance shares the session through the parent domain. The contracted modules travel in the session token, so apps check access without a database call.
Trade-off. The token has a size limit, so only module ids go in it. A product on its own domain stays outside the shared login.
Brand and pricing as code, not copy
Why. Colors, names and prices live once in TypeScript packages. The pricing calculator and the plan recommender call the same pure functions. Design tokens compile to CSS, so a React Native app can import the same values later.
Trade-off. Tokens need a generation step. If someone edits the TypeScript and skips it, the CSS is stale.
Local dev on subdomains, not ports
Why. Browsers share cookies across ports, so a login test on localhost passes for the wrong reason. A Caddy proxy serves each app on a vimo.localhost subdomain. Tests now see the same cookie rules as production.
Trade-off. Running locally needs Docker and a few more steps. The E2E suite also starts four sibling repos.



