AI-assisted engineering • 2026

2026 web development:
Dissecting the AI SDLC

Prototype in vanilla. Harden in a framework.

When domain boundaries and API contracts are explicit, HTML, CSS, and vanilla JavaScript can become an executable reference implementation. Coding agents can then migrate that known behavior into a production framework under testing, security, architecture, and dependency constraints.

The core idea

Separate exploration from hardening.

Instead of using a frontend framework to discover what the application should be, establish the behavior first. Treat the vanilla frontend as a POC and discovery spike against the backend contract, not as a finished product — the framework then becomes a production migration target, and migration is also where the production design system gets applied. Converting a working first-principles prototype into that design system, rather than asking an agent to write directly in the framework from scratch, is what surfaces the framework's own gaps and keeps the agent from misusing its patterns.

At a glance

The AI SDLC as a reference-first workflow

FastAPI owns the domain. The vanilla frontend makes browser behavior explicit. Coding agents then migrate that behavior into a constrained production target — including the production design system itself, which is where framework and component-library deficiencies actually surface.

Domain / API contract

FastAPI application

DDD / bounded contexts

Explicit API contracts

Business logic

Reference frontend

HTML + CSS + Vanilla JS

Minimal dependencies

Explicit browser/API edges

Executable specification

Agent migration

Translate behavior

Apply production design system

Preserve contracts and tests

Surface framework gaps

Production targets
Next.js React / product target
Nuxt Vue / migration target
Angular Hardening target
Validate → Harden → Release

Same behavioral tests • security analysis • dependency governance • CDN-ready frontend

Framework comparison

Fit for vanilla → framework migration

Architectural assessment for a FastAPI/DDD application using a vanilla reference frontend. Scores are comparative judgments, not benchmark measurements.

Fit for vanilla to framework migration Comparison of Next.js, Nuxt and Angular for migration from vanilla JavaScript, security defaults, architectural enforcement, minimal package potential and agent migration determinism. 0 2.5 5 7.5 10 Next.js Nuxt Angular Migration from vanilla Security defaults Architectural enforcement Minimal-package potential Agent migration determinism 10 = particularly strong fit
Reference-first FastAPI / DDD frontend comparison
Criterion Vanilla seed Next.js Nuxt Angular
Rapid prototype ★★★★★ ★★★ ★★★★ ★★
Explicit browser behavior ★★★★★ ★★★ ★★★★ ★★★
Easy for agent to understand ★★★★★ ★★★ ★★★★ ★★★★
Migration from vanilla ★★★★ ★★★★½ ★★★
Framework security defaults ★★ ★★★★ ★★★★ ★★★★★
Architectural enforcement ★★★ ★★★★ ★★★★★
DDD compatibility ★★★★★ ★★★★ ★★★★ ★★★★★
Minimal-package potential ★★★★★ ★★★ ★★★★ ★★★★
Static/CDN deployment ★★★★★ ★★★★★ ★★★★★ ★★★★★
Full-stack capability ★★★★★ ★★★★★ ★★★★
Framework complexity Very low High Medium High
Agent migration determinism Medium High High
Long-term structural consistency Depends on you Medium High Very high

These are architectural assessments for this workflow, not measured benchmark scores.

The argument

Start with the domain, not the framework

Modern frontend development often begins with a framework decision: React or Vue, Next.js or Nuxt, Angular, a state manager, a component library, and then another layer of packages around those choices.

For a FastAPI application with well-defined domain boundaries, that can be the wrong place to begin.

Let FastAPI own application behavior

Domain-driven design makes a much simpler starting point possible. FastAPI can own application services, business rules, persistence, integrations, and explicit API contracts. The frontend then becomes a presentation implementation consuming those contracts.

The vanilla frontend is not necessarily throwaway code

A working HTML, CSS, and vanilla JavaScript implementation can capture expected browser behavior, DOM interactions, API calls, accessibility expectations, and regression tests. It becomes a specification that runs.

