Summary of Technology Strategy
CTO-friendly technology strategy contrasting the old way versus the AI-first new way.
Old way: stack sprawl driven by human-maintainability abstractions
[Channel] [Edge/Client] [Front‑end App] [API/Middleware] [Services] [Data]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Browsers, Mobile → SPA Runtime (React/Angular) → State Mgmt (Redux/MobX/Zustand) → BFF (Node/Java/Kotlin/.NET) → Business Services (microservices xN) → ORM(s) (Hibernate/EF/ActiveRec) → DB(s)
Apps, Integrations Polyfills, Routing, VDOM Client GraphQL/Apollo cache REST/GraphQL gateway, API composition Service mesh, circuit breakers Repository & Unit of Work patterns SQL/NoSQL, Search
Input validation duplication DTO mappers, validators + query builders + Cache clusters
Obs/Non‑Func Build chain: webpack/babel/tsc/eslint/stylelint; design system; CI templates; feature flag SDK; auth SDK; i18n; analytics SDK; error SDK; A/B SDK; test libs (Jest, RTL, Cypress, Playwright)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Cross‑cutting: secrets mgmt; service discovery; API gateways; schema registries; message brokers; CDC pipelines; ETL/ELT; data virtualization; object mappers; codegen; contract tests; blue/green; SRE playbooks
Blast radius of change
- Front‑end: component + hook + state + routing + cache + tests
- Back‑end: controller + service + mapper + ORM + migration + contract tests
- Non‑func: rebuilds, redeploy, re‑provision, update SDKs, docs
Debt drivers
- Abstractions piled to make human workflows tolerable
- Divergent duplication (validation, types, DTOs, mappers)
- Inert code: glue, config, and ceremony outnumbering domain logicWhat this shows
- Each box exists to ease human coordination: layers to “cleanly separate concerns,” SDKs to standardize patterns, caches to hide latency introduced by the layers, and meshes/gateways to tame the distributed complexity.
- Over time, the abstractions themselves become the product to maintain, creating persistent tech debt and upgrade drag.
New way: AI‑first, HTML‑native, thin server, direct data
[Channel] [Edge/Client] [Front‑end View] [Server Endpoints] [Data]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Browsers, Mobile, Integr. → ES Modules, Web Components → HTML templates + attributes (htmx, data-*) → Thin handlers (HTML/JSON) → Direct SQL / Text‑to‑SQL → DB(s), Search
CSS native features SSE/WebSocket streams (Datastar/htmx SSE) Input validation + auth in one place Parameterized queries + Cache if truly needed
Obs/Non‑Func No‑build or light build (optional) Accessibility, perf budgets, CSP enforced AI‑generated tests (E2E + contract) Migrations as SQL, reviewed by humans
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
AI roles in the loop: spec→code; attribute wiring; SQL generation; refactors; test synthesis; telemetry insertion; security linting; upgrade suggestions
Change surface
- Front‑end: edit HTML + attributes; optional small component
- Back‑end: one handler + one SQL; shared validation
- Non‑func: AI updates tests/telemetry; minimal rebuild/redeploy
Debt reducers
- Fewer layers; fewer SDKs; less glue
- Single source of truth for validation/authorization
- AI enforces standards and eliminates drift automaticallyWhat this removes
- SPA runtime, client state frameworks, client caches for most screens
- ORMs and mapping layers in favor of reviewed SQL
- Heavy API middleware in favor of simple handlers returning HTML fragments or JSON
- Large build chains in favor of ES modules and “no‑build” where possible
What this keeps (only where justified)
- Web Components for genuine encapsulation
- SSE/WebSockets for real‑time requirements
- A small cache or queue when the domain, not the stack, demands it
Mermaid version (drop into docs)
Old way
flowchart LR
subgraph Channel[Channels]
A[Browsers / Mobile / Integrations]
end
subgraph Edge[Edge / Client]
B[SPA Runtime<br/>(React/Angular/Vue)]
C[Routing + VDOM + Polyfills]
D[Client State Mgmt<br/>(Redux/MobX/Apollo Cache)]
E[Build Chain<br/>(webpack/babel/tsc)]
end
subgraph FE[Front‑end App]
F[Design System / Components]
G[Feature Flags / i18n / Analytics SDKs]
H[Error + A/B Testing SDKs]
I[UI Tests (Jest/RTL/Cypress)]
end
subgraph API[API / Middleware]
J[BFF / API Gateway<br/>(REST/GraphQL)]
K[Input Validation (duplication)]
L[DTO Mappers]
end
subgraph SVC[Services]
M[Microservices xN]
N[Service Mesh / Circuit Breakers]
end
subgraph Data[Data Access]
O[ORMs (Hibernate/EF/ActiveRec)]
P[Query Builders / Repositories]
Q[Databases / Search / Cache]
end
A --> B --> C --> D --> F
E --> B
F --> G --> H --> I --> J
D --> J
J --> K --> L --> M --> N --> O --> P --> QNew way
flowchart LR
subgraph Channel[Channels]
A[Browsers / Mobile / Integrations]
end
subgraph Edge[Edge / Client]
B[ES Modules]
C[Web Components (as needed)]
D[CSS Grid/Flexbox/Vars]
end
subgraph View[Front‑end View]
E[Semantic HTML Templates]
F[htmx/data-* attributes]
G[SSE/WebSocket Streams<br/>(Datastar/htmx SSE)]
end
subgraph Server[Thin Server Endpoints]
H[Handlers returning HTML fragments or JSON]
I[Centralized Auth + Validation]
J[AI‑generated Tests + Telemetry]
end
subgraph Data[Direct Data]
K[Direct SQL / Text‑to‑SQL]
L[Parameterized Queries]
M[Databases / Search / Cache (if needed)]
end
A --> B --> C --> E
D --> E
E --> F --> H
G --> E
H --> I --> K --> L --> M
J -. monitors .- HNarrative to accompany the diagram
-
Old way: every layer exists to make human work “maintainable.” Over time, the layers accrete: client state to tame async, API gateways to shape contracts, ORMs to hide SQL, builders to juggle tooling, SDKs to standardize cross‑cutting. Each layer adds its own lifecycle, configuration, and failure modes. Complexity increases linearly per feature and exponentially with integration points, creating chronic tech debt.
-
New way: we bias toward the native platform and let AI absorb the toil that those layers once justified. HTML is the contract; attributes are behavior; SSE streams carry change; handlers are small and testable; SQL is explicit and reviewed. Complexity grows with the domain, not with the stack. Tech debt decelerates because there are fewer abstractions to drift and the AI continuously refactors toward your standards.
Optional callouts for a slide
- Complexity driver: “layers for humans” → ceremony exceeds domain logic
- AI-first antidote: “intent over infrastructure” → attributes + thin handlers + direct SQL
- Measurables: dependency count, JS KB shipped, median RTT per action, time-to-spec → PR, time-to-fix, percent of tests auto‑maintained
If you want, I can drop these into a one-page PDF and a slide-ready SVG with your color palette next.
How is this guide?
Last updated on