[{"data":1,"prerenderedAt":2113},["ShallowReactive",2],{"navigation":3,"blog-react-til-saas-og-enterprise":35,"blog-related-react-til-saas-og-enterprise":331},[4,11,17,23,29],{"fields":5,"sys":9},{"navigationTitle":6,"slug":7,"external":8},"Om Nicky","nicky-christensen",false,{"id":10},"nav-1",{"fields":12,"sys":15},{"navigationTitle":13,"slug":14,"external":8},"Udvalgte projekter","referencer",{"id":16},"nav-2",{"fields":18,"sys":21},{"navigationTitle":19,"slug":20,"external":8},"Blog","blog",{"id":22},"nav-blog",{"fields":24,"sys":27},{"navigationTitle":25,"slug":26,"external":8},"Hvad koster det?","projekt-estimator",{"id":28},"nav-estimator",{"fields":30,"sys":33},{"navigationTitle":31,"slug":32,"external":8},"Kontakt","kontakt",{"id":34},"nav-3",{"id":36,"title":37,"body":38,"date":311,"description":312,"extension":313,"meta":314,"navigation":315,"noindex":8,"path":316,"seo":317,"seoDescription":318,"seoTitle":319,"slug":320,"stem":321,"tags":322,"thumbnail":329,"updated":311,"__hash__":330},"blog\u002Fblog\u002Freact-til-saas-og-enterprise.md","React til SaaS og enterprise — erfaringer fra Harness IDP",{"type":39,"value":40,"toc":301},"minimark",[41,46,50,53,57,60,66,87,90,100,107,112,115,118,122,125,131,138,141,145,148,153,156,161,164,169,180,184,187,213,216,220,223,226,240,244,247,261,264,275,278,287],[42,43,45],"h2",{"id":44},"det-er-ikke-det-samme-som-at-bygge-en-simpel-spa","Det er ikke det samme som at bygge en simpel SPA",[47,48,49],"p",{},"Der er React-projekter, og så er der enterprise React-projekter. Forskellen handler ikke primært om antallet af komponenter eller størrelsen af kodebasen — det handler om de krav til skalering, vedligeholdbarhed og teamkoordination som man sjældent støder på i mindre projekter.",[47,51,52],{},"Jeg arbejdede som Staff Software Engineer II hos Harness og havde det tekniske ansvar for Harness IDP (Internal Developer Portal) — en enterprise-platform bygget i React og TypeScript. Her er de vigtigste erfaringer.",[42,54,56],{"id":55},"arkitektur-bestemmer-alt","Arkitektur bestemmer alt",[47,58,59],{},"I et SaaS-produkt med mange teams og mange features er arkitekturen den vigtigste enkeltfaktor for om kodebasen skalerer eller ej. Ikke test-coverage. Ikke teknologivalg. Arkitektur.",[47,61,62],{},[63,64,65],"strong",{},"Feature-baseret mappestruktur over teknisk mappestruktur",[47,67,68,69,73,74,73,77,73,80,83,84,86],{},"Den klassiske React-struktur med ",[70,71,72],"code",{},"\u002Fcomponents",", ",[70,75,76],{},"\u002Fhooks",[70,78,79],{},"\u002Futils",[70,81,82],{},"\u002Fservices"," bryder ned så snart projektet vokser. Ender med 80 filer i ",[70,85,72],{}," og ingen konvention for hvad der hører sammen.",[47,88,89],{},"Feature-baseret struktur grupperer alt hvad der tilhører en feature:",[91,92,97],"pre",{"className":93,"code":95,"language":96},[94],"language-text","\u002Ffeatures\n  \u002Fdeveloper-portal\n    \u002Fcomponents\n    \u002Fhooks\n    \u002Fapi\n    \u002Ftypes\n    index.ts  ← public API\n","text",[70,98,95],{"__ignoreMap":99},"",[47,101,102,103,106],{},"Hvert feature eksponerer kun en public API via ",[70,104,105],{},"index.ts",". Resten er implementation details. Det gør det muligt at refaktorere en feature uden at røre resten af kodebasen.",[47,108,109],{},[63,110,111],{},"Tydelig adskillelse af server state og klient state",[47,113,114],{},"I enterprise-applikationer er størstedelen af state faktisk server state — data hentet fra en API, der caches, invalides og gensynkroniseres. React Query (TanStack Query) til server state og Zustand til lokal klient state er kombinationen der virker godt i praksis.",[47,116,117],{},"Redux er i de fleste nye projekter overkill. Det er et kraftfuldt værktøj der løser et problem de færreste moderne React-projekter har.",[42,119,121],{"id":120},"typescript-er-ikke-til-forhandling-i-enterprise","TypeScript er ikke til forhandling i enterprise",[47,123,124],{},"Det er ikke et spørgsmål om TypeScript er værd indsatsen. I enterprise-kontekst er svaret ubetinget ja.",[47,126,127,130],{},[63,128,129],{},"Grunden er ikke typesikkerhed alene"," — selvom det hjælper. Grunden er at TypeScript er den primære dokumentation i en stor kodebase med mange udviklere. Et veldefineret TypeScript-interface fortæller fremtidige udviklere præcist hvad en funktion forventer og returnerer, uden at de behøver læse implementeringen.",[47,132,133,134,137],{},"Strict mode fra dag ét. ",[70,135,136],{},"any"," er et kodelugt. Generics frem for type assertions.",[47,139,140],{},"En praktisk tommelfingerregel: hvis TypeScript-typerne er svære at skrive, er det et signal om at arkitekturen er kompleks. TypeScript afslører design-problemer tidligt.",[42,142,144],{"id":143},"performance-i-enterprise-react","Performance i enterprise React",[47,146,147],{},"Standard React performance-råd (memo, useMemo, useCallback) er nødvendige men ikke tilstrækkelige i enterprise-kontekst.",[47,149,150],{},[63,151,152],{},"Virtualisering af lange lister",[47,154,155],{},"En liste med 500 elementer i React uden virtualisering giver mærkbar forsinkelse på lavere-ende hardware. TanStack Virtual er det jeg bruger — det virtualiserer store lister uden at introducere kompleksitet i komponentstrukturen.",[47,157,158],{},[63,159,160],{},"Code splitting er ikke valgfrit",[47,162,163],{},"En enterprise React-applikation loader ikke hele bundlet fra start. Route-baseret code splitting med React.lazy og Suspense er baseline. Derefter feature-baseret splitting for tunge funktioner der ikke bruges af alle brugere.",[47,165,166],{},[63,167,168],{},"Undgå re-renders — men start med at måle",[47,170,171,172,175,176,179],{},"Mange udviklere tilføjer ",[70,173,174],{},"useMemo"," og ",[70,177,178],{},"useCallback"," overalt som en slags forsikring. Det er forkert. Memo er ikke gratis — det koster en sammenligning ved hvert render. Mål med React DevTools Profiler, find de faktiske bottlenecks, og optimer målrettet.",[42,181,183],{"id":182},"testarkitektur-der-faktisk-bruges","Testarkitektur der faktisk bruges",[47,185,186],{},"Tests der ikke kører hurtigt bliver ikke skrevet. Tests der er for tæt på implementeringen bryder ved refaktorering. Her er hvad der virker:",[188,189,190,201,207],"ul",{},[191,192,193,196,197,200],"li",{},[63,194,195],{},"Unit tests"," til ren forretningslogik (reducers, utilities, custom hooks med ",[70,198,199],{},"renderHook",")",[191,202,203,206],{},[63,204,205],{},"Integration tests"," med Testing Library til komponent-interaktion — test brugeradfærd, ikke implementering",[191,208,209,212],{},[63,210,211],{},"E2E tests"," (Playwright eller Cypress) til kritiske flows: login, checkout, core user journeys",[47,214,215],{},"At teste komponent-implementering (intern state, private metoder) er antipattern. Test hvad brugeren oplever.",[42,217,219],{"id":218},"teamkoordination-og-kodekonventioner","Teamkoordination og kodekonventioner",[47,221,222],{},"I et team med 5+ udviklere er konsistens vigtigere end elegance. Det er bedre at alle skriver kode på én bestemt måde end at alle skriver \"god kode\" på forskellige måder.",[47,224,225],{},"Praktisk:",[188,227,228,231,234,237],{},[191,229,230],{},"ESLint-regler for project-specifikke konventioner (importrækkefølge, navngivning)",[191,232,233],{},"Prettier for formatering — ingen diskussioner om tabs vs. spaces",[191,235,236],{},"Husky + lint-staged for pre-commit hooks der fanger fejl inden de lander i main",[191,238,239],{},"ADR (Architecture Decision Records) til at dokumentere vigtige beslutninger",[42,241,243],{"id":242},"hvornår-er-react-det-rigtige-valg-til-din-løsning","Hvornår er React det rigtige valg til din løsning?",[47,245,246],{},"React er det rigtige valg når:",[188,248,249,252,255,258],{},[191,250,251],{},"Du bygger en kompleks, interaktiv applikation (dashboard, editor, workflow-tool)",[191,253,254],{},"Du har behov for et stort og velkendt biblioteks-ekonomi",[191,256,257],{},"Dit team allerede kender React, eller du rekrutterer i et marked med mange React-udviklere",[191,259,260],{},"Du bygger cross-platform og overvejer React Native til mobil",[47,262,263],{},"React er sandsynligvis ikke det rigtige valg når:",[188,265,266,269,272],{},[191,267,268],{},"Du bygger et primært content-drevet site (overvej Nuxt\u002FNext.js med statisk generering)",[191,270,271],{},"Applikationen er simpel og ikke kræver avanceret state management",[191,273,274],{},"Dit team har dyb erfaring med et andet framework — skift ikke framework for sjovets skyld",[276,277],"hr",{},[47,279,280,281,286],{},"Arbejder du med et React-projekt der har skaleringsudfordringer, eller er du ved at træffe arkitekturvalgene for en ny SaaS-platform? Se mere om hvad jeg tilbyder som ",[282,283,285],"a",{"href":284},"\u002Freact-js-udvikler\u002F","freelance React udvikler"," — eller tag en uforpligtende samtale.",[47,288,289,292,293,297,298],{},[63,290,291],{},"Fra praksis:"," Hos ",[282,294,296],{"href":295},"\u002Freferencer\u002Fharness-idp","Harness"," havde jeg det fulde tekniske ejerskab over en enterprise React-platform. ",[282,299,300],{"href":295},"Se casen →",{"title":99,"searchDepth":302,"depth":302,"links":303},2,[304,305,306,307,308,309,310],{"id":44,"depth":302,"text":45},{"id":55,"depth":302,"text":56},{"id":120,"depth":302,"text":121},{"id":143,"depth":302,"text":144},{"id":182,"depth":302,"text":183},{"id":218,"depth":302,"text":219},{"id":242,"depth":302,"text":243},"2026-04-24","Hvad kræver det at bygge og vedligeholde en enterprise React-applikation? Erfaringer fra rollen som Staff Software Engineer II hos Harness.","md",{},true,"\u002Fblog\u002Freact-til-saas-og-enterprise",{"title":37,"description":312},"Hvad kræver det at bygge enterprise React-applikationer? Erfaringer fra Harness IDP som Staff Software Engineer II — arkitektur, performance og tekniske beslutninger.","React til SaaS og enterprise — Arkitektur, Performance og Skalering","react-til-saas-og-enterprise","blog\u002Freact-til-saas-og-enterprise",[323,324,325,326,327,328],"react","enterprise","saas","typescript","frontend","arkitektur","\u002Fimages\u002Fcontentful\u002Fblog-typescript.png","WSAiJMbuZASsAI1EafEMYZngVyoUzvhLaybzTNkVCUc",[332,1080,1493],{"id":333,"title":334,"body":335,"date":1068,"description":1069,"extension":313,"meta":1070,"navigation":315,"noindex":8,"path":1071,"seo":1072,"seoDescription":1073,"seoTitle":1074,"slug":1075,"stem":1076,"tags":1077,"thumbnail":329,"updated":1068,"__hash__":1079},"blog\u002Fblog\u002Ffrontend-arkitektur-for-store-projekter.md","Frontend arkitektur for store projekter — Sådan skalerer du din kodebase",{"type":39,"value":336,"toc":1057},[337,340,343,346,350,353,359,365,368,378,381,385,388,394,400,576,582,585,589,592,697,700,720,723,727,730,733,771,774,778,781,787,798,804,815,818,821,825,828,834,840,930,949,955,959,962,968,974,980,983,987,990,996,1002,1017,1023,1027,1030,1033,1035,1043,1045,1053],[47,338,339],{},"Når du arbejder på et frontend-projekt med 2-3 udviklere, kan du slippe afsted med mange ting. Mappestruktur? Det løser sig selv. State management? Props er fint. Kodekonventioner? Vi snakker bare sammen.",[47,341,342],{},"Men når teamet vokser til 10, 20 eller 50 udviklere, og kodebasen rammer hundredtusinder af linjer kode, så falder den tilgang fra hinanden. Pludselig er der konflikter i hver merge request, ingen kan finde noget, og performance er gået i stændig tilbagegang.",[47,344,345],{},"Jeg har arbejdet med frontend i enterprise-skala hos Grundfos, Vestas, Playable og Harness — og nu som Technical Director hos Checkmate.dk. Her er de vigtigste lærdomme om hvordan du arkitekterer frontend-applikationer der faktisk skalerer.",[42,347,349],{"id":348},"komponentarkitektur-og-mappestruktur","Komponentarkitektur og mappestruktur",[47,351,352],{},"Den første og mest grundlæggende beslutning er hvordan du organiserer dine komponenter. Jeg har set to primære tilgange:",[47,354,355,358],{},[63,356,357],{},"Feature-baseret struktur"," er næsten altid det rigtige valg for store projekter. I stedet for at gruppere efter type (alle buttons i en mappe, alle modals i en anden), grupperer du efter feature:",[91,360,363],{"className":361,"code":362,"language":96},[94],"components\u002F\n  Dashboard\u002F\n    DashboardView.vue\n    DashboardStats.vue\n    DashboardChart.vue\n    useDashboardData.ts\n  UserProfile\u002F\n    UserProfileView.vue\n    UserProfileForm.vue\n    useUserProfile.ts\n  UI\u002F\n    BaseButton.vue\n    BaseModal.vue\n    BaseInput.vue\n",[70,364,362],{"__ignoreMap":99},[47,366,367],{},"Grunden er simpel: når en udvikler arbejder på en feature, skal de kun røre filer i en mappe. Det reducerer merge-konflikter drastisk og gør det nemmere at forstå konteksten.",[47,369,370,373,374,377],{},[63,371,372],{},"UI-komponenter"," (buttons, inputs, modals) lever for sig selv i en delt mappe, fordi de bruges på tværs af features. Men feature-specifikke komponenter hører til i feature-mappen — ikke i en generisk ",[70,375,376],{},"components\u002F"," rod.",[47,379,380],{},"En tommelfingerregel jeg bruger: Hvis en komponent kun bruges et sted, hører den til i den features mappe. Først når den bruges to eller flere steder, flyttes den til en delt mappe.",[42,382,384],{"id":383},"state-management-pinia-vs-composables-vs-props","State management — Pinia vs composables vs props",[47,386,387],{},"Et af de mest debatterede emner i frontend-verdenen. I Vue-økosystemet har vi Pinia, composables og props. I React er det Redux\u002FZustand, hooks og props. Men principperne er de samme.",[47,389,390,393],{},[63,391,392],{},"Props"," er førstevalget. Altid. Data der flyder fra forælder til barn er det simpleste og mest forudsigelige mønster. Når folk klager over \"prop drilling\", er det ofte et tegn på at komponenthierarkiet er forkert — ikke at du mangler global state.",[47,395,396,399],{},[63,397,398],{},"Composables (eller custom hooks)"," er næste trin. Når logik skal deles mellem komponenter der ikke har et direkte forælder-barn-forhold, er en composable perfekt. Den indkapsler logik og state uden at gøre det globalt.",[91,401,404],{"className":402,"code":403,"language":326,"meta":99,"style":99},"language-typescript shiki shiki-themes github-dark","\u002F\u002F useCurrentUser.ts\nexport function useCurrentUser() {\n  const user = ref\u003CUser | null>(null)\n  const isLoading = ref(false)\n\n  async function fetchUser() {\n    isLoading.value = true\n    user.value = await api.getCurrentUser()\n    isLoading.value = false\n  }\n\n  return { user, isLoading, fetchUser }\n}\n",[70,405,406,415,432,469,489,495,508,520,540,550,556,561,570],{"__ignoreMap":99},[407,408,411],"span",{"class":409,"line":410},"line",1,[407,412,414],{"class":413},"sAwPA","\u002F\u002F useCurrentUser.ts\n",[407,416,417,421,424,428],{"class":409,"line":302},[407,418,420],{"class":419},"snl16","export",[407,422,423],{"class":419}," function",[407,425,427],{"class":426},"svObZ"," useCurrentUser",[407,429,431],{"class":430},"s95oV","() {\n",[407,433,435,438,442,445,448,451,454,457,460,463,466],{"class":409,"line":434},3,[407,436,437],{"class":419},"  const",[407,439,441],{"class":440},"sDLfK"," user",[407,443,444],{"class":419}," =",[407,446,447],{"class":426}," ref",[407,449,450],{"class":430},"\u003C",[407,452,453],{"class":426},"User",[407,455,456],{"class":419}," |",[407,458,459],{"class":440}," null",[407,461,462],{"class":430},">(",[407,464,465],{"class":440},"null",[407,467,468],{"class":430},")\n",[407,470,472,474,477,479,481,484,487],{"class":409,"line":471},4,[407,473,437],{"class":419},[407,475,476],{"class":440}," isLoading",[407,478,444],{"class":419},[407,480,447],{"class":426},[407,482,483],{"class":430},"(",[407,485,486],{"class":440},"false",[407,488,468],{"class":430},[407,490,492],{"class":409,"line":491},5,[407,493,494],{"emptyLinePlaceholder":315},"\n",[407,496,498,501,503,506],{"class":409,"line":497},6,[407,499,500],{"class":419},"  async",[407,502,423],{"class":419},[407,504,505],{"class":426}," fetchUser",[407,507,431],{"class":430},[407,509,511,514,517],{"class":409,"line":510},7,[407,512,513],{"class":430},"    isLoading.value ",[407,515,516],{"class":419},"=",[407,518,519],{"class":440}," true\n",[407,521,523,526,528,531,534,537],{"class":409,"line":522},8,[407,524,525],{"class":430},"    user.value ",[407,527,516],{"class":419},[407,529,530],{"class":419}," await",[407,532,533],{"class":430}," api.",[407,535,536],{"class":426},"getCurrentUser",[407,538,539],{"class":430},"()\n",[407,541,543,545,547],{"class":409,"line":542},9,[407,544,513],{"class":430},[407,546,516],{"class":419},[407,548,549],{"class":440}," false\n",[407,551,553],{"class":409,"line":552},10,[407,554,555],{"class":430},"  }\n",[407,557,559],{"class":409,"line":558},11,[407,560,494],{"emptyLinePlaceholder":315},[407,562,564,567],{"class":409,"line":563},12,[407,565,566],{"class":419},"  return",[407,568,569],{"class":430}," { user, isLoading, fetchUser }\n",[407,571,573],{"class":409,"line":572},13,[407,574,575],{"class":430},"}\n",[47,577,578,581],{},[63,579,580],{},"Pinia\u002FRedux"," er kun til ægte global state — ting som den aktuelle bruger, tema-indstillinger, notifikationer. Hvis du har mere end 10-15 stores, har du sandsynligvis lagt for meget i global state.",[47,583,584],{},"Min erfaring fra Harness, hvor vi havde en stor Vue-applikation: Teamet startede med at lægge alt i Vuex (forgængeren til Pinia). Resultatet var en massiv, uforudsigelig state-graf hvor ingen vidste hvad der påvirkede hvad. Da vi refaktorerede til composables for feature-specifik state og kun beholdt ægte global state i stores, blev kodebasen markant nemmere at arbejde med.",[42,586,588],{"id":587},"code-splitting-og-lazy-loading","Code splitting og lazy loading",[47,590,591],{},"I en stor applikation er det afgørende at brugeren ikke skal downloade hele din kodebase for at se første side. Både Vue Router og React Router understøtter lazy loading af routes ud af boksen:",[91,593,595],{"className":402,"code":594,"language":326,"meta":99,"style":99},"\u002F\u002F Vue Router\nconst routes = [\n  {\n    path: '\u002Fdashboard',\n    component: () => import('.\u002Fpages\u002FDashboard.vue')\n  },\n  {\n    path: '\u002Fsettings',\n    component: () => import('.\u002Fpages\u002FSettings.vue')\n  }\n]\n",[70,596,597,602,615,620,632,653,658,662,671,688,692],{"__ignoreMap":99},[407,598,599],{"class":409,"line":410},[407,600,601],{"class":413},"\u002F\u002F Vue Router\n",[407,603,604,607,610,612],{"class":409,"line":302},[407,605,606],{"class":419},"const",[407,608,609],{"class":440}," routes",[407,611,444],{"class":419},[407,613,614],{"class":430}," [\n",[407,616,617],{"class":409,"line":434},[407,618,619],{"class":430},"  {\n",[407,621,622,625,629],{"class":409,"line":471},[407,623,624],{"class":430},"    path: ",[407,626,628],{"class":627},"sU2Wk","'\u002Fdashboard'",[407,630,631],{"class":430},",\n",[407,633,634,637,640,643,646,648,651],{"class":409,"line":491},[407,635,636],{"class":426},"    component",[407,638,639],{"class":430},": () ",[407,641,642],{"class":419},"=>",[407,644,645],{"class":419}," import",[407,647,483],{"class":430},[407,649,650],{"class":627},"'.\u002Fpages\u002FDashboard.vue'",[407,652,468],{"class":430},[407,654,655],{"class":409,"line":497},[407,656,657],{"class":430},"  },\n",[407,659,660],{"class":409,"line":510},[407,661,619],{"class":430},[407,663,664,666,669],{"class":409,"line":522},[407,665,624],{"class":430},[407,667,668],{"class":627},"'\u002Fsettings'",[407,670,631],{"class":430},[407,672,673,675,677,679,681,683,686],{"class":409,"line":542},[407,674,636],{"class":426},[407,676,639],{"class":430},[407,678,642],{"class":419},[407,680,645],{"class":419},[407,682,483],{"class":430},[407,684,685],{"class":627},"'.\u002Fpages\u002FSettings.vue'",[407,687,468],{"class":430},[407,689,690],{"class":409,"line":552},[407,691,555],{"class":430},[407,693,694],{"class":409,"line":558},[407,695,696],{"class":430},"]\n",[47,698,699],{},"Men routes er bare begyndelsen. I store projekter bør du også overveje:",[188,701,702,708,714],{},[191,703,704,707],{},[63,705,706],{},"Lazy loading af tunge komponenter"," — Diagrammer, editorer, og lignende bør loades on-demand",[191,709,710,713],{},[63,711,712],{},"Prefetching af sandsynlige næste sider"," — Hvis 80% af brugerne går fra dashboard til rapporter, så prefetch rapporter-chunken",[191,715,716,719],{},[63,717,718],{},"Dynamiske imports for tredjepartsbiblioteker"," — Lad være med at bundle moment.js eller lodash ind i din hovedbundle hvis det kun bruges et sted",[47,721,722],{},"Den største fejl jeg ser er at teams optimerer for tidligt. Start med route-baseret code splitting. Mål din bundle-størrelse. Optimer derefter de største chunks først.",[42,724,726],{"id":725},"design-system-integration","Design system integration",[47,728,729],{},"Når du har mere end 3-4 frontend-udviklere, har du brug for et design system. Ikke et fancy Storybook-setup med 200 komponenter — men en fælles forståelse af de basale byggeklodser.",[47,731,732],{},"Et effektivt design system i praksis:",[734,735,736,742,748],"ol",{},[191,737,738,741],{},[63,739,740],{},"Tokens først"," — Definer farver, spacing, typografi og breakpoints som design tokens (CSS custom properties eller en theme-fil). Alt andet bygger på disse.",[191,743,744,747],{},[63,745,746],{},"Primitive komponenter"," — Button, Input, Select, Modal, Card. Maks 15-20 komponenter. De skal være veltestede og veldokumenterede.",[191,749,750,753,754,757,758,73,761,73,764,73,767,770],{},[63,751,752],{},"Kompositionsmønstret"," — Byg komplekse komponenter ved at kombinere primitive. Lad være med at lave en ",[70,755,756],{},"SuperTable"," der kan alt — lav i stedet ",[70,759,760],{},"Table",[70,762,763],{},"TableHeader",[70,765,766],{},"TableRow",[70,768,769],{},"TableCell"," der kan sammensættes.",[47,772,773],{},"Det vigtigste er at design systemet lever tæt på koden. Jeg har set for mange teams hvor design systemet er et separat projekt der altid er bagud. Når det lever i en delt pakke i din monorepo (eller som en npm-pakke med hurtig release-cyklus), bliver det faktisk brugt.",[42,775,777],{"id":776},"monorepo-vs-polyrepo","Monorepo vs polyrepo",[47,779,780],{},"Det her er en beslutning der har store konsekvenser, og der er ikke et universelt svar.",[47,782,783,786],{},[63,784,785],{},"Monorepo"," (alle pakker i et repository) er bedst når:",[188,788,789,792,795],{},[191,790,791],{},"Teams deler meget kode (design system, utilities, typer)",[191,793,794],{},"Du vil have atomare ændringer på tværs af pakker",[191,796,797],{},"Du har værktøj til det (Nx, Turborepo, eller Lerna)",[47,799,800,803],{},[63,801,802],{},"Polyrepo"," (separate repositories) er bedst når:",[188,805,806,809,812],{},[191,807,808],{},"Teams er meget autonome og sjældent deler kode",[191,810,811],{},"Du har strikse deployment-boundaries",[191,813,814],{},"Teams bruger forskellige tech stacks",[47,816,817],{},"Min erfaring: For de fleste frontend-teams er en monorepo det rigtige valg. Værktøjerne (særligt Nx og Turborepo) er blevet så modne at overhead er minimal, og fordelen ved at kunne dele typer, konfiguration og design system-komponenter er enorm.",[47,819,820],{},"Hos Vestas arbejdede vi med en polyrepo-tilgang der betød at vi konstant kæmpede med at holde delte biblioteker i sync. Hos Playable skiftede vi til monorepo, og det var en game-changer for developer experience.",[42,822,824],{"id":823},"typescript-som-skaleringsværktøj","TypeScript som skaleringsværktøj",[47,826,827],{},"TypeScript er ikke bare \"JavaScript med typer.\" I store projekter er det et arkitekturværktøj.",[47,829,830,833],{},[63,831,832],{},"Interfaces som kontrakter."," Når team A bygger en API og team B bruger den, fungerer TypeScript-interfaces som en levende kontrakt. Hvis API'en ændrer sig, får team B en kompileringsfejl — ikke en runtime-fejl i produktion kl. 3 om natten.",[47,835,836,839],{},[63,837,838],{},"Strenge typer for domæneobjekter."," Definer dine domæneobjekter som TypeScript-typer og brug dem konsekvent:",[91,841,843],{"className":402,"code":842,"language":326,"meta":99,"style":99},"interface Order {\n  id: string\n  status: 'pending' | 'confirmed' | 'shipped' | 'delivered'\n  items: OrderItem[]\n  customer: Customer\n  createdAt: Date\n}\n",[70,844,845,856,868,893,906,916,926],{"__ignoreMap":99},[407,846,847,850,853],{"class":409,"line":410},[407,848,849],{"class":419},"interface",[407,851,852],{"class":426}," Order",[407,854,855],{"class":430}," {\n",[407,857,858,862,865],{"class":409,"line":302},[407,859,861],{"class":860},"s9osk","  id",[407,863,864],{"class":419},":",[407,866,867],{"class":440}," string\n",[407,869,870,873,875,878,880,883,885,888,890],{"class":409,"line":434},[407,871,872],{"class":860},"  status",[407,874,864],{"class":419},[407,876,877],{"class":627}," 'pending'",[407,879,456],{"class":419},[407,881,882],{"class":627}," 'confirmed'",[407,884,456],{"class":419},[407,886,887],{"class":627}," 'shipped'",[407,889,456],{"class":419},[407,891,892],{"class":627}," 'delivered'\n",[407,894,895,898,900,903],{"class":409,"line":471},[407,896,897],{"class":860},"  items",[407,899,864],{"class":419},[407,901,902],{"class":426}," OrderItem",[407,904,905],{"class":430},"[]\n",[407,907,908,911,913],{"class":409,"line":491},[407,909,910],{"class":860},"  customer",[407,912,864],{"class":419},[407,914,915],{"class":426}," Customer\n",[407,917,918,921,923],{"class":409,"line":497},[407,919,920],{"class":860},"  createdAt",[407,922,864],{"class":419},[407,924,925],{"class":426}," Date\n",[407,927,928],{"class":409,"line":510},[407,929,575],{"class":430},[47,931,932,933,936,937,940,941,944,945,948],{},"Når ",[70,934,935],{},"status"," er en union type i stedet for en ",[70,938,939],{},"string",", kan du ikke ved et uheld sætte den til ",[70,942,943],{},"\"PENDING\""," eller ",[70,946,947],{},"\"Shipped\"",". Det lyder som en lille ting, men i en kodebase med 50 udviklere forhindrer det hundredevis af bugs.",[47,950,951,954],{},[63,952,953],{},"Generics for genbrugelig kode."," Composables og utility-funktioner der bruger generics er mærkbart nemmere at genbruge korrekt i store teams.",[42,956,958],{"id":957},"teststrategi-i-skala","Teststrategi i skala",[47,960,961],{},"Store projekter har brug for en strategi — ikke bare \"vi skriver tests.\" Her er den pyramide jeg anbefaler:",[47,963,964,967],{},[63,965,966],{},"Unit tests (70%)"," — Test composables, utility-funktioner og forretningslogik. De er hurtige, stabile og giver mest værdi per tidsenhed.",[47,969,970,973],{},[63,971,972],{},"Komponent-tests (20%)"," — Test at komponenter renderer korrekt med forskellige props og håndterer brugerinteraktion. Brug Vue Test Utils eller React Testing Library.",[47,975,976,979],{},[63,977,978],{},"End-to-end tests (10%)"," — Test kritiske brugerflows (login, checkout, osv.) med Playwright eller Cypress. Hold antallet lavt — de er langsomme og skrøbelige.",[47,981,982],{},"Den største fejl er at starte med E2E-tests. De er dyre at vedligeholde og giver falsk tryghed. Start med unit tests af din forretningslogik, og tilføj E2E-tests for de mest kritiske flows.",[42,984,986],{"id":985},"teamkonventioner-og-code-review","Teamkonventioner og code review",[47,988,989],{},"Værktøj og arkitektur er kun halvdelen. Den anden halvdel er mennesker og processer.",[47,991,992,995],{},[63,993,994],{},"Automatiser hvad der kan automatiseres."," ESLint, Prettier, husky pre-commit hooks. Diskuter ikke formatering i code reviews — lad værktøjerne håndtere det.",[47,997,998,1001],{},[63,999,1000],{},"Brug ADR'er (Architecture Decision Records)."," Når teamet træffer en større beslutning (f.eks. \"vi bruger Pinia i stedet for composables til global state\"), skriv det ned med kontekst og begrundelse. Nye teammedlemmer vil takke dig.",[47,1003,1004,1007,1008,1012,1013,1016],{},[63,1005,1006],{},"Code reviews er læring, ikke gatekeeping."," De bedste teams jeg har arbejdet med bruger code reviews som en mulighed for videndeling. Forklar ",[1009,1010,1011],"em",{},"hvorfor"," du foreslår en ændring, ikke bare ",[1009,1014,1015],{},"hvad",". Og vær åben for at lære noget nyt fra den der har skrevet koden.",[47,1018,1019,1022],{},[63,1020,1021],{},"Definer \"done\" for komponenter."," En komponent er ikke færdig når den virker. Den er færdig når den har typer, er testet, er dokumenteret (mindst en kommentar med et eksempel), og er reviewet.",[42,1024,1026],{"id":1025},"afslutningstanker","Afslutningstanker",[47,1028,1029],{},"God frontend-arkitektur handler ikke om at vælge det rigtige framework eller det nyeste værktøj. Det handler om at skabe struktur der gør det muligt for mange mennesker at arbejde effektivt på den samme kodebase over lang tid.",[47,1031,1032],{},"Start simpelt. Tilføj kompleksitet når du har bevist at du har brug for det. Og husk: den bedste arkitektur er den dit team faktisk forstår og følger.",[276,1034],{},[47,1036,1037,1038,1042],{},"Har du brug for hjælp med at skalere din frontend-arkitektur? Jeg arbejder til dagligt med disse udfordringer som Technical Director hos Checkmate.dk, og jeg deler regelmæssigt mine erfaringer her på bloggen. ",[282,1039,1041],{"href":1040},"\u002Fkontakt","Kontakt mig"," hvis du vil diskutere dit projekt, eller følg med her for flere artikler om frontend i enterprise-skala.",[276,1044],{},[47,1046,1047,1049,1050],{},[63,1048,291],{}," Disse principper er ikke teoretiske — jeg anvendte dem som Staff Software Engineer II med fuldt teknisk ejerskab over frontenden på Harness' enterprise DevOps-platform. ",[282,1051,1052],{"href":295},"Se case →",[1054,1055,1056],"style",{},"html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}",{"title":99,"searchDepth":302,"depth":302,"links":1058},[1059,1060,1061,1062,1063,1064,1065,1066,1067],{"id":348,"depth":302,"text":349},{"id":383,"depth":302,"text":384},{"id":587,"depth":302,"text":588},{"id":725,"depth":302,"text":726},{"id":776,"depth":302,"text":777},{"id":823,"depth":302,"text":824},{"id":957,"depth":302,"text":958},{"id":985,"depth":302,"text":986},{"id":1025,"depth":302,"text":1026},"2026-04-03","Hvordan arkitekterer du frontend-applikationer der skalerer? Her er mine erfaringer fra 19+ år med enterprise-projekter hos Grundfos, Vestas, Playable og Harness.",{},"\u002Fblog\u002Ffrontend-arkitektur-for-store-projekter",{"title":334,"description":1069},"Lær at arkitektere frontend-applikationer der skalerer. Praktiske tips om komponentarkitektur, state management, TypeScript og teamkonventioner.","Frontend Arkitektur for Store Projekter — Skalering, Patterns og Best Practices","frontend-arkitektur-for-store-projekter","blog\u002Ffrontend-arkitektur-for-store-projekter",[327,328,326,1078,323,324],"vue","KjFCz6_E1qlbrHGPfA2xQKYRi2zz1r-tE8siWo6LGcw",{"id":1081,"title":1082,"body":1083,"date":1068,"description":1481,"extension":313,"meta":1482,"navigation":315,"noindex":8,"path":1483,"seo":1484,"seoDescription":1485,"seoTitle":1486,"slug":1487,"stem":1488,"tags":1489,"thumbnail":329,"updated":1068,"__hash__":1492},"blog\u002Fblog\u002Freact-vs-vue-i-2026.md","React vs Vue i 2026 — En erfaren udviklers perspektiv",{"type":39,"value":1084,"toc":1456},[1085,1089,1092,1095,1098,1102,1228,1232,1237,1240,1243,1247,1250,1254,1257,1261,1264,1268,1272,1275,1278,1282,1285,1289,1292,1296,1310,1314,1346,1350,1382,1386,1390,1393,1397,1400,1404,1407,1411,1418,1421,1425,1428,1431,1441,1443],[42,1086,1088],{"id":1087},"jeg-har-brugt-begge-i-mange-år","Jeg har brugt begge — i mange år",[47,1090,1091],{},"Dette er ikke en af de artikler der er skrevet af nogen der har læst dokumentationen og sammenlignet bullet points. Jeg har brugt både React og Vue professionelt i adskillige år — Vue hos Playable og i mine egne projekter, React hos Grundfos, Vestas og Harness.",[47,1093,1094],{},"Jeg har bygget SaaS-platforme, enterprise-løsninger og websites med begge frameworks. Og mit svar på \"hvad er bedst?\" er det samme som altid: det kommer an på.",[47,1096,1097],{},"Men lad mig være mere specifik end det.",[42,1099,1101],{"id":1100},"hurtigt-overblik","Hurtigt overblik",[1103,1104,1105,1120],"table",{},[1106,1107,1108],"thead",{},[1109,1110,1111,1114,1117],"tr",{},[1112,1113],"th",{},[1112,1115,1116],{},"React",[1112,1118,1119],{},"Vue",[1121,1122,1123,1137,1150,1163,1176,1189,1202,1215],"tbody",{},[1109,1124,1125,1131,1134],{},[1126,1127,1128],"td",{},[63,1129,1130],{},"Skabt af",[1126,1132,1133],{},"Meta (Facebook)",[1126,1135,1136],{},"Evan You \u002F community",[1109,1138,1139,1144,1147],{},[1126,1140,1141],{},[63,1142,1143],{},"Første release",[1126,1145,1146],{},"2013",[1126,1148,1149],{},"2014",[1109,1151,1152,1157,1160],{},[1126,1153,1154],{},[63,1155,1156],{},"Popularitet",[1126,1158,1159],{},"Størst community og jobmarked",[1126,1161,1162],{},"Større i Asien, voksende i Europa",[1109,1164,1165,1170,1173],{},[1126,1166,1167],{},[63,1168,1169],{},"Læringskurve",[1126,1171,1172],{},"Stejlere",[1126,1174,1175],{},"Blødere",[1109,1177,1178,1183,1186],{},[1126,1179,1180],{},[63,1181,1182],{},"Rendering",[1126,1184,1185],{},"JSX (JavaScript + HTML)",[1126,1187,1188],{},"Templates (HTML + directives)",[1109,1190,1191,1196,1199],{},[1126,1192,1193],{},[63,1194,1195],{},"State management",[1126,1197,1198],{},"Mange valg (Redux, Zustand, Jotai)",[1126,1200,1201],{},"Pinia (officiel)",[1109,1203,1204,1209,1212],{},[1126,1205,1206],{},[63,1207,1208],{},"Meta-framework",[1126,1210,1211],{},"Next.js",[1126,1213,1214],{},"Nuxt",[1109,1216,1217,1222,1225],{},[1126,1218,1219],{},[63,1220,1221],{},"TypeScript",[1126,1223,1224],{},"Førsteklasses support",[1126,1226,1227],{},"Førsteklasses support (fra Vue 3)",[42,1229,1231],{"id":1230},"hvor-react-udmærker-sig","Hvor React udmærker sig",[1233,1234,1236],"h3",{"id":1235},"større-økosystem-og-jobmarked","Større økosystem og jobmarked",[47,1238,1239],{},"React har det største økosystem i frontend-verdenen. Der er flere biblioteker, flere tutorials, flere svar på Stack Overflow, og langt flere jobopslag. Hvis du optimerer for karrieremuligheder, er React det sikre valg.",[47,1241,1242],{},"I Danmark er React stadig det mest efterspurgte frontend-framework på jobmarkedet — særligt i enterprise-segmentet.",[1233,1244,1246],{"id":1245},"fleksibilitet","Fleksibilitet",[47,1248,1249],{},"React er et bibliotek, ikke et framework. Det giver dig frihed til at vælge din egen state management, routing, og arkitektur. For erfarne teams der ved hvad de vil, er den fleksibilitet en styrke.",[1233,1251,1253],{"id":1252},"react-server-components-og-server-actions","React Server Components og Server Actions",[47,1255,1256],{},"React har med Server Components taget et stort skridt mod server-side rendering der føles naturligt. Det er en arkitektonisk innovation der giver mulighed for at blande server- og klient-kode på en måde der er unik for React.",[1233,1258,1260],{"id":1259},"react-native","React Native",[47,1262,1263],{},"Hvis du har brug for at bygge mobile apps, er React Native det største cross-platform framework. At dele kode mellem web og mobil med samme team er en reel fordel.",[42,1265,1267],{"id":1266},"hvor-vue-udmærker-sig","Hvor Vue udmærker sig",[1233,1269,1271],{"id":1270},"læringskurven-er-kortere","Læringskurven er kortere",[47,1273,1274],{},"Vue er lettere at lære for både nye og erfarne udviklere. Template-syntaksen er mere intuitiv end JSX, og Vue's Composition API giver den samme kraft som React Hooks, men med en blødere læringskurve.",[47,1276,1277],{},"Jeg har onboardet mange udviklere til begge frameworks, og Vue-teams er konsekvent produktive hurtigere.",[1233,1279,1281],{"id":1280},"bedre-batteries-included","Bedre \"batteries included\"",[47,1283,1284],{},"Vue har officielle løsninger for de fleste behov: Pinia til state management, Vue Router til routing, og Nuxt som meta-framework. Du slipper for at evaluere og vælge mellem 10 forskellige state management-biblioteker.",[1233,1286,1288],{"id":1287},"composition-api-er-elegant","Composition API er elegant",[47,1290,1291],{},"Vue 3's Composition API er efter min mening den reneste måde at skrive reaktiv logik på. Composables (Vue's svar på custom hooks) er nemmere at læse, teste og genbruge end React hooks, primært fordi du slipper for at tænke på dependency arrays og re-renders.",[1233,1293,1295],{"id":1294},"reaktivitetssystem","Reaktivitetssystem",[47,1297,1298,1299,1301,1302,73,1304,175,1306,1309],{},"Vue's fine-grained reaktivitet er smartere end React's re-rendering model. Vue ved præcis ",[1009,1300,1015],{}," der har ændret sig og opdaterer kun det nødvendige. React re-renderer hele komponenten og dens børn, hvilket kræver at du tænker over ",[70,1303,174],{},[70,1305,178],{},[70,1307,1308],{},"React.memo"," for at undgå performance-problemer.",[42,1311,1313],{"id":1312},"hvornår-skal-du-vælge-react","Hvornår skal du vælge React?",[188,1315,1316,1322,1328,1334,1340],{},[191,1317,1318,1321],{},[63,1319,1320],{},"Dit team kender allerede React"," — Det vigtigste argument. Skift ikke framework for sjov",[191,1323,1324,1327],{},[63,1325,1326],{},"Du har brug for React Native"," — Hvis mobil er en del af planen",[191,1329,1330,1333],{},[63,1331,1332],{},"Du ansætter i et stort marked"," — Der er flere React-udviklere at vælge imellem",[191,1335,1336,1339],{},[63,1337,1338],{},"Du bygger på et eksisterende React-økosystem"," — Mange virksomheder har interne React-biblioteker og tooling",[191,1341,1342,1345],{},[63,1343,1344],{},"Enterprise med mange teams"," — React's fleksibilitet giver teams mulighed for at vælge deres egne patterns",[42,1347,1349],{"id":1348},"hvornår-skal-du-vælge-vue","Hvornår skal du vælge Vue?",[188,1351,1352,1358,1364,1370,1376],{},[191,1353,1354,1357],{},[63,1355,1356],{},"Du starter et nyt projekt"," — Vue's opinionated tilgang giver hurtigere time-to-market",[191,1359,1360,1363],{},[63,1361,1362],{},"Dit team har blandet erfaring"," — Vue er lettere at lære for juniors og backendudviklere",[191,1365,1366,1369],{},[63,1367,1368],{},"Du bygger et content-site eller marketing-site"," — Nuxt's statiske generering og SEO-support er fremragende",[191,1371,1372,1375],{},[63,1373,1374],{},"Performance er kritisk"," — Vue's reaktivitetssystem giver bedre out-of-the-box performance",[191,1377,1378,1381],{},[63,1379,1380],{},"Du vil have en sammenhængende stack"," — Vue + Pinia + Nuxt er en tight integration uden compatibility-sorger",[42,1383,1385],{"id":1384},"hvad-med-andre-frameworks","Hvad med andre frameworks?",[1233,1387,1389],{"id":1388},"sveltesveltekit","Svelte\u002FSvelteKit",[47,1391,1392],{},"Svelte er et fantastisk framework der kompilerer væk sit eget runtime. Det giver ekstremt let output og en behagelig udvikleroplevelse. Men økosystemet er stadig lille sammenlignet med React og Vue, og jobmarkedet er begrænset.",[1233,1394,1396],{"id":1395},"angular","Angular",[47,1398,1399],{},"Angular er stadig stort i enterprise-verdenen, særligt i backend-tunge organisationer. Men i den bredere frontend-verden er det blevet mindre relevant.",[1233,1401,1403],{"id":1402},"solid-qwik-og-andre","Solid, Qwik og andre",[47,1405,1406],{},"Spændende teknologier der løser reelle problemer, men for de fleste projekter i 2026 er React eller Vue stadig det pragmatiske valg.",[42,1408,1410],{"id":1409},"min-personlige-præference","Min personlige præference",[47,1412,1413,1414,1417],{},"Hvis jeg starter et nyt projekt i dag og har frit valg, vælger jeg ",[63,1415,1416],{},"Vue 3 med Nuxt",". Det er det jeg kender bedst, og Composition API + Nuxt's DX er efter min mening den bedste udvikleroplevelse i frontend-verdenen.",[47,1419,1420],{},"Men hvis et team allerede bruger React, eller hvis projektet kræver React Native, ville jeg aldrig foreslå at skifte til Vue. Det vigtigste er ikke hvilket framework du vælger — det er at du bruger det godt.",[42,1422,1424],{"id":1423},"konklusion","Konklusion",[47,1426,1427],{},"Både React og Vue er modne, velunderstøttede frameworks der kan bygge hvad som helst. I 2026 er forskellen mellem dem mindre end nogensinde — begge har TypeScript-support, server-side rendering, og store økosystemer.",[47,1429,1430],{},"Vælg det der passer til dit team, dit projekt og dine krav. Ikke det der er mest hypet på Twitter.",[47,1432,1433,1434,944,1438,1440],{},"Har du spørgsmål om valg af framework til dit næste projekt? Jeg rådgiver gerne baseret på dine specifikke behov — uanset om du overvejer ",[282,1435,1437],{"href":1436},"\u002Fvue-js-udvikler\u002F","Vue.js",[282,1439,1116],{"href":284},".",[276,1442],{},[47,1444,1445,1447,1448,1452,1453,1455],{},[63,1446,291],{}," Jeg har brugt begge frameworks professionelt. Hos ",[282,1449,1451],{"href":1450},"\u002Freferencer\u002Fplayable-platform","Playable"," drev jeg som Frontend Tech Lead den komplette omskrivning til Vue 3 + TypeScript. Hos ",[282,1454,296],{"href":295}," havde jeg som Staff Software Engineer II det fulde tekniske ejerskab over en enterprise React-platform.",{"title":99,"searchDepth":302,"depth":302,"links":1457},[1458,1459,1460,1466,1472,1473,1474,1479,1480],{"id":1087,"depth":302,"text":1088},{"id":1100,"depth":302,"text":1101},{"id":1230,"depth":302,"text":1231,"children":1461},[1462,1463,1464,1465],{"id":1235,"depth":434,"text":1236},{"id":1245,"depth":434,"text":1246},{"id":1252,"depth":434,"text":1253},{"id":1259,"depth":434,"text":1260},{"id":1266,"depth":302,"text":1267,"children":1467},[1468,1469,1470,1471],{"id":1270,"depth":434,"text":1271},{"id":1280,"depth":434,"text":1281},{"id":1287,"depth":434,"text":1288},{"id":1294,"depth":434,"text":1295},{"id":1312,"depth":302,"text":1313},{"id":1348,"depth":302,"text":1349},{"id":1384,"depth":302,"text":1385,"children":1475},[1476,1477,1478],{"id":1388,"depth":434,"text":1389},{"id":1395,"depth":434,"text":1396},{"id":1402,"depth":434,"text":1403},{"id":1409,"depth":302,"text":1410},{"id":1423,"depth":302,"text":1424},"Jeg har brugt både React og Vue professionelt i mange år. Her er min ærlige sammenligning i 2026 — uden fanboy-bias.",{},"\u002Fblog\u002Freact-vs-vue-i-2026",{"title":1082,"description":1481},"React vs Vue sammenligning fra en udvikler med 19+ års erfaring i begge. Lær forskelle, fordele og ulemper, og hvornår du skal vælge hvad i 2026.","React vs Vue i 2026 — Hvilket framework skal du vælge?","react-vs-vue-i-2026","blog\u002Freact-vs-vue-i-2026",[323,1078,1490,327,1491],"javascript","framework","CVnqUm4L6U9AiyT80LfEjTWoUlL24roEtjJbv2CgCzY",{"id":1494,"title":1495,"body":1496,"date":1068,"description":2100,"extension":313,"meta":2101,"navigation":315,"noindex":8,"path":2102,"seo":2103,"seoDescription":2104,"seoTitle":2105,"slug":2106,"stem":2107,"tags":2108,"thumbnail":329,"updated":1068,"__hash__":2112},"blog\u002Fblog\u002Fsaadan-vaelger-du-den-rigtige-tech-stack.md","Sådan vælger du den rigtige tech stack i 2026",{"type":39,"value":1497,"toc":2073},[1498,1502,1505,1508,1540,1543,1547,1550,1554,1557,1560,1565,1576,1580,1587,1590,1594,1611,1615,1618,1622,1636,1640,1643,1647,1658,1662,1666,1673,1677,1680,1684,1687,1691,1694,1698,1701,1705,1708,1712,1738,1741,1745,1769,1773,1803,1806,1810,1833,1836,1840,1847,1852,1866,1871,1885,1890,1901,1906,1917,1921,1924,1930,1936,1942,1948,1952,1955,1961,1967,1973,1976,1980,1983,2038,2041,2045,2048,2054,2056,2064,2066],[42,1499,1501],{"id":1500},"hvorfor-tech-stack-valget-er-vigtigere-end-du-tror","Hvorfor tech stack-valget er vigtigere end du tror",[47,1503,1504],{},"At vælge en tech stack er ikke bare et teknisk valg — det er en forretningsbeslutning. Jeg har set virksomheder spilde hundredtusindvis af kroner fordi de valgte den forkerte teknologi. Og jeg har set små teams levere hurtigere end store teams, fordi de valgte klogt.",[47,1506,1507],{},"Her er hvad der står på spil:",[188,1509,1510,1516,1522,1528,1534],{},[191,1511,1512,1515],{},[63,1513,1514],{},"Udviklingsomkostninger"," — Den forkerte stack kan fordoble din udviklingstid",[191,1517,1518,1521],{},[63,1519,1520],{},"Hastighed til markedet"," — Rigtig teknologi betyder hurtigere launch",[191,1523,1524,1527],{},[63,1525,1526],{},"Rekruttering"," — Kan du finde udviklere der kender stakken? Og hvad koster de?",[191,1529,1530,1533],{},[63,1531,1532],{},"Skalerbarhed"," — Kan teknologien vokse med din forretning?",[191,1535,1536,1539],{},[63,1537,1538],{},"Vedligeholdelse"," — Hvad koster det at holde systemet kørende om 3-5 år?",[47,1541,1542],{},"I min karriere — fra Grundfos og Vestas til Playable og Harness, og nu som Technical Director hos Checkmate.dk — har jeg truffet denne beslutning mange gange. Her er det framework jeg bruger.",[42,1544,1546],{"id":1545},"mit-framework-til-at-evaluere-tech-stack","Mit framework til at evaluere tech stack",[47,1548,1549],{},"Før du overhovedet tænker på specifikke teknologier, skal du stille de rigtige spørgsmål. Her er min tjekliste:",[1233,1551,1553],{"id":1552},"_1-hvad-kan-dit-team","1. Hvad kan dit team?",[47,1555,1556],{},"Det vigtigste spørgsmål. Punkt. Teknologi dit team allerede kender vil næsten altid slå \"den bedste\" teknologi dit team ikke kender.",[47,1558,1559],{},"Hos Grundfos arvede vi et projekt bygget i et framework teamet ikke havde erfaring med. Resultatet? 6 måneders forsinkelse og en komplet omskrivning. Havde nogen spurgt \"hvad kan teamet?\", var det aldrig sket.",[47,1561,1562],{},[63,1563,1564],{},"Spørgsmål du skal stille:",[188,1566,1567,1570,1573],{},[191,1568,1569],{},"Hvad har teamet erfaring med?",[191,1571,1572],{},"Hvad kan de lære realistisk inden for projektets tidsramme?",[191,1574,1575],{},"Er der nogen i teamet der kan drive den tekniske retning?",[1233,1577,1579],{"id":1578},"_2-hvad-kræver-projektet-reelt","2. Hvad kræver projektet reelt?",[47,1581,1582,1583,1586],{},"Ikke hvad det ",[1009,1584,1585],{},"måske"," kræver om 3 år. Hvad kræver det nu?",[47,1588,1589],{},"Mange teams over-engineerer fordi de forbereder sig på skaleringsudfordringer de aldrig får. Byg til dine næste 12 måneder, ikke til et hypotetisk scenarie.",[47,1591,1592],{},[63,1593,1564],{},[188,1595,1596,1599,1602,1605,1608],{},[191,1597,1598],{},"Hvor mange brugere skal systemet håndtere?",[191,1600,1601],{},"Hvor kompleks er forretningslogikken?",[191,1603,1604],{},"Er der real-time krav?",[191,1606,1607],{},"Skal det integreres med eksisterende systemer?",[191,1609,1610],{},"Hvad er tidsplanen?",[1233,1612,1614],{"id":1613},"_3-hvor-modent-er-økosystemet","3. Hvor modent er økosystemet?",[47,1616,1617],{},"Et framework kan være teknisk overlegent, men hvis der ikke er gode biblioteker, dokumentation og community support, betaler du prisen i udvikling.",[47,1619,1620],{},[63,1621,1564],{},[188,1623,1624,1627,1630,1633],{},[191,1625,1626],{},"Hvor gammel er teknologien? (Under 2 år = risiko)",[191,1628,1629],{},"Er der aktiv udvikling og regelmæssige releases?",[191,1631,1632],{},"Hvor stort er communityet?",[191,1634,1635],{},"Er der gode biblioteker til dine kernebehov?",[1233,1637,1639],{"id":1638},"_4-kan-du-ansætte-folk","4. Kan du ansætte folk?",[47,1641,1642],{},"I Danmark er der stor forskel på hvor mange udviklere der kan de forskellige teknologier. Det skal du tænke ind fra start.",[47,1644,1645],{},[63,1646,1564],{},[188,1648,1649,1652,1655],{},[191,1650,1651],{},"Hvor mange ledige stillinger bruger denne teknologi i dit område?",[191,1653,1654],{},"Hvad er lønniveauet for udviklere med denne kompetence?",[191,1656,1657],{},"Kan du træne eksisterende medarbejdere?",[42,1659,1661],{"id":1660},"de-5-mest-almindelige-fejl","De 5 mest almindelige fejl",[1233,1663,1665],{"id":1664},"fejl-1-at-vælge-baseret-på-hype","Fejl 1: At vælge baseret på hype",[47,1667,1668,1669,1672],{},"\"Vi skal bruge ",[407,1670,1671],{},"nyeste framework"," fordi alle taler om det.\" Nej. Medmindre der er en reel teknisk grund, er popularitet på Twitter ikke et argument.",[1233,1674,1676],{"id":1675},"fejl-2-over-engineering-fra-dag-1","Fejl 2: Over-engineering fra dag 1",[47,1678,1679],{},"Du bygger en marketing-side og vælger microservices med Kubernetes? Stop. Start simpelt, tilføj kompleksitet når du har brug for det.",[1233,1681,1683],{"id":1682},"fejl-3-at-ignorere-teamets-kompetencer","Fejl 3: At ignorere teamets kompetencer",[47,1685,1686],{},"Jeg gentager det gerne: dit teams erfaring trækker mere end noget frameworks features. En middelmådig stack i hænderne på et godt team slår en perfekt stack i hænderne på et team der fumler.",[1233,1688,1690],{"id":1689},"fejl-4-at-lade-en-enkelt-udvikler-diktere-valget","Fejl 4: At lade en enkelt udvikler diktere valget",[47,1692,1693],{},"Undgå \"resume-driven development\" — hvor nogen vælger en teknologi fordi de gerne vil have den på deres CV, ikke fordi den er rigtig for projektet.",[1233,1695,1697],{"id":1696},"fejl-5-at-glemme-exit-strategien","Fejl 5: At glemme exit-strategien",[47,1699,1700],{},"Hvad sker der hvis frameworket dør, eller den primære maintainer stopper? Kan du migrere? Hvor låst er du inde?",[42,1702,1704],{"id":1703},"konkrete-anbefalinger-efter-projekttype","Konkrete anbefalinger efter projekttype",[47,1706,1707],{},"Her er mine anbefalinger baseret på det jeg ser virke i 2026. Husk: disse er udgangspunkter, ikke dogmer.",[1233,1709,1711],{"id":1710},"marketing-site-portfolio","Marketing-site \u002F portfolio",[188,1713,1714,1720,1726,1732],{},[191,1715,1716,1719],{},[63,1717,1718],{},"Frontend:"," Nuxt 3 (Vue) eller Next.js (React) med statisk generering",[191,1721,1722,1725],{},[63,1723,1724],{},"CMS:"," Headless CMS som Storyblok, Contentful eller Sanity",[191,1727,1728,1731],{},[63,1729,1730],{},"Hosting:"," Netlify eller Vercel",[191,1733,1734,1737],{},[63,1735,1736],{},"Hvorfor:"," Hurtig udvikling, god SEO ud af boksen, billig hosting, ingen server at vedligeholde",[47,1739,1740],{},"Dette site (nickychristensen.dk) er bygget præcis sådan — Nuxt 3, statisk generering, deployeret på Netlify. Det er hurtigt, billigt at drive og nemt at vedligeholde.",[1233,1742,1744],{"id":1743},"e-commerce-webshop","E-commerce \u002F webshop",[188,1746,1747,1753,1758,1764],{},[191,1748,1749,1752],{},[63,1750,1751],{},"Platform:"," Shopify (simpel) eller headless Shopify \u002F Medusa med custom frontend",[191,1754,1755,1757],{},[63,1756,1718],{}," Nuxt eller Next.js",[191,1759,1760,1763],{},[63,1761,1762],{},"Betalinger:"," Stripe eller Adyen",[191,1765,1766,1768],{},[63,1767,1736],{}," E-commerce er et løst problem. Brug en platform der håndterer det tunge (betaling, lager, ordre), og byg custom UI ovenpå",[1233,1770,1772],{"id":1771},"saas-produkt","SaaS-produkt",[188,1774,1775,1780,1786,1792,1798],{},[191,1776,1777,1779],{},[63,1778,1718],{}," Vue 3 + Pinia eller React + Zustand\u002FJotai",[191,1781,1782,1785],{},[63,1783,1784],{},"Backend:"," Node.js (Express\u002FFastify) eller Go for høj performance",[191,1787,1788,1791],{},[63,1789,1790],{},"Database:"," PostgreSQL med Prisma eller Drizzle ORM",[191,1793,1794,1797],{},[63,1795,1796],{},"Auth:"," Auth0, Clerk eller Supabase Auth",[191,1799,1800,1802],{},[63,1801,1736],{}," Her skal du tænke langsigtet. Vælg det dit team er stærkest i, og prioriter god arkitektur fra start",[47,1804,1805],{},"Hos Playable byggede vi SaaS-produktet i Vue med en Node-backend. Det fungerede fremragende fordi teamet kendte stakken.",[1233,1807,1809],{"id":1808},"enterprise-applikation","Enterprise-applikation",[188,1811,1812,1817,1822,1828],{},[191,1813,1814,1816],{},[63,1815,1718],{}," React (størst talentpool) eller Vue 3 med TypeScript",[191,1818,1819,1821],{},[63,1820,1784],{}," .NET, Java Spring eller Node.js — afhængig af organisationens kompetencer",[191,1823,1824,1827],{},[63,1825,1826],{},"Infrastruktur:"," Cloud (AWS\u002FAzure\u002FGCP) med CI\u002FCD",[191,1829,1830,1832],{},[63,1831,1736],{}," Her handler det om stabilitet, skalerbarhed og muligheden for at ansætte. Vælg modne teknologier med lang track record",[47,1834,1835],{},"Hos Vestas og Grundfos oplevede jeg værdien af at vælge kedeligt og gennemprøvet. Nye og spændende teknologier har en højere pris når hundredevis af udviklere skal arbejde med dem.",[42,1837,1839],{"id":1838},"vue-vs-react-vs-andre-frameworks-i-2026","Vue vs React vs andre frameworks i 2026",[47,1841,1842,1843,1846],{},"Jeg har skrevet en hel artikel om ",[282,1844,1845],{"href":1483},"React vs Vue i 2026",", men her er den korte version:",[47,1848,1849],{},[63,1850,1851],{},"Vælg Vue hvis:",[188,1853,1854,1857,1860,1863],{},[191,1855,1856],{},"Dit team er mindre (2-10 udviklere)",[191,1858,1859],{},"Du vil have en blødere læringskurve",[191,1861,1862],{},"Du foretrækker convention over configuration",[191,1864,1865],{},"Du bygger med Nuxt og vil have \"batteries included\"",[47,1867,1868],{},[63,1869,1870],{},"Vælg React hvis:",[188,1872,1873,1876,1879,1882],{},[191,1874,1875],{},"Du ansætter i stor skala og har brug for den største talentpool",[191,1877,1878],{},"Du har brug for React Native til mobil",[191,1880,1881],{},"Dit team allerede kender React",[191,1883,1884],{},"Du arbejder i et enterprise-miljø med eksisterende React-infrastruktur",[47,1886,1887],{},[63,1888,1889],{},"Overvej Svelte\u002FSvelteKit hvis:",[188,1891,1892,1895,1898],{},[191,1893,1894],{},"Du bygger et mindre projekt med fokus på performance",[191,1896,1897],{},"Dit team er nysgerrige og villige til at lære noget nyt",[191,1899,1900],{},"Du ikke har brug for et kæmpe økosystem af tredjepartsbiblioteker",[47,1902,1903],{},[63,1904,1905],{},"Angular er stadig relevant hvis:",[188,1907,1908,1911,1914],{},[191,1909,1910],{},"Du arbejder i et stort enterprise-miljø (særligt .NET-shops)",[191,1912,1913],{},"Dit team kender det allerede",[191,1915,1916],{},"Du værdsætter streng struktur og opinionated arkitektur",[42,1918,1920],{"id":1919},"backend-overvejelser","Backend-overvejelser",[47,1922,1923],{},"Frontend får al opmærksomheden, men backend-valget er mindst lige så vigtigt.",[47,1925,1926,1929],{},[63,1927,1928],{},"Node.js"," er det oplagte valg hvis dit team allerede skriver JavaScript\u002FTypeScript. Du får kodedeling mellem frontend og backend, og der er et enormt økosystem.",[47,1931,1932,1935],{},[63,1933,1934],{},"Headless CMS"," (Storyblok, Contentful, Sanity) er rigtige for content-drevne sites. Lad redaktørerne arbejde i en editor de forstår, og byg en custom frontend.",[47,1937,1938,1941],{},[63,1939,1940],{},"Backend-as-a-Service"," (Supabase, Firebase) er fantastisk til prototyper og mindre SaaS-produkter. Du får database, auth og API uden at bygge det selv. Men vær opmærksom på vendor lock-in.",[47,1943,1944,1947],{},[63,1945,1946],{},"Go eller Rust"," giver mening hvis performance er kritisk og dit team har kompetencen. For de fleste projekter er Node.js rigeligt.",[42,1949,1951],{"id":1950},"ai-værktøjers-rolle-i-tech-stack-valget-2026-perspektiv","AI-værktøjers rolle i tech stack-valget (2026-perspektiv)",[47,1953,1954],{},"I 2026 har AI-assistenter som GitHub Copilot, Cursor og Claude fundamentalt ændret hvordan vi skriver kode. Det påvirker også tech stack-valget:",[47,1956,1957,1960],{},[63,1958,1959],{},"Større økosystem = bedre AI-support."," AI-modeller er trænet på offentlig kode. React og Vue har mere træningsdata end nicheframeworks, hvilket betyder bedre autokomplettering og fejlfinding.",[47,1962,1963,1966],{},[63,1964,1965],{},"AI reducerer læringskurven."," Det er nemmere at komme i gang med et nyt framework når AI kan forklare kode, generere boilerplate og finde fejl. Men det erstatter ikke dyb forståelse — du skal stadig vide hvad du laver.",[47,1968,1969,1972],{},[63,1970,1971],{},"Vælg ikke kun baseret på AI-support."," Det er fristende at vælge den teknologi AI er bedst til at generere. Men AI er et værktøj, ikke en arkitekt. De fundamentale kriterier (team, krav, økosystem, rekruttering) er stadig vigtigere.",[47,1974,1975],{},"Mit råd: Brug AI som accelerator, men lad det ikke diktere dine teknologiske valg.",[42,1977,1979],{"id":1978},"din-tjekliste","Din tjekliste",[47,1981,1982],{},"Før du træffer den næste tech stack-beslutning, gå denne liste igennem:",[188,1984,1987,1996,2002,2008,2014,2020,2026,2032],{"className":1985},[1986],"contains-task-list",[191,1988,1991,1995],{"className":1989},[1990],"task-list-item",[1992,1993],"input",{"disabled":315,"type":1994},"checkbox"," Hvad kan dit team allerede?",[191,1997,1999,2001],{"className":1998},[1990],[1992,2000],{"disabled":315,"type":1994}," Hvad kræver projektet reelt (ikke hypotetisk)?",[191,2003,2005,2007],{"className":2004},[1990],[1992,2006],{"disabled":315,"type":1994}," Er økosystemet modent nok?",[191,2009,2011,2013],{"className":2010},[1990],[1992,2012],{"disabled":315,"type":1994}," Kan du ansætte folk med denne kompetence?",[191,2015,2017,2019],{"className":2016},[1990],[1992,2018],{"disabled":315,"type":1994}," Har du overvejet vedligeholdelsesomkostninger?",[191,2021,2023,2025],{"className":2022},[1990],[1992,2024],{"disabled":315,"type":1994}," Er du sikker på du ikke over-engineerer?",[191,2027,2029,2031],{"className":2028},[1990],[1992,2030],{"disabled":315,"type":1994}," Har du en exit-strategi?",[191,2033,2035,2037],{"className":2034},[1990],[1992,2036],{"disabled":315,"type":1994}," Har du spurgt teamet (og ikke kun den mest højlydte udvikler)?",[47,2039,2040],{},"Hvis du kan svare ja til de fleste af disse, er du på rette vej.",[42,2042,2044],{"id":2043},"afsluttende-tanker","Afsluttende tanker",[47,2046,2047],{},"I 19+ år som udvikler og nu som Technical Director har jeg lært en ting: den bedste tech stack er den der lader dit team levere værdi hurtigt og pålideligt. Det lyder kedeligt. Det er det også. Men det virker.",[47,2049,2050,2051,1440],{},"Stop med at lede efter den perfekte teknologi. Find den rigtige teknologi ",[1009,2052,2053],{},"for dig, dit team og dit projekt",[276,2055],{},[47,2057,2058],{},[1009,2059,2060,2061,2063],{},"Har du brug for sparring på dit næste teknologivalg? Jeg hjælper virksomheder med at træffe de rigtige tekniske beslutninger. ",[282,2062,1041],{"href":1040}," for en uforpligtende snak.",[276,2065],{},[47,2067,2068,2070,2071],{},[63,2069,291],{}," Tech stack-valg har reelle konsekvenser — da vi valgte Vue 3 og TypeScript til Playables SaaS-platform, lagde det fundamentet for en skalérbar og vedligeholdbar arkitektur. ",[282,2072,1052],{"href":1450},{"title":99,"searchDepth":302,"depth":302,"links":2074},[2075,2076,2082,2089,2095,2096,2097,2098,2099],{"id":1500,"depth":302,"text":1501},{"id":1545,"depth":302,"text":1546,"children":2077},[2078,2079,2080,2081],{"id":1552,"depth":434,"text":1553},{"id":1578,"depth":434,"text":1579},{"id":1613,"depth":434,"text":1614},{"id":1638,"depth":434,"text":1639},{"id":1660,"depth":302,"text":1661,"children":2083},[2084,2085,2086,2087,2088],{"id":1664,"depth":434,"text":1665},{"id":1675,"depth":434,"text":1676},{"id":1682,"depth":434,"text":1683},{"id":1689,"depth":434,"text":1690},{"id":1696,"depth":434,"text":1697},{"id":1703,"depth":302,"text":1704,"children":2090},[2091,2092,2093,2094],{"id":1710,"depth":434,"text":1711},{"id":1743,"depth":434,"text":1744},{"id":1771,"depth":434,"text":1772},{"id":1808,"depth":434,"text":1809},{"id":1838,"depth":302,"text":1839},{"id":1919,"depth":302,"text":1920},{"id":1950,"depth":302,"text":1951},{"id":1978,"depth":302,"text":1979},{"id":2043,"depth":302,"text":2044},"En praktisk guide til at vælge den rigtige teknologi til dit næste projekt. Baseret på 19+ års erfaring med alt fra enterprise-løsninger til startups.",{},"\u002Fblog\u002Fsaadan-vaelger-du-den-rigtige-tech-stack",{"title":1495,"description":2100},"Lær at vælge den rigtige tech stack i 2026. Praktisk framework med konkrete anbefalinger til marketing sites, webshops, SaaS og enterprise.","Sådan vælger du den rigtige tech stack i 2026 — Praktisk guide","saadan-vaelger-du-den-rigtige-tech-stack","blog\u002Fsaadan-vaelger-du-den-rigtige-tech-stack",[2109,2110,327,1078,323,2111],"tech-stack","strategi","webudvikling","5qETdP281SXGQYBoZBruEm7W8CscMgSVkKLF3ydGLRA",1777210997808]