That changes the coding-agent task. Instead of asking an agent to design and implement an application in a framework at the same time, the agent can be asked to reproduce known behavior while preserving contracts, tests, architectural boundaries, and dependency constraints.

The reference frontend is also a UI/UX handoff artifact

A working vanilla prototype does more than prove the backend contract — it's something a designer or UI/UX engineer can actually pick up and treat as a starting point instead of a description of one. That handoff used to be lossy: a static mockup, or a prototype built in a different tool entirely, still had to be reimplemented from scratch by engineering, so the prototype's only real job was communication, never code.

A running, contract-backed vanilla frontend changes that. Branding, A/B testing different content flows, and optimizing a sales funnel can all happen directly against real, working behavior instead of a description of it. That's the actual handoff point between a POC and discovery spike on the backend and the frontend polish that creates the experience an end user is meant to have.

That first-principles constraint has a second effect worth naming directly: it changes what happens when a coding agent later converts the prototype into a production design system — Tailwind, a component library, whatever the target stack standardizes on. Asked to write directly in that design system from scratch, with no first-principles reference to build against, an agent has no concrete ground truth for what the interface is actually supposed to do, so it improvises within the framework's own idioms — and the result is often technically valid CSS that's still structurally inconsistent and hard to untangle later. Migrating a working vanilla prototype instead gives the agent a known-correct target to reconcile against the design system's real capabilities. That reconciliation is exactly where a design system's own gaps surface, and where the agent is least likely to misuse its patterns, because the migration doesn't get thrown away at the framework boundary the way a design mockup usually would — it's the same deterministic-migration property, applied to CSS instead of behavior.

Coding agents change the economics of framework structure

Framework boilerplate historically represented developer time. In an agent-assisted SDLC, the agent can absorb much of that repetitive translation cost. Framework structure can therefore become useful as a production constraint rather than a tax paid during early experimentation.

Optional detail

Open only what you need

The central argument above stands on its own. The sections below contain implementation details, framework tradeoffs, and DevSecOps considerations for readers who want to go deeper.

01 Next.js — the React product target

Next.js remains a strong destination when React itself provides meaningful product value: its component ecosystem, sophisticated composition, server rendering, static generation, or React Server Components.

Vanilla                       Next.js

HTML                →         JSX
DOM events          →         React events
JavaScript state    →         React state
fetch()             →         data fetching
pages               →         routes / layouts
functions           →         components / hooks

The architectural concern in a FastAPI application is backend duplication.

Preferred:

FastAPI
   ↓
API contract
   ↓
Next presentation


Possible drift:

FastAPI
   ↕
Next server
   ↕
React client

If FastAPI owns the domain and application layers, that boundary should remain explicit during migration. Next server capabilities should not quietly become a second implementation of the backend simply because the framework makes them convenient.

02 Nuxt — possibly the most natural migration target

Nuxt becomes particularly interesting when the reference implementation already uses HTML, CSS, JavaScript, and Vite.

HTML       → template
CSS        → style
JavaScript → script setup

The conceptual translation from ordinary HTML into Vue templates is relatively direct.

PROTOTYPE

HTML
CSS
JavaScript
Vite


      ↓ agent migration


PRODUCTION

Vue
Nuxt
Vite
Nitro

The architecture becomes more capable without replacing every part of the development toolchain. This smaller conceptual distance may also make automated migrations easier to reason about and review.

03 Angular — the hardening target

Angular presents a different proposition. It is not being selected because it makes initial experimentation faster. It is interesting because a coding agent can translate an already-understood application into a more constrained production representation.

             DRAFT
               │
               ▼
     HTML / CSS / Vanilla JS
               │
               ▼
        Behavior works
               │
               ▼
      Contracts stabilize
               │
               ▼
            HARDEN
               │
       ┌───────┴────────┐
       │                │
    Angular          DevSecOps
       │                │
  strict TS           SAST
  templates           SBOM
  structure           dependency scan
  DI                  security tests
       │                │
       └───────┬────────┘
               ▼
             RELEASE

