Products
Team projects
Bolta micro frontends and design system
I reworked the frontend for Bolta, an electronic tax invoice service, introducing independent app deployments, a shared design system, and stability improvements.
99.8%Crash-free rate measured in Sentry, up from 96%
- Period
- 2024.10 ~ 2025.06
- Organization
- Bolta Corporation
- Role
- Frontend architecture migration and design system
- Key features
- I separated the apps so each could be deployed or rolled back independently, and brought their interfaces under a shared design system.
- Work and results
- Crash-free rate improved from 96% to 99.8%, measured in Sentry
- Scattered interface pieces unified into one design system
- Bulk notification processing moved to a Web Worker to reduce UI load
- Tech stack
- Next.js
- Turborepo
- Vercel
- Shadcn
- TanStack Query
- Zustand
- Web Worker
- Sentry
Context
I reworked the frontend architecture at Bolta, an electronic tax invoice service. As the service grew, building and deploying everything together became a burden, and interfaces differed between apps.
I separated the apps for independent deployment and built a shared design system. As I migrated the existing code, I also improved stability and addressed stuttering when real-time notifications arrived in bulk.
Decisions and implementation
- Micro frontend migration: To let each app deploy on its own, I migrated the monolith to micro frontends step by step. I set up a Turborepo monorepo, defined the boundaries between apps and packages, and split cache units so only changed apps were rebuilt.
- Moving from AWS Amplify to Vercel, I gave each app its own project so it could deploy and roll back independently, and shortened the deploy cycle with Next.js build caching and bundle optimization.
- Shadcn design system: I put the company’s design tokens in a separate layer and wrapped Shadcn components so they received styles only through those tokens.
- I defined the component prop contract on three axes (intent, size, and variant) so new variations could be expressed inside the system. Several apps consumed the same package, and I moved the scattered UI into it gradually.
- FSD migration: I adopted Feature-Sliced Design (FSD) to decouple the domains, and used TanStack Query to organize the data flow and remove unnecessary global state.
- I migrated the legacy code gradually to spread the risk, and confirmed in Sentry that the crash-free rate rose from 96% before the stability work to 99.8% after it.
- I moved bulk notification handling into a Web Worker that combined SSE event processing, central Zustand state, and reconnection and error handling, so the UI kept rendering smoothly while notifications streamed in.