# Kodebase

## Hvad det er

En kodebase, på engelsk codebase eller code base, er hele den mængde kildekode,
et team redigerer, gennemgår og udgiver som én ting. Når udviklere siger
»kodebasen«, mener de stedet, hvor hver ændring af en applikation ender: selve
koden, testene, de scripts, der bygger og tjekker den, databaseændringerne og de
dokumenter, der forklarer, hvordan delene hænger sammen.

[The Twelve-Factor App](https://12factor.net/), en metode til at bygge
webtjenester, giver den mest brugbare definition, fordi den gør grænsen til
noget, man kan efterprøve. I et centraliseret versionsstyringssystem som
Subversion er en kodebase ét repository. I et distribueret system som Git er det
ethvert sæt af repositories, der deler en rod-commit: den første commit i
historikken, den eneste uden forælder. To repositories, der er vokset fra den
samme første commit, er én kodebase, uanset hvor langt de er gledet fra
hinanden. To, der begyndte hver for sig, er to kodebaser, også selv om filerne
er næsten ens.

Samme dokument parrer definitionen med en anden regel: én kodebase, mange
deploys. Et deploy er en kørende instans af applikationen, og der er som regel
flere ad gangen. Produktion er ét, staging et andet, og hver udviklers lokale
kopi tæller med. De kører alle den samme kodebase, ofte ved forskellige commits:
en udvikler har arbejde, som staging mangler, og staging har arbejde, som
produktion mangler.

Hvad der hører hjemme i den, følger af det. Kildekoden og alt, hvad der skal til
for at gøre den til et kørende program, hører til, også et manifest, der
navngiver hver afhængighed og dens version. Selve afhængighederne ligger som
regel udenfor og hentes af en pakkehåndtering. Værdier, der skifter fra det ene
deploy til det næste, ligger også udenfor, og frem for alt adgangsoplysninger:
en adgangskode, der er committet én gang, rejser med hver kopi af historikken
bagefter.

En kodebase kan rumme flere programmer. Et monorepo holder en frontend, et API
og databasekoden side om side i ét repository, så én commit kan ændre alle tre
på en gang. Efter rod-commit-reglen er det stadig én kodebase. Det modsatte valg
spreder en applikation ud over repositories med hver sin historik, og så er
hvert repository sin egen kodebase. Twelve-factor siger det ligeud: er der flere
kodebaser, er det et distribueret system, og hver komponent er en app for sig.

## Hvorfor det betyder noget

Grænsen afgør, hvad der kan ændres samlet. Inden for én kodebase kan en ændring
af et API og den skærm, der kalder det, skrives, gennemgås og merges som én
enhed. På tværs af to kodebaser bliver den samme ændring til to pull requests,
to udgivelser og en periode, hvor den ene side er foran den anden. Begge dele
kan fungere; prisen bestemmes af, hvor stregen blev trukket.

Kodebasen er også den enhed, standarder kører over. En testsuite, en linter, en
formatter, en regel for commitbeskeder og en task runner tager alle »kodebasen«
som deres område, og det, der ligger uden for den, falder uden for dem alle.

Tidlige beslutninger stivner hurtigere i en kodebase end noget andet sted. Hver
linje, der skrives efter et valg, forudsætter valget, så en regel om lagdeling
eller en kvalitetsstandard fra de første uger bliver formen på alt, hvad der
følger. At vende den senere betyder at skrive den kode om, der er vokset op
omkring den.

For mennesker er kodebasen det, en nyansat får udleveret. Rummer den alt, der
skal til for at bygge, teste og køre applikationen, kommer den nye i gang med én
clone og én kommando. Ligger viden dels i koden og dels i en kollegas
hukommelse, går den første uge med at finde ud af, hvad der er hvad.

## Sådan ser det ud i praksis

En kodebase i mange sprog har brug for én hoveddør. På én platform er
[kodebasen et polyglot-monorepo](/da/portfolio/authored-578-go-task-automation-targets-70/)
i Go, TypeScript, SQL, Python og shell, og hvert sprog kommer med sin egen måde
at bygge, teste og linte på. Svaret var én indgang: et go-task-lag, der voksede
til 578 navngivne mål, 50 i rodfilen og 528 i namespacede filer under den, med
udviklingstilstande til native, Docker og HTTPS, kodekvalitet,
databasehåndtering og deploy. Enhver kan køre `task --list` og se hele
værktøjskæden. Siden læser også tallet som en advarsel: 578 mål er mere, end
nogen kan holde i hovedet, så det er navngivningen og opdelingen i namespaces,
der holder det brugbart.

Grundreglerne kan også komme først. Et projekt begyndte den 25. november 2025
med et repository uden indhold, og
[tre beslutninger fra de første uger](/da/portfolio/set-the-platform-s-founding-decisions-in-november-2025-80/)
holdt stadig ni måneder og flere tusinde commits senere: en lagdelt stak,
dataadgang bag stored functions og en zero-warnings-standard, der kom ind, før
der var meget kode at holde til den. Begrundelsen på siden er kernen i denne
artikel: en standard indført ved commit 5.000 er et oprydningsprojekt, mens den
samme standard ved commit 50 bare er, hvordan repositoriet fungerer.

Væggene inde i en kodebase kan være selve designet. På en
[maritim platform bygget i tre lag](/da/portfolio/architected-a-layered-maritime-platform-separating-a-next-57/)
står Next.js-frontenden for præsentation og intet andet, et bevidst tyndt Go-API
bygget med Huma oven på Fiber router, validerer og orkestrerer, og
forretningslogikken bor i PostgreSQL-funktioner. Når en regel ændres, ændres den
i ét lag, i SQL. Grænserne blev skrevet ned og håndhævet i code review, fordi en
konvention, som ingen holder øje med, holder op med at være en.

Dette sites egen kodebase trækker en anden slags streg. Projektsiderne skrives i
et separat repository, eksporteres hertil af et script og committes, så sitet
kan bygges for sig selv. Inden for denne kodebase er de genererede filer, og
instruktionerne for arbejdet her siger, at de aldrig rettes i hånden.

## Hvor det går galt

### Kopieret kode glider fra hinanden

To applikationer har brug for den samme hjælpefunktion, og det hurtigste er at
kopiere den over. Et år senere findes der to versioner med forskellige
rettelser, og en fejl, der er lukket i den ene, lever videre i den anden.
Twelve-factor kalder flere apps, der deler den samme kode, et brud på metoden og
peger på løsningen: flyt den fælles del ud i et bibliotek, hent den ind gennem
pakkehåndteringen, og lad hver kodebase angive den version, den bruger.

### En hemmelighed havner i historikken

En forbindelsesstreng eller en API-nøgle bliver committet i en
konfigurationsfil, og fra da af ligger den i den historik, som hver clone bærer
med sig, også efter at en senere commit har slettet linjen. Twelve-factors prøve
er værd at tage før hver commit: kan denne kodebase udgives som open source i
dag uden at afsløre en eneste adgangsoplysning? Alt, der dumper den prøve, hører
hjemme i miljøet for hvert deploy.

### En genereret fil bliver rettet i hånden

En fil skrevet af et script ligner enhver anden kildefil, så nogen retter en
tastefejl direkte i den. Næste gang scriptet kører, skriver det den gamle tekst
tilbage, og rettelsen forsvinder i stilhed. Mærk genererede stier tydeligt, lad
generatoren være den eneste, der skriver dem, og send hver rettelse til
generatorens input.

### Væggene indeni bliver tynde

Under tidspres ryger en databaseforespørgsel direkte ind i en request handler,
fordi det er den korteste vej, og den lagdeling, projektet startede med, holder
op med at beskrive koden. Hver genvej er lille. Tilsammen gør de en ændring på
to linjer til en, der rører hvert lag. En skreven regel hjælper, code review
hjælper mere, og et tjek, der stopper buildet, når ét lag rækker ind i et andet,
hjælper mest.

### En standard dækker halvdelen af koden

En linter sat op til frontenden lader shellscripts og SQL være, og netop de
filer samler de problemer, linteren skulle forhindre. En standard for hele
kodebasen skal nævne hvert sprog i den, og det er den skjulte pris ved et
polyglot-repository.

### En fork bliver til et nyt produkt

Et team kopierer et repository for at starte et beslægtet produkt. Begge kopier
beholder den samme rod-commit, så efter twelve-factor-reglen er de stadig én
kodebase, der nu tjener to apps, og den drift, der er beskrevet ovenfor,
begynder i et helt repositorys målestok. En sammenligning af rod-commits viser,
hvilken situation man står i:

```sh
git -C app-a rev-list --max-parents=0 HEAD
git -C app-b rev-list --max-parents=0 HEAD
```

Ens output betyder en fælles rod og en fælles kodebase; forskelligt output
betyder to adskilte historikker.

## Læs mere

- [I. Codebase](https://12factor.net/codebase) — reglen om én kodebase og mange
  deploys og prøven med den fælles rod-commit bag den.
- [II. Dependencies](https://12factor.net/dependencies) — hver afhængighed
  erklæret i et manifest og isoleret, så kodebasen siger præcis, hvad den
  trækker ind.
- [III. Config](https://12factor.net/config) — open source-prøven for, hvad der
  skal holdes ude af en kodebase.
- [gitsubmodules](https://git-scm.com/docs/gitsubmodules) — hvordan Git
  indlejrer ét repository i et andet, mens hvert beholder sin egen historik.
- [git-rev-list](https://git-scm.com/docs/git-rev-list) — opslagsværket for at
  liste commits, også rod-commits i en historik.

<https://engineer.company/da/glossary/codebase/>
