Frameworks are rented. The platform is owned. jQuery taught us DOM manipulation, and the browser absorbed it into querySelector. Promise libraries taught us asynchrony, and the browser absorbed them into async/await. Every few years, a framework’s proudest feature becomes a native API, and the framework quietly deletes code.
That process has never moved faster than it does right now. In the last two years the browser shipped parent selectors, container queries, native nesting, view transitions, and scroll-driven animations — features an entire generation of developers assumed would always need JavaScript. Meanwhile TypeScript made strict mode the factory default and rewrote its compiler in Go for a 10x speedup. Part 2 is about this bedrock: what the platform gives you in mid-2026, and how to build on it directly before any framework enters the picture.
Why the platform outlives every framework
The practical argument is dependency half-life. A design system built on :has() and container queries will still be valid in ten years, because browsers almost never remove shipped features — the web’s backwards-compatibility contract is the strongest in software. The same system built on a utility library or an animation framework inherits that library’s release cadence, breaking changes, and eventual abandonment.
There is also a hiring-test argument that happens to be true: when an AI agent writes the first draft of a component, the person reviewing it needs to know what the browser can already do. Otherwise you merge 60 lines of JavaScript that reimplement a CSS selector.
Baseline: the compatibility contract
“Can I use this?” used to mean checking four browser versions by hand. In 2026 the answer is a single word: Baseline. A feature becomes Baseline Newly available when it works in the latest Chrome, Edge, Firefox, and Safari; it becomes Widely available after 30 months across all of them. MDN and Can I Use show the badges inline, so any API lookup ends with a clear yes or no.
Working rules:
- Widely available — use it unconditionally. Grid, container queries,
:has(), native nesting,Promise.withResolvers. - Newly available — ship it with progressive enhancement:
@supportsfallbacks for CSS, feature detection for JS. Scroll-driven animations and cross-page view transitions live here (Firefox’s support landed only partially in early 2026). - Not Baseline — experimental only. Temporal is the big one on the horizon.
Two Baseline features worth adopting immediately on content sites: content-visibility: auto, which lets the browser skip rendering offscreen sections (web.dev measured a 232ms → 30ms rendering cut on a long page), and <link rel="modulepreload">, which kills module dependency waterfalls.
HTML: semantics are the API
HTML in 2026 quietly absorbs components that used to require libraries. <dialog> gives you a modal with focus trapping, ::backdrop styling, and Esc-to-close. The popover attribute gives you tooltips and menus with top-layer rendering and light-dismiss, no portal code. <details> is an accessible accordion out of the box. Form validation — required, pattern, minlength, :user-invalid — runs without a line of JavaScript.
The discipline that matters has not changed: use elements for what they mean. A <button> that submits is keyboard-focusable, screen-reader-announced, and form-aware; a <div> with a click handler is none of those, and no ARIA attribute fully repays the difference. Semantic HTML is also the version of your page that search engines and LLM crawlers read most reliably — the machine audience now outnumbers the screen-reader audience, and it reads the same markup.
CSS grew up
Three structural features changed how stylesheets are written, and all three are Baseline Widely available today.
:has() is the parent selector we waited fifteen years for. It styles an element based on what is inside it — or after it. A form group that highlights when its input is focused, a card that changes layout only when it contains an image, a submit button that dims while any required field is empty: all pure CSS, zero event listeners. Teams report deleting hundreds of lines of class-toggling JavaScript per project.
Container queries decouple components from the viewport. With container-type: inline-size on a wrapper, a card responds to the width of the space it is in — sidebar, modal, or full-width column — instead of the screen. This killed the <Card layout="horizontal"> variant-prop pattern. One published design-system migration cut stylesheet size from 84 KB to 52 KB, a 38% reduction, largely from deleted media-query overrides.
Native nesting and modern color closed the Sass gap. Nesting, custom properties, color-mix(), and oklch() mean a new project in 2026 needs no CSS preprocessor for everyday work. This site, for example, is plain CSS with custom properties — the same variables drive both color themes from one declaration.
Motion and rendering: how pixels actually happen
Understanding why modern CSS motion is smooth requires knowing the pipeline. The browser parses HTML and CSS into the DOM and CSSOM, resolves them into a render tree, computes geometry in layout, rasterizes in paint, and assembles layers on the GPU in composite. Animating width or top re-runs layout and paint every frame; animating transform and opacity touches only the composite step.
On top of that pipeline, two APIs replaced whole categories of JavaScript:
- View transitions animate page navigations — including cross-document, MPA-style ones — with shared-element continuity. A thumbnail on a list page can morph into the hero of the detail page. Chrome and Safari have shipped this since 2024; Firefox is still completing support, so treat it as enhancement.
- Scroll-driven animations tie keyframes to scroll position via
animation-timeline: scroll()orview(), running entirely on the compositor. Parallax and reveal-on-scroll without IntersectionObserver, scroll listeners, or libraries like AOS. The non-negotiables: an@supportsfallback so unsupported browsers simply show the content, and aprefers-reduced-motionrule for users who ask for stillness.
The deletion list this enables: Sass for nesting-and-variables use, AOS/ScrollReveal, basic Popper.js tooltip positioning, and most of autoprefixer’s workload. Keep GSAP only for genuinely choreographed, gesture-driven, or physics-based motion.
JavaScript the language caught up
ES2024 and ES2025 filled the gaps that used to send people to utility libraries, and everything below is Baseline in 2026:
Object.groupBy/Map.groupBy— grouping collections without reduce gymnasticsPromise.withResolvers()— creating a promise you settle from the outside, no constructor-wrapper awkwardness- Iterator helpers —
.map(),.filter(),.take(),.drop()directly on iterators and generators, lazily evaluated - Set methods —
union,intersection,difference,isSubsetOf, finally Promise.try,RegExp.escape,Array.prototype.toSorted / toReversed / with(immutable updates), and JSON modules via import attributes
Temporal — the long-awaited replacement for Date — is still finishing standardization in mid-2026 and TypeScript 6.0 already ships its type definitions. Learn it when it lands; until then, Intl.DateTimeFormat covers locale formatting honestly.
The meta-lesson: before adding a dependency, search MDN first. In 2026 the answer is increasingly “the platform does that.”
The event loop is still the interview question
Every JavaScript runtime runs one loop: take one task (a setTimeout callback, an I/O event, a DOM event), run it to completion on the call stack, then drain the microtask queue completely — promise callbacks, queueMicrotask, MutationObserver — and only then maybe render, before taking the next task.
The two consequences that actually bite in production:
Promise.resolve().then(fn)always runs beforesetTimeout(fn, 0)— microtasks drain after the current task, timers wait for the next one.- A microtask that schedules itself forever starves rendering completely; a recursive
setTimeoutdoes not, because rendering happens between tasks. This is the difference between “page frozen” and “page merely slow.”
Framework schedulers, React’s concurrent rendering, and every loading spinner you will ever write are all negotiations with this loop.
TypeScript: strict by default, fast by Go
TypeScript’s 2026 story is two releases. TypeScript 6.0 (March 2026) was the last JavaScript-based compiler — and a deliberate spring cleaning: strict: true is now the default, ESM is the default module system, ES5 targets and moduleResolution: "classic" are gone, and ES2025 library types are built in. Strictness is no longer a team policy you argue for; it is the factory setting you argue to leave.
TypeScript 7.0 (RC, June 2026) is the Go-based port of the same compiler — a port, not a rewrite, so type-checking semantics are identical, but Microsoft’s benchmark on VS Code’s 1.5 million lines drops from 77.8s to 7.5s, with four parallel checker workers by default. The stable release is expected within weeks of this writing; tools that consume the programmatic API (typescript-eslint, ts-morph) should wait for 7.1. One more quietly important change: Node 24 can execute TypeScript files directly by stripping erasable types, which makes scripts and small tools a zero-build affair.
What TypeScript does not do is just as important: types are erased at compile time and never reach the runtime. Anything crossing a boundary — API responses, form input, environment variables — still needs runtime validation. That boundary is where Part 6 picks the problem back up.
Practice, then Part 3
Before moving on, prove the platform to yourself without a framework:
- Build one page of semantic HTML — header, nav, main, article, footer — styled with native nesting and custom properties, plus one card component driven by a container query that works in both a wide column and a narrow sidebar.
- Add a form whose validation states (focus, invalid, submittable) are styled entirely with
:has()and:user-invalid— no JavaScript. - Predict, then verify in DevTools, the log order of
setTimeoutvsPromise.thenvsqueueMicrotaskmixed in one script. - Initialize a project with
typescript@latest, confirmstrictis on by default, and feel how fasttsc --noEmitis on the 7.0 RC.
Part 3 builds React 19 on top of all of this — and you will recognize every piece: components are just functions, Server Components are just the rendering pipeline moved server-side, and Actions are the platform’s forms, upgraded.