Da jeg opgav mit “perfekte” sideprojekt og endelig fik noget færdigt

Da jeg opgav mit “perfekte” sideprojekt og endelig fik noget færdigt

Jeg kan stadig huske Trello-boardet. Fire kolonner, 63 kort, farvekoder, labels. Og nul færdige features. Jeg havde sat mig for at bygge en “seriøs” webapp til min portefølje. Tre måneder senere havde jeg én halvfærdig login-side og en meget flot README-overskrift.

Det første projekt, der faktisk fik mig til samtale hos en arbejdsgiver, var derimod en lille, kedelig support-ticket tracker bygget på to aftener og en weekend. Forskellen var ikke idéen. Det var scopet.

Før vs nu: hvorfor porteføljeprojekter dør

Hvis jeg skal koge det ned, så har mine døde projekter næsten altid haft én af de samme fire sygdomme.

Før (projekter der døde) Nu (projekter der bliver færdige)
Starter med “jeg vil lave et slags mini-Trello / mini-Notion / mini-Facebook” Starter med “én konkret bruger og ét konkret problem”
Ingen slutdato, bare en vag drøm om “når det føles rigtigt” Timebox: “Jeg skal have noget deployet om 7 dage, om det så er grimt”
Features i hovedet, ingen liste, ingen prioritering Lille liste: must / should / could, og jeg rører ikke “could” før deploy
Portefølje = “flot kode” inde i repoet Portefølje = demo-link + README der fortæller historien

Hvis du genkender venstre kolonne, er du helt normal. Det betyder bare, at du tænker som en bruger af software, ikke som den person der skal bygge det alene.

Vælg et domæneproblem, ikke en “app-type”

Den klassiske søgning er “portefølje projekt idé” eller “coding projekter for begyndere”. Så får du en liste: to-do app, blog, chat, budget-app, blablabla.

Problemet: de siger intet om kontekst. Du ender med “endnu en to-do app” uden historie.

Domæne først, funktion bagefter

Prøv at starte her i stedet:

  • Hvem kender du, som har et lille, konkret problem?
  • Hvad er det for et domæne? Studier, café, forening, musik, gaming, sport, frivilligt arbejde?
  • Kan du beskrive problemet i én sætning uden tekniske ord?

Eksempler:

  • “Mit kor kan aldrig huske, hvilken rækkefølge vi skal synge sangene til koncerten.”
  • “Min ven med foodtruck glemmer, hvem der har bestilt forud.”
  • “Min studiegruppe mister altid links til gamle eksamenssæt.”

Så kan du oversætte det til en app-type bagefter: liste, lille CRUD-system, filtret søgning osv. Der er en grund til, at jeg tidligere har argumenteret for at bygge et lille system i stedet for endnu en to-do app. Systemer har historier. Historier bliver husket.

Check: er din idé “for flink”?

En idé er “for flink”, hvis du ikke kan svare skarpt på de her spørgsmål:

  • Hvem er brugeren? (ikke “alle der har travlt”)
  • Hvornår på dagen bruger de det?
  • Hvilken nuværende løsning ville de droppe, hvis din app virkede?

Hvis du ikke kan svare, så er det ikke et domæneproblem endnu. Så er det bare en app-type.

Scope-framework: must / should / could + timebox

Nu til det kedelige, der gør forskellen: at beslutte, hvad du ikke bygger.

Step 1: Sæt en hård tidsramme

Vælg en timebox inden du skriver et eneste issue:

  • Lille portefølje-brik: 1 weekend
  • Lidt større showcase: 7 dage med 1-2 timer om dagen
  • Ambitiøst men realistisk: 3 uger, klart defineret scope

Jo tidligere du er i din karriere, jo kortere synes jeg din timebox skal være. Et lille, færdigt projekt hver eller hver anden uge slår et kæmpe ufærdigt projekt hver tredje måned.

Step 2: Skriv features som brugerhandlinger

Drop “byg database” og “lav auth” som tasks. Skriv dem som handlinger:

  • “Bruger kan oprette en ticket med titel og beskrivelse”
  • “Bruger kan markere en ticket som løst”
  • “Bruger kan se alle åbne tickets sorteret nyeste først”

Det gør det meget nemmere at skære fra.

Step 3: Del alt op i must / should / could

Nu tager du din liste og fordeler den:

  • Must: Hvis de her mangler, giver appen ikke mening overhovedet.
  • Should: Klart nice at have, men appen kan bruges uden.
  • Could: Fremtidsdrømme, kun hvis du bliver færdig tidligt.

