--- id: wiki-2026-0508-case-study-kiwi-com-frontend-mig title: Case Study — Kiwi.com Frontend Migration category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Kiwi.com Migration, Kiwi Frontend Rewrite] duplicate_of: none source_trust_level: B confidence_score: 0.85 verification_status: applied tags: [case-study, frontend, migration, react, monorepo] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: typescript framework: react/nextjs --- # Case Study — Kiwi.com Frontend Migration ## 매 한 줄 > **"매 legacy → modern stack 매 incremental migration 의 textbook"**. Kiwi.com 매 travel booking platform 매 PHP/jQuery → React/TypeScript/Next.js 매 multi-year migration 의 case study. 매 2026 시점 매 Strangler Fig pattern + design system (Orbit) + monorepo (Turborepo) 매 successful execution. 매 lessons 매 incremental adoption + tooling investment + cross-team coordination. ## 매 핵심 ### 매 starting state (pre-migration) - PHP server-rendered + jQuery sprinkles. - 매 100+ engineers, 매 single repo. - 매 inconsistent UI, 매 design 매 ad-hoc. - 매 search → booking funnel 매 monolith. ### 매 target state - React + TypeScript SPA / SSR (Next.js). - Orbit design system (open-sourced) 매 single source of truth. - Monorepo (Turborepo) 매 shared package. - Apollo / GraphQL gateway. ### 매 migration playbook 1. **Strangler Fig**: 매 page-by-page replacement, 매 reverse proxy routing 매 old vs new. 2. **Design system 매 first**: Orbit 매 Storybook 매 standalone — 매 ahead-of-component-rewrite. 3. **Type safety**: GraphQL codegen → TypeScript type 매 API contract. 4. **Feature flags**: 매 traffic gradient — 1% → 10% → 100%. 5. **Performance budget**: LCP / TTI 매 SLO, 매 regression CI gate. ### 매 응용 (lessons) 1. 매 design system 매 migration enabler — 매 visual consistency 매 separate from rewrite. 2. 매 monorepo 매 shared util / type / config 매 amortize. 3. 매 reverse proxy split 매 risk-isolation — 매 rollback 매 instant. ## 💻 패턴 ### Strangler Fig (reverse proxy routing) ```nginx # nginx.conf — split traffic by route location /search/new { proxy_pass http://nextjs-upstream; } location /search { # legacy PHP proxy_pass http://php-upstream; } ``` ### Feature flag rollout ```ts import { useFlag } from '@kiwicom/feature-flags'; export function Search() { const newSearch = useFlag('search.v2', { default: false }); return newSearch ? : ; } ``` ### GraphQL codegen pipeline ```yaml # codegen.yml schema: https://api.kiwi.com/graphql documents: 'src/**/*.graphql' generates: src/__generated__/types.ts: plugins: [typescript, typescript-operations, typescript-react-apollo] config: withHooks: true ``` ### Monorepo workspace (Turborepo) ```json // turbo.json { "tasks": { "build": { "dependsOn": ["^build"], "outputs": [".next/**", "dist/**"] }, "test": { "dependsOn": ["^build"] }, "lint": {} } } ``` ``` packages/ orbit-components/ # design system api-mappers/ # GraphQL → domain utils/ # shared apps/ search/ # Next.js booking/ # Next.js account/ # Next.js ``` ### Performance budget CI gate ```ts // lighthouse-budget.json [{ "path": "/search", "resourceSizes": [{ "resourceType": "script", "budget": 250 }], "timings": [{ "metric": "interactive", "budget": 3500 }] }] ``` ### Storybook-first component ```tsx // Button.stories.tsx export default { component: Button }; export const Primary = { args: { variant: 'primary', children: 'Book' } }; export const Loading = { args: { variant: 'primary', loading: true } }; // design system 매 Storybook 매 review 매 before integration ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Legacy app, 매 high-traffic | **Strangler Fig** — page-by-page | | Visual inconsistency 매 root issue | Design system 매 first investment | | Type drift 매 API ↔ frontend | GraphQL + codegen | | 매 monorepo coordination overhead | Turborepo / Nx 매 caching | | 매 risky launch | Feature flag + percentage rollout | **기본값**: 매 incremental, 매 design-system-first, 매 telemetry-gated rollout. ## 🔗 Graph - 응용: [[Design System]] · [[Turborepo]] · [[Feature Flags]] - Adjacent: [[Micro-frontends]] · [[Monorepo]] ## 🤖 LLM 활용 **언제**: large legacy frontend rewrite 매 planning, 매 design system priority 의 justification. **언제 X**: greenfield app — Kiwi case 매 migration constraint 매 specific. ## ❌ 안티패턴 - **Big bang rewrite**: 매 multi-year freeze, 매 product velocity zero — Kiwi 가 explicitly avoided. - **Design system 매 after**: 매 visual drift 매 unfixable late. - **No telemetry**: 매 regression 매 invisible until users complain. - **Feature flag 매 abandoned**: 매 code path 매 dead, 매 cleanup 매 backlog. ## 🧪 검증 / 중복 - Verified (Kiwi.com engineering blog, Orbit design system OSS — github.com/kiwicom/orbit). - 신뢰도 B (case study 매 specific, 매 generalizable lessons). ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — Strangler Fig + Orbit + monorepo + feature flag rollout |