Strict TypeScript, dependency injection, structured conventions, template security mechanisms, and recognizable escape hatches become more interesting when an agent is paying much of the boilerplate cost.

04 Make dangerous code obvious

Agent-generated code introduces a useful DevSecOps opportunity: constructs that cross sensitive security boundaries can become explicit review triggers rather than ordinary generated code.

bypassSecurityTrustHtml
bypassSecurityTrustScript
bypassSecurityTrustStyle
bypassSecurityTrustUrl
bypassSecurityTrustResourceUrl

innerHTML
direct DOM manipulation
dynamic template construction
unsafe-inline CSP
new third-party dependency

The presence of one of these constructs does not automatically mean the implementation is wrong. It means the implementation crossed a boundary that warrants additional inspection.

Agent migration
      │
      ▼
Framework build
      │
      ▼
AST / policy analysis
      │
      ▼
Security escape hatch?
      │
   ┌──┴──┐
   │     │
  NO    YES
   │     │
   ▼     ▼
continue  review
05 Package count is a security decision

Framework security and software supply-chain security are different problems. A secure framework underneath a large set of unnecessary transitive dependencies does not automatically produce a secure application.

Need a capability
Can the browser provide it?
↓ no
Can the framework provide it?
↓ no
Is an approved dependency already available?
↓ no
Can it reasonably be implemented without another package?
↓ no
Dependency security review
Review:

vulnerability history
maintainer health
transitive dependencies
install scripts
license
actual necessity

The objective is not zero dependencies. The objective is intentional dependencies. npm install becomes a small architectural decision instead of the automatic first response to a missing capability.

06 Test the migration, not the framework

The reference implementation makes it possible to evaluate these frameworks using the actual development methodology rather than generic framework rankings.

                Vanilla Reference
                       │
          ┌────────────┼────────────┐
          ▼            ▼            ▼
       Next.js        Nuxt       Angular
          │            │            │
          └────────────┼────────────┘
                       ▼
                  Measurements
Migration LOC Dependency count Bundle size Agent corrections Security findings Build complexity Behavioral failures Transitive dependencies Deploy complexity

The same moderately complicated vanilla feature can be migrated into each target using the same rules and behavioral tests. The result provides evidence about which architecture best fits the actual SDLC.

07 Frameworks as compilation targets

There is a larger idea underneath this workflow. Coding agents may change the role of application frameworks.

Human + agent exploration

HTML
CSS
JavaScript
HTTP
FastAPI

        ↓

behavioral contract

        ↓

migration agent

        ↓

┌────────────┬────────────┬────────────┐
│            │            │            │
▼            ▼            ▼            │
Next.js     Nuxt        Angular        │
React       Vue         strict TS      │
RSC         Vite        structure      │
ecosystem   Nitro       sanitization   │
│            │            │            │
└────────────┴─────┬──────┴────────────┘
                   ▼
              verification
                   │
                   ▼
                 release

Complexity during exploration can obscure the problem because the developer is simultaneously trying to understand the product and satisfy a framework.

Complexity during hardening can be useful when that complexity represents explicit constraints that can be automatically verified.

The 2026 mindset

Prototype for understanding. Migrate for production. Verify the difference.

The best framework may depend not only on what application is being built, but on where in the software-development lifecycle the framework enters the system. HTML, CSS, JavaScript, HTTP, and FastAPI can remain powerful tools for discovering behavior, with branding, A/B testing, and sales-funnel decisions made directly against that proven behavior instead of a static mockup; and Next.js, Nuxt, and Angular can become increasingly constrained migration targets — the same migration step that applies the production design system and surfaces where it falls short.

Dependency-free HTML/CSS article — native browser <details> elements provide progressive disclosure without adding a JavaScript package.