Arkitekturen som gjorde

React gøy igjen

hos Tet/Ruter

Første dag

Tilrettelagt Transport

De som ikke kan ta vanlig kollektiv

Historikken

Samres AB

Tatt over brått

Periode med mye press

Over det verste

Se fremover

Mye skrik etter features

Her må du ha skylapper på når du skriver kode

Tilstanden 😱

Mange pakker var kritisk bakpå

Mye spagetti 🍝

Dødt designsystem 💀

Det var ikke gøy

Preview, rollback eller testmiljø

Ny retning

Masse meninger 💬

Fokus på arkitektur

Resume driven development

Lett for en, mareritt for annen

Løsningen

Nytt blod 🩸

Alt hang i designsystemet

DX og UX

Det ble gøy igjen

Mye bedre brukeropplevelse

Men hva gjorde vi?

Arkitekturen som gjorde

React gøy igjen

hos Tet/Ruter

Alt vi drar med oss

Resume driven development

Hype driven development

God arkitektur 🏗️

God arkitektur 🏗️

Litt saktere i starten

Men går ikke ned videre

Oppstår underveis

Vi er ikke ærlige

Blir dette faktisk noe stort?

Redux

Gir dette mening?

Next, React Server Components, Axios

Automatisk Next

La oss se på det

Next fordeler

SSR/SSG ut av boksen

Caching

Statiske sider og SEO

Vercel

Filbasert routing 🛣️

Next ulemper

Mer kompleksitet

Vercel lock-in

Trenger backend?

CVE-2025-29927 (9.1/10)

Kan bytte senere

React Server Components


export default async function Posts() {
  const posts = await db.post.findMany({
    orderBy: { createdAt: 'desc' },
    take: 10,
  });

  return (
    
    {posts.map(p =>
  • {p.title}
  • )}
); }

React Server Components ✅

Server side rendering

Mindre useEffect

Direkte datatilgang

Stor satsning

React Server Components ❌

Mye høyere kompleksitet

Krever ofte Next

Debugging

CVE-2025-55182 (10/10)

Axios

Native fetch

Interceptors og filopplasting 📂

Bundle size

Supply chain attack

Supply chain attack

npm install axios

Pnpm

Postinstall safety

allowBuilds list

minimumReleaseAge: 1440 (24h)

Date-fns 📅

Temporal veldig snart

const now = Temporal.Now.plainDateTimeISO();
console.log(now.toString()); // 2026-04-04T14:30:00

const today = Temporal.Now.plainDateISO();
console.log(today.toString()); // 2026-04-04
						

Drømmestacken

TypeScript & React & Tailwind

TanStack Query

Next vs React Router

Vitest, Biome & Knip

TypeScript & React & Tailwind

Strict som mulig

Tsconfig import paths


							import { Button } from '@/components/Button';
						

Design system med Tailwind

State management

TanStack Query

Single file React context

Aldri Redux

Mulig Zustand

TanStack Query


// ❌ useEffect
const [posts, setPosts] = useState([]);
useEffect(() => { fetch('/api/posts').then(r => r.json()).then(setPosts) }, []);
return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
						

// ✅ TanStack Query
const { data: posts } = usePosts();
if (!posts) return <>Laster...</>;
return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
						

Single file React context

type MusicContextValue = {isMuted: boolean;};

const MusicContext = createContext<MusicContextValue | null>(null);

export const useMusic = (): MusicContextValue => {
	const context = useContext(MusicContext);
  if (!context) {
		throw new Error("useMusic must be used within a MusicProvider");
  }
  return context;
}

export const MusicProvider = ({ children }: { children: React.ReactNode }) => {...};

Forms 📝

React hook form

Zod schema

Next vs React Router

Hvorfor Next

Backend for frontend

Middleware

Økosystemet

Hvorfor React Router

Enkel mental modell

Statiske filer

Vite

Null vendor lock-in

Next vs React Router

Trenger du backend?

Liker du file based routing? 🛣️

Liker du Vercel?

Verktøy 🛠️

Biome over prettier & eslint

Verktøy 🛠️

Biome over prettier & eslint

Knip

Vite

Mappestruktur

Pages

Components

Hooks

Utils

Types

Types

Unngå d.ts

Co-locate!


export type SimulationState = {
  buildings: Building[];
};

export const simulateGame = ({
  state,
}: {
  state: SimulationState;
}): void => {};
						

Eksempel mappestruktur


app/
├── pages/
│   └── home/
│       ├── HomePage.tsx
│       └── components/
├── components/
│   ├── Button.tsx
│   └── Header.tsx
├── hooks/
│   └── use-debounce.ts
├── utils/
│   └── format-date.ts
├── types/
│   └── shared.ts
						

Testing 🧪

Vitest

Playwright

Stubbet

Co-located?

Andre tips 💡

Ikke bruk useEffect

satisfies fremfor as

Named exports over default exports

React compiler over useMemo

AI elefanten i rommet

Vi er nå systemutviklere

Flom av ulest kode

Flom av ulest kode

Fungerende kode over sikker kode

dangerouslySetInnerHTML

AI trenger struktur

Arkitektur viktigere

Claude.md

Tech Stack + Arkitektur oversikt

Prosjekt Struktur, ikke alle filer

Kode Konvensjoner

Testing Strategi

Hold CLAUDE.md oppdatert

Utdatert dokumentasjon

Farligere enn ingen

Samme med Claude

Alle AI råd er utdatert om 6 måneder

Lær prinsippene, ikke verktøyene

Migrere til stacken

Aldri skriv om fra Angular til React

Små skritt

Dependency pruning

Big bang rewrite

The single worst strategic mistake that any software company can make

Stopp maks 3 måneder

Neste feature betaler

Det du har er ofte bra nok

Du trenger mindre enn du tror

Jan Greger Hemb

JPro

Takk for meg 👋