Eksempel: lille support-ticket app til en ven:

Must
- Opret ticket med titel og beskrivelse
- Liste over åbne tickets
- Skift status: "åben" → "lukket"

Should
- Filtrer tickets efter status
- Søg i tickets efter tekst
- Sorter efter oprettelsesdato

Could
- Simpelt login-system
- Upload af billede til en ticket
- Label-system (fx "bug", "spørgsmål")

Regel: du må ikke røre “should” før alle “must” er kodet, testet og deployet.

Step 4: Tjek scopet mod timeboxen

Nu kommer den ubehagelige del: at være ærlig om, hvor lang tid ting tager.

Kig kun på “must” og giv dem et groft bud:

  • “Opret ticket” (form, request, gemme data): 2-4 timer
  • “Liste tickets” (API, liste, visning): 2-4 timer
  • “Skift status” (UI + API): 2-3 timer
  • Deploy (hosting, domain, basic opsætning): 2-4 timer

Samlet: 8-15 timer. Hvis din timebox er en weekend, er det faktisk realistisk for en begyndende udvikler, hvis du holder tech-stacken simpel. Hvis det ender på 20-30 timer, så skær én “must” væk, eller gør den mindre.

Hvad imponerer mest: features vs engineering-vaner

Mange spørger “hvad skal man bygge til portefølje for at imponere?”. Min erfaring: arbejdsgivere bliver mere imponeret af hvordan du har bygget noget lille, end hvor mange features dit halvfærdige monster har.

Vælg 2-3 “fokus-akser”

Du kan ikke være verdensmester i alt i ét projekt. Vælg 2-3 ting, hvor du vil vise ekstra omtanke, fx:

  • Drift: Deploy, miljøvariabler, simple logs.
  • Tests: Nogle få, men meningsfulde tests.
  • Data: Fornuftig datamodel, måske lidt SQL.
  • UX: Klart flow, keyboard shortcuts, loading states.
  • Sikkerhed: Fornuftig håndtering af auth, ingen åbenlyse huller.

Det spiller fint sammen med andre emner du måske allerede har læst om, som fx at skrive en README andre gider læse eller helt basic HTML og CSS struktur.

Eksempel: to versioner af samme feature

Forestil dig to næsten identiske projekter:

  • Projekt A: Mange features, ingen README, ingen demo, ingen tests, ingen seed-data.
  • Projekt B: Færre features, men deployet, med README, et par tests og screenshots.

Hvis jeg skal ansætte en juniorudvikler, vælger jeg altid B. Det er meget nemmere at se, hvordan du arbejder i virkeligheden.

6 projekt-skabeloner med niveauer (så du kan stoppe i tide)

Her får du seks slags projekter, som er gode i en portefølje, hver med tre niveauer. Pointen er, at du trygt kan stoppe på niveau 1 og stadig have noget at vise.

1) Lille tickets- eller opgave-tracker

Domæne: support, studieopgaver, huslige pligter, bug-liste.

  • Niveau 1: Opret, se liste, markér som færdig. Alt gemt i localStorage eller en lille JSON backend.
  • Niveau 2: Rigtig database, simple filtre (åben/lukket), sortering efter dato.
  • Niveau 3: Auth, roller (fx “admin” vs “bruger”), labels, kommentarfelt.

2) Studiedata-browser

Domæne: eksamenssæt, noter, forelæsningsslides.

  • Niveau 1: Liste over ressourcer med kategori og link.
  • Niveau 2: Filtret søgning, fx efter fag, årstal, type.
  • Niveau 3: Upload af dokumenter, brugerprofiler, favoritter.

3) Simpel finans- eller budgetapp

Domæne: personligt budget, fællesudgifter i en lejlighed, madbudget.

  • Niveau 1: Indtast indtægter/udgifter, vis sum pr. kategori.
  • Niveau 2: Dato-filtrering, simple grafer, eksport til CSV.
  • Niveau 3: Delte budgetter mellem brugere, notifikationer.

4) Content- eller link-samler

Domæne: “link-hub” til YouTube-videoer, artikler, opskrifter, tutorials.

  • Niveau 1: Gem titel, URL og kategori, vis liste.
  • Niveau 2: Flerfelts-søgning, tags, sortering (mest nyligt tilføjet).
  • Niveau 3: Delte samlinger, public/private, simple analytics (antal kliks).

5) Lidt klogere to-do app (med system-twist)

Ja, jeg ved godt jeg lige sagde “drop to-do appen”. Men hvis du giver den et system-formål, kan den leve.

  • Niveau 1: To-do liste for ét specifikt domæne (fx “indflytningstjekliste”).
  • Niveau 2: Skabeloner (“eksamensforberedelse”, “rejsepakning”), gemt for hver bruger.
  • Niveau 3: Del lister med andre, kommentarfelt, simple påmindelser.

Hvis du har bygget mange todo-apps før, giver det mening at koble det sammen med noget mere avanceret, fx JavaScript til web eller et lille backend-API.

6) Mini-dashboard til noget data

Domæne: sport, gaming, trafik, vejret, hvad som helst med tal.

  • Niveau 1: Hent data fra en offentlig API, vis liste og én simpel opsummering.
  • Niveau 2: Filtre, grafer, flere visninger (tabel + kort + stats).
  • Niveau 3: Gem brugerens egne favoritter, cached data, måske egen lille backend.

Leverancerne der gør dit projekt “rigtigt”: demo, README, deploy

Hvis dit projekt kun eksisterer som et GitHub-link med default README, ser det ud som alle andres. Og så gør det ikke så meget, hvor god din kode er.

1) Demo-link

Et projekt er “rigtigt”, når jeg kan prøve det uden at skulle clone noget. Fx:

  • Statisk frontend på Netlify, Vercel, GitHub Pages.
  • Full stack på fx Render, Railway, Fly.io.

Hvis du ikke er tryg ved hosting endnu, er der gode pointer i artiklen om at vælge en hosting-løsning du ikke slås med.

2) README, der fortæller en lille historie

README er din pitch. Ikke et dump af kommandoer. En simpel skabelon, du kan genbruge:

  • Hvad: 2 linjer om problemet og målgruppen.
  • Hvordan: 3-6 bullets om features (gerne opdelt i must/should-niveauer).
  • Tech: Liste over stack (frontend, backend, database, hosting).
  • Run: Trin-for-trin for at køre det lokalt.
  • Tradeoffs: Hvad du bevidst har valgt ikke at bygge.

Tradeoffs-delen er guld. Det viser, at du kan scope et softwareprojekt og prioritere, ikke bare kaste features efter det.

3) Roadmap-fil eller sektion

Hvis du har lyst til at vise, at du tænker fremad, så tilføj en lille ROADMAP-sektion i README:

### Roadmap
- [ ] Tilføje filtrering på status
- [ ] Lave simpel rolle-fordeling (admin/bruger)
- [ ] Skriv 2-3 ekstra tests til APIet

Det er vigtigt, at du ikke lader det erstatte “færdig”-følelsen. Roadmap er ikke en undskyldning for at have alt i stykker. Det er bare en liste over næste skridt.

Hvornår er et projekt “færdigt nok”? Tjekliste

Her er min personlige “er det her portefølje-klar?”-check. Brug den brutalt ærligt.

Check 1: Kan en fremmed prøve det på under 30 sekunder?

Det betyder:

  • Der er et klart demo-link øverst i README.
  • Der er ingen hemmelige env-vars, der blokerer alt.
  • Hvis der er login, er der en testbruger i README.

Check 2: Giver README mening uden at kende dig?

Forestil dig en recruiter på 3 minutter mellem to møder. Kan de:

  • Forstå problemet og målgruppen?
  • Se dine hoved-features og stack?
  • Forstå, hvad du bevidst har valgt fra?

Check 3: Er der mindst én ting, der viser engineering-omtanke?

Fx:

  • Et par tests (ikke hundrede, bare 2-5 meningsfulde).
  • En anelse fejlhåndtering og “tom”-states i UI.
  • En simpel logning af vigtige events.
  • Basic struktur i repoet, ikke bare én kæmpe fil.

Hvis du er helt ny, er det her et fint sted at blande projektarbejdet med noget projektbaseret læring, så du bygger skill og portefølje samtidig.

Check 4: Kan du forklare projektet på 1 minut uden at undskylde?

Stil dig selv det her spørgsmål højt (ja, det føles lidt fjollet):

“Jeg har bygget en [kort beskrivelse]. Brugeren er [målgruppe]. Det løser [problem] ved at [løsning]. Det næste jeg ville bygge, hvis jeg havde mere tid, er [1 ting].”

Hvis du automatisk begynder at undskylde (“altså det er jo ikke færdigt, og jeg ville også gerne have lavet…”), så er det et tegn på, at du prøver at sælge drømmen om projektet mere end det, der faktisk eksisterer.

Sådan fortæller du projektets historie i en ansøgning

Et stærkt portefølje projekt er halvt kode, halvt historie. Ikke roman-historie, men beslutnings-historie.

Fra “jeg byggede en app” til “jeg løste et problem”

Når du nævner projektet i CV eller ansøgning, så drej det lidt:

  • Ikke: “Jeg byggede en to-do app i React med Node backend.”
  • Men: “Jeg byggede et lille opgavesystem til min studiegruppe, så vi kunne fordele eksamenssæt og se, hvem der tog hvad. Fokus var på at få noget deployet hurtigt og øve basic test og drift.”

Det giver mig som læser langt mere at arbejde med. Jeg kan spørge videre ind til scope, valg af stack, og hvad du ville gøre om.

Brug tradeoffs aktivt

Når du skriver eller taler om projektet, så nævn én ting, du valgte fra, og hvorfor:

  • “Jeg valgte ikke at lave brugerregistrering i første version, fordi min primære brugergruppe var en lille fast gruppe. Jeg lavede i stedet en simpel “hemmelig URL”-løsning og ville skifte til rigtig auth, hvis projektet voksede.”
  • “Jeg startede med in-memory storage for at komme hurtigt i gang. Da jeg havde basic flows på plads, flyttede jeg til en rigtig database, så jeg kunne øve lidt SQL.”

Det viser, at du kan tænke i MVP for sideprojekt og ikke bare kaste teknologi efter problemet.

Forbind projektet til rollen

Til sidst kan du oversætte projektet til noget, der ligner jobbet:

  • Hvis du søger frontend: tal om state management, komponentstruktur, UI-flow.
  • Hvis du søger backend: tal om API-design, datamodeller, teststrategi.
  • Hvis du søger full stack: fortæl om snittet mellem frontend, backend og deployment.

Så selv et ret simpelt projekt kan bruges til at vise, at du forstår de arbejdsopgaver, du er på vej ind i.

Start med en eller to brugerhistorier (en 'happy path') og skriv de mindste trin der skal til for at gennemføre dem. Del hver funktion i opgaver du kan udføre på 1-4 timer, sæt prioritet must/should/could, og brug timeboxing i stedet for præcise estimater for at undgå overplanlægning.
Lav en simpel prototype eller et klikbart flow i Figma eller paper, og vis det til 3-5 potentielle brugere mens du observerer dem i 5-10 minutter. Alternativt kan en enkel landingside med kort forklaring og en 'interesseret'-knap give hurtig feedback og vise om nogen vil bruge eller betale for løsningen.
Skriv en kort pitch: hvilket problem du løser, hvem brugeren er, og hvad der er dit MVP. Inkluder et live demo-link, 1-2 screenshots eller en GIF, en hurtig guide til at køre projektet lokalt, og et kort afsnit om tekniske valg og begrænsninger.
Vælg platforme der minimerer opsætning, fx Vercel eller Netlify til frontend og serverless-funktioner, eller Render/Heroku til små backends. Brug Hosted DB/auth som Supabase eller Firebase for at spare tid på infrastruktur, og vælg et simpelt starter-kit så du kan fokusere på funktion frem for konfiguration.

Lasse Falkenberg er typen, der begyndte at rode med HTML og CSS for at lave en simpel bandside – og opdagede, at det var langt sjovere at få knapperne til at virke end at stå på scenen. Siden har han kastet sig over alt fra små JavaScript-snippets til Python-scripts, der kan spare ham for kedeligt, manuelt arbejde i hverdagen.

Han har lært det meste ved at bygge ting, der lige præcis løser hans egne problemer: en lille webapp til at holde styr på brætspilsaftener, et script til at rydde op i rodede mapper, eller en enkel side til at dele noter med venner. Undervejs har han kæmpet sig gennem alle de klassiske fejl – semikolon, forkerte indrykninger og variabler, der hedder noget helt andet end man tror – og det er præcis den rejse, han deler på Coding Class.

På Coding Class skriver Lasse praktiske, jordnære guides, der tager udgangspunkt i små, konkrete opgaver: noget du kan se, teste og bygge videre på med det samme. Han elsker at bryde en opgave ned i små bidder, vise den fulde kode og forklare linje for linje, hvad der sker – inklusive de typiske bugs, du med stor sandsynlighed også støder på.

For Lasse handler kodning ikke om flotte titler eller store ord, men om følelsen af at få noget til at virke – og om at du som læser kan gå derfra med noget, du selv har bygget. Hvis du kan kende glæden ved at få en fejl til endelig at forsvinde, er du lige på bølgelængde med hans måde at lære fra sig på.

Send kommentar

You May Have Missed