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
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