{t}
; } ``` **App:** ```tsx export default async function Page() { const t = Date.now(); return{t}
; } ``` ## ⚠️ Pitfalls [#️-pitfalls] * Mixing both routers works but doubles mental models — document boundaries. * Hooks require `'use client'` in App Router — easy to forget. * Caching defaults in App Router surprise Pages veterans — learn `no-store` / revalidate. ## 🔗 Related [#-related] * [Next.js/app\_router.md](/docs/comparisons/../next.js/app-router) * [Next.js/pages\_router.md](/docs/comparisons/../next.js/pages-router) * [Next.js/server\_components.md](/docs/comparisons/../next.js/server-components) * [README.md](/docs/comparisons) # pathlib vs os.path (/docs/comparisons/pathlib-vs-os) # pathlib vs os.path [#pathlib-vs-ospath] *Comparisons · Reference cheat sheet* *** ## 📋 Overview [#-overview] Choose **pathlib** for most new Python path logic (object-oriented, readable). Use **os.path** / `os` when maintaining legacy code or needing specific `os` side effects (cwd, env, process). ## 🔧 Core concepts [#-core-concepts] | Dimension | pathlib | os / os.path | | -------------- | -------------------------- | ---------------------------- | | Style | Objects (`Path`) | Strings | | Join | `/` operator, `joinpath` | `os.path.join` | | Exists / mkdir | `path.exists()`, `mkdir()` | `os.path.exists`, `os.mkdir` | | Glob | `path.glob` / `rglob` | `glob.glob` | | Read/write | `read_text` / `write_text` | open + join paths | | Best for | New code, clarity | Legacy, thin wrappers | **When to use pathlib:** new scripts, apps, anything that manipulates many paths. **When to use os.path:** drop-in maintenance, or APIs that already require strings and `os.*` process calls. ## 💡 Examples [#-examples] **pathlib:** ```python from pathlib import Path root = Path.cwd() / "data" root.mkdir(parents=True, exist_ok=True) for p in root.glob("*.csv"): print(p.read_text(encoding="utf-8")[:80]) ``` **os.path:** ```python import os root = os.path.join(os.getcwd(), "data") os.makedirs(root, exist_ok=True) for name in os.listdir(root): if name.endswith(".csv"): path = os.path.join(root, name) with open(path, encoding="utf-8") as f: print(f.read(80)) ``` ## ⚠️ Pitfalls [#️-pitfalls] * Mixing `Path` and strings casually works often (`os.fspath`) but be consistent at API boundaries. * `Path` on Windows vs POSIX differs for anchors — test both if you ship cross-platform. * `os.path` won't stop you from forgetting `exist_ok` / parents the way pathlib habits encourage. ## 🔗 Related [#-related] * [Python/os.md](/docs/comparisons/../python/os) (if present) * [Python/getting\_started.md](/docs/comparisons/../python/getting-started) * [README.md](/docs/comparisons) # pytest vs unittest (/docs/comparisons/pytest-vs-unittest) # pytest vs unittest [#pytest-vs-unittest] *Comparisons · Reference cheat sheet* *** ## 📋 Overview [#-overview] **pytest** is the common default for modern Python tests (fixtures, parametrize, assert rewriting). **unittest** is the stdlib xUnit-style framework — fine for stdlib-only environments and legacy suites. ## 🔧 Core concepts [#-core-concepts] | Dimension | pytest | unittest | | ----------- | -------------------------- | -------------------- | | Install | Third-party | Stdlib | | Assertions | Plain `assert` | `self.assertEqual`… | | Fixtures | Elegant `@pytest.fixture` | `setUp` / `tearDown` | | Parametrize | `@pytest.mark.parametrize` | More boilerplate | | Plugins | Rich ecosystem | Limited | | Discovery | `test_*.py` conventions | `unittest` discovery | **When to use pytest:** almost all application and library projects. **When to use unittest:** zero-dependency constraints, teaching stdlib, or extending large existing unittest suites. ## 💡 Examples [#-examples] **pytest:** ```python import pytest @pytest.fixture def n(): return 2 @pytest.mark.parametrize("x,y", [(1, 2), (2, 4)]) def test_double(x, y, n): assert x * n == y ``` **unittest:** ```python import unittest class DoubleTest(unittest.TestCase): def test_double(self): self.assertEqual(2 * 2, 4) if __name__ == "__main__": unittest.main() ``` ## ⚠️ Pitfalls [#️-pitfalls] * Mixing styles in one repo without guidance confuses contributors — pick a default. * pytest plugin overload can obscure failures — keep conftest lean. * unittest mock (`unittest.mock`) works great *with* pytest too. ## 🔗 Related [#-related] * [Pytest/](../Pytest/) * [Python/getting\_started.md](/docs/comparisons/../python/getting-started) * [README.md](/docs/comparisons) # Redis vs Postgres (/docs/comparisons/redis-vs-postgres) # Redis vs Postgres [#redis-vs-postgres] *Comparisons · Reference cheat sheet* *** ## 📋 Overview [#-overview] **Postgres** is a durable relational system of record. **Redis** is an in-memory data structure server optimized for speed, caching, ephemeral state, and specialized structures. Often used together, not as mutual substitutes. ## 🔧 Core concepts [#-core-concepts] | Dimension | Redis | Postgres | | ----------------- | -------------------------- | -------------------------------- | | Primary store? | Usually no (cache/session) | Yes (SoR) | | Durability | Optional RDB/AOF | WAL + strong durability defaults | | Query model | Keys + data structures | SQL + relational model | | Latency | Sub-ms in-memory | Low ms; disk-backed | | Relations / joins | DIY | First-class | | Memory cost | Entire working set in RAM | Buffer cache + disk | **When to use Redis:** cache, rate limits, sessions, leaderboards, pub/sub, queues (or Streams). **When to use Postgres:** authoritative business data, complex queries, transactions, constraints. ## 💡 Examples [#-examples] **Redis cache aside:** ```shellscript GET user:42 # miss → load from Postgres → SET user:42 … EX 300 ``` **Postgres source of truth:** ```sql SELECT id, email FROM users WHERE id = 42; ``` ## ⚠️ Pitfalls [#️-pitfalls] * Using Redis as the only database without HA/persistence for critical data. * Caching without invalidation strategy serves stale Postgres data forever. * Storing huge blobs in Redis blows RAM — keep hot, small keys. ## 🔗 Related [#-related] * [Redis/getting\_started.md](/docs/comparisons/../redis/getting-started) * [Postgres/getting\_started.md](/docs/comparisons/../postgres/getting-started) * [Redis/expiry\_ttl.md](/docs/comparisons/../redis/expiry-ttl) * [README.md](/docs/comparisons) # Tailwind vs hand-written CSS (/docs/comparisons/tailwind-vs-css) # Tailwind vs hand-written CSS [#tailwind-vs-hand-written-css] *Comparisons · Reference cheat sheet* *** ## 📋 Overview [#-overview] **Tailwind** accelerates UI via utility classes and a shared design scale. **Hand-written CSS** (or CSS Modules / plain stylesheets) offers full control and fewer markup classes. Many teams mix: Tailwind for app UI, custom CSS for complex animations or third-party overrides. ## 🔧 Core concepts [#-core-concepts] | Dimension | Tailwind | Hand-written CSS | | ------------------ | ----------------------- | --------------------------- | | Speed of iteration | Very fast for common UI | Slower unless well-factored | | Bundle discipline | Scans used classes | Depends on your imports | | Readability | Busy class strings | Centralized selectors | | Design consistency | Theme tokens by default | You must enforce tokens | | Learning curve | Utility vocabulary | CSS cascade/specificity | | Dynamic theming | Variants + CSS vars | Full freedom | **When to use Tailwind:** product UIs, design systems with utility tokens, rapid component work. **When to use CSS:** intricate animations, unique marketing layouts, existing CSS architecture, or teams that dislike utilities-in-markup. ## 💡 Examples [#-examples] **Tailwind:** ```html ``` **CSS:** ```css .button { border-radius: 0.375rem; background: #18181b; padding: 0.5rem 0.75rem; font-size: 0.875rem; color: white; } .button:hover { background: #3f3f46; } ``` ## ⚠️ Pitfalls [#️-pitfalls] * Tailwind without content paths generates empty CSS. * Hand-written CSS without conventions recreates a one-off design system by accident. * `@apply` everywhere reintroduces the problems utilities were meant to solve. ## 🔗 Related [#-related] * [Tailwind/getting\_started.md](/docs/comparisons/../tailwind/getting-started) * [CSS/](../CSS/) * [README.md](/docs/comparisons) # useEffect vs useLayoutEffect (/docs/comparisons/useeffect-vs-uselayouteffect) # useEffect vs useLayoutEffect [#useeffect-vs-uselayouteffect] *Comparisons · Reference cheat sheet* *** ## 📋 Overview [#-overview] Both React hooks run after render from side-effect logic. **useLayoutEffect** fires synchronously after DOM mutations before paint; **useEffect** fires after paint. Prefer `useEffect` unless you must measure/mutate DOM before the user sees a frame. ## 🔧 Core concepts [#-core-concepts] | Dimension | useEffect | useLayoutEffect | | -------------- | ----------------------------- | ------------------------------------------ | | Timing | After paint | Before paint (sync) | | Blocking | Non-blocking paint | Can delay paint | | SSR | OK (warns if misused) | Warning on server — often gate | | Typical use | Fetch, subscriptions, logging | DOM measure, scroll lock, tooltip position | | Default choice | Yes | Only when needed | **When to use useEffect:** data loading, event listeners, integrating non-React libs that can wait a frame. **When to use useLayoutEffect:** avoid flicker when reading layout (`getBoundingClientRect`) and synchronously updating state/DOM. ## 💡 Examples [#-examples] **useEffect (fetch):** ```tsx useEffect(() => { let cancelled = false; fetch("/api").then(async (r) => { const data = await r.json(); if (!cancelled) setData(data); }); return () => { cancelled = true; }; }, []); ``` **useLayoutEffect (measure):** ```tsx useLayoutEffect(() => { const rect = ref.current?.getBoundingClientRect(); if (rect) setWidth(rect.width); }, [deps]); ``` ## ⚠️ Pitfalls [#️-pitfalls] * Putting heavy work in `useLayoutEffect` janks the UI. * `useLayoutEffect` on the server warns — use `useEffect` or client-only components. * Neither replaces data libraries (react-query) for complex fetching. ## 🔗 Related [#-related] * [React/](../React/) * [Next.js/server\_components.md](/docs/comparisons/../next.js/server-components) * [README.md](/docs/comparisons) # Docker Compose (/docs/docker/compose) # Docker Compose [#docker-compose] *Docker · Reference cheat sheet* *** ## 📋 Overview [#-overview] Compose defines multi-service stacks in YAML: web, db, redis, networks, and volumes with one `docker compose up`. ## 🔧 Core concepts [#-core-concepts] | Key | Role | | -------------------------- | ---------------------------- | | `services` | Containers to run | | `images` / `build` | Prebuilt vs local Dockerfile | | `ports` | `host:container` publish | | `environment` / `env_file` | Config | | `volumes` | Persist or share data | | `networks` | Service DNS names | | `depends_on` | Start order (not readiness) | | Command | Purpose | | ------------------------ | -------------- | | `docker compose up -d` | Start detached | | `docker compose down` | Stop + remove | | `docker compose logs -f` | Follow logs | | `docker compose ps` | Status | ## 💡 Examples [#-examples] **Minimal stack:** ```yaml services: web: build: . ports: - "9000:9000" environment: DATABASE_URL: postgres://postgres:postgres@db:5432/app depends_on: - db db: image: postgres:16-alpine environment: POSTGRES_PASSWORD: postgres volumes: - pgdata:/var/lib/postgresql/data volumes: pgdata: ``` **Rebuild one service:** ```shellscript docker compose up -d --build web ``` ## ⚠️ Pitfalls [#️-pitfalls] * `depends_on` does not wait for DB ready — use healthchecks + `condition: service_healthy`. * Host `localhost` inside a container is the container itself — use service names (`db`). * Old `docker-compose` (hyphen) CLI differs from `docker compose` plugin — prefer the plugin. ## 🔗 Related [#-related] * [networks.md](/docs/docker/networks) * [volumes.md](/docs/docker/volumes) * [healthchecks.md](/docs/docker/healthchecks) * [env\_secrets.md](/docs/docker/env-secrets) # Dockerfile (/docs/docker/dockerfile) # Dockerfile [#dockerfile] *Docker · Reference cheat sheet* *** ## 📋 Overview [#-overview] A Dockerfile is a sequence of instructions that build an image layer by layer. Order matters for cache efficiency. ## 🔧 Core concepts [#-core-concepts] | Instruction | Role | | -------------------- | -------------------------------- | | `FROM` | Base image | | `WORKDIR` | Set working directory | | `COPY` / `ADD` | Add files (`COPY` preferred) | | `RUN` | Execute build commands | | `ENV` / `ARG` | Runtime env / build args | | `EXPOSE` | Document port (does not publish) | | `USER` | Switch user | | `CMD` / `ENTRYPOINT` | Default process | | Cache tip | Practice | | -------------------- | --------------------------------------- | | Copy lockfiles first | Reuse `npm ci` / `pip` layers | | Fewer layers | Combine related `RUN`s when it helps | | `.dockerignore` | Exclude `node_modules`, `.git`, secrets | ## 💡 Examples [#-examples] **Node app sketch:** ```dockerfile FROM node:22-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev COPY . . USER node EXPOSE 9000 CMD ["node", "server.js"] ``` **Build args:** ```dockerfile ARG NODE_ENV=production ENV NODE_ENV=$NODE_ENV ``` **`.dockerignore`:** ``` node_modules .git .env Dockerfile* ``` ## ⚠️ Pitfalls [#️-pitfalls] * `ADD` auto-extracts archives and can fetch URLs — surprising; prefer `COPY`. * Secrets in `RUN` lines leak into image history — use BuildKit secret mounts. * `CMD` vs `ENTRYPOINT` confusion: know exec-form JSON arrays vs shell form. ## 🔗 Related [#-related] * [multi\_stage.md](/docs/docker/multi-stage) * [images\_tags.md](/docs/docker/images-tags) * [env\_secrets.md](/docs/docker/env-secrets) * [getting\_started.md](/docs/docker/getting-started) # Env & Secrets (/docs/docker/env-secrets) # Env & Secrets [#env--secrets] *Docker · Reference cheat sheet* *** ## 📋 Overview [#-overview] Pass configuration with environment variables and inject secrets without baking them into image layers. Prefer runtime secrets over `Dockerfile ENV` for credentials. ## 🔧 Core concepts [#-core-concepts] | Mechanism | Use | | -------------------- | ----------------------------------------------------- | | `ENV` | Non-secret defaults in image | | `ARG` | Build-time only (still visible in history if misused) | | `-e` / `environment` | Runtime env | | `env_file` | File of KEY=VAL | | BuildKit `--secret` | Secret mounts during build | | Orchestrator secrets | Swarm/K8s/Compose secrets | ## 💡 Examples [#-examples] **Runtime env:** ```shellscript docker run --rm -e DATABASE_URL="$DATABASE_URL" myapp:1.0.0 ``` **Compose env\_file:** ```yaml services: api: env_file: - .env environment: NODE_ENV: production ``` **BuildKit npm token (sketch):** ```dockerfile # syntax=docker/dockerfile:1 RUN --mount=type=secret,id=npm,target=/root/.npmrc npm ci ``` ```shellscript docker build --secret id=npm,src=$HOME/.npmrc -t myapp . ``` ## ⚠️ Pitfalls [#️-pitfalls] * `ENV SECRET=...` in a Dockerfile is recoverable from image history. * Committing `.env` with production credentials is a common breach path. * `docker history` and layer caching can retain leaked build args. ## 🔗 Related [#-related] * [dockerfile.md](/docs/docker/dockerfile) * [compose.md](/docs/docker/compose) * [multi\_stage.md](/docs/docker/multi-stage) * [getting\_started.md](/docs/docker/getting-started) # Getting Started with Docker (/docs/docker/getting-started) # Getting Started with Docker [#getting-started-with-docker] *Docker · Reference cheat sheet* *** ## 📋 Overview [#-overview] Docker packages apps and dependencies into images and runs them as containers. Use it for reproducible environments, local stacks, and deployment units. ## 🔧 Core concepts [#-core-concepts] | Idea | Meaning | | ---------- | ----------------------------------------- | | Image | Immutable filesystem + metadata template | | Container | Running (or stopped) instance of an image | | Dockerfile | Build recipe for an image | | Registry | Image store (Docker Hub, GHCR, …) | | Compose | Multi-container app definition | | Command | Purpose | | ---------------- | ------------------------ | | `docker version` | Client/server versions | | `docker pull` | Download image | | `docker run` | Create + start container | | `docker ps` | List running containers | | `docker build` | Build from Dockerfile | ## 💡 Examples [#-examples] **Run nginx:** ```shellscript docker run --rm -p 8080:80 nginx:alpine ``` **Build and run:** ```shellscript docker build -t myapp:dev . docker run --rm -p 9000:9000 myapp:dev ``` **Shell into a container:** ```shellscript docker exec -it