Type something to search...
Nextjs API Components

Nextjs API Components

Every React framework eventually ends up shipping its own set of "special" components — the ones that aren't quite ordinary JSX, because they're doing something the framework specifically knows how to optimize. Next.js has five of these: Font, Form, Image, Link, and Script. If you've spent any time in an App Router codebase, you've almost certainly reached for next/image or next/link without thinking twice about why they exist instead of a plain <img> or <a>.

This article is the map, not the territory. Each of these five components has its own dedicated, much longer write-up elsewhere on this blog covering its full API surface, edge cases, and gotchas. What's worth doing here is stepping back and asking a more useful question: what actually earns a component the label "built-in" in Next.js, and why does it matter that these particular five got that treatment instead of being left to userland libraries or native HTML?

What Makes a Component "Built-In"

A built-in Next.js component isn't just a convenience wrapper. In every one of these five cases, the component is solving a problem that genuinely can't be solved well with a plain HTML tag alone, because the fix requires cooperation from the build pipeline, the server, or the runtime — not just clever prop-passing in the browser.

Consider what a plain <img src="/hero.png" /> actually does: it tells the browser to fetch that exact file, at its exact dimensions, with no resizing, no format negotiation, and no lazy-loading unless you hand-roll it. The browser has no idea that a WebP version half the size would look identical, or that this image is 800px below the fold and doesn't need to block anything. next/image exists because that information — "this image can be resized, reformatted, and deferred" — has to be known and acted on somewhere between build time and request time, and a static <img> tag has no mechanism for that conversation to happen.

The same pattern shows up in every one of the other four:

  • Font needs to intercept a @font-face declaration at build time, self-host the actual font files, and inject preload and size-adjust hints before the browser ever asks for a font — none of which a <link> tag to Google Fonts can do without shipping a render-blocking external request.
  • Form needs to know it's inside an App Router route so it can prefetch the destination page in the background and update the URL client-side after a plain HTML <form> submission, instead of forcing a full-page reload.
  • Image needs a request-time or build-time image optimization service sitting behind it, resizing and re-encoding images on demand — logic a static tag simply has nowhere to live.
  • Link needs to know about the App Router's route tree well enough to prefetch a destination route's code and data before the user even clicks, something a plain <a> has no concept of.
  • Script needs to know about the page lifecycle — hydration, interactivity, idle time — well enough to schedule a third-party <script> tag at exactly the right moment instead of blindly wherever it's placed in the JSX tree.

Every single one of these requires the framework itself to be involved, either at build time (bundling, static analysis) or at runtime (the router, the server). That's the real dividing line between "built-in component" and "component someone could write themselves in userland": it needs privileged access to something React alone doesn't expose.

Why Not Just Use a Third-Party Library?

For every one of these five, a userland equivalent already existed before Next.js shipped its own version — react-helmet for fonts and head tags, react-lazy-load-image-component for images, react-router's Link, dozens of "load this script async" utility hooks. So why does Next.js bother maintaining its own?

The honest answer is that a third-party library, by definition, sits outside the framework's build pipeline and server runtime. It can approximate what these built-ins do, but it's always working with less information. A third-party lazy-loading image library doesn't know your next.config.js image domains allowlist. A third-party font loader doesn't know which routes will be statically generated and which won't, so it can't guarantee the font is available before first paint. A third-party router link doesn't have access to the App Router's internal route manifest, so its "prefetching" is really just a fetch call it's guessing about, not a genuine integration with the framework's data-fetching layer.

None of this makes third-party alternatives useless — plenty of teams still reach for a CMS-specific image component or a custom router abstraction for good reasons specific to their stack. But it does mean that, for the common case, the built-in components will consistently outperform a generic equivalent, because they're not guessing at the framework's internals from the outside — they are part of the framework's internals.

A Fast Comparison of What Each One Solves

If you're deciding which of the five deep-dive articles to read first, here's the one-sentence version of each:

Font (next/font) — solves layout shift and slow font loading by self-hosting Google Fonts or local font files and computing fallback metrics automatically, so text doesn't visibly jump when the real font finishes loading.

Form (next/form) — solves the "full page reload on every search bar submit" problem by making a plain HTML form behave like a client-side navigation, complete with prefetching of the target page.

Image (next/image) — solves oversized, unoptimized images by automatically resizing, reformatting, and lazy-loading images, plus reserving layout space to prevent shift while the image loads.

Link (next/link) — solves slow perceived navigation by prefetching a route's JavaScript and data ahead of a click, so the actual click feels instantaneous.

Script (next/script) — solves third-party scripts blocking the main thread by giving you explicit control over when a script loads relative to the page becoming interactive.

A Practical Note the Docs Don't Spell Out: These Compose

One thing that's easy to miss when you're learning these one at a time is that they're designed to be used together, not in isolation. A typical marketing page in a real App Router project might use all five in the same layout: Font in the root layout for typography, Image for the hero and product photos, Link for internal navigation, Form for a newsletter signup, and Script for the analytics tag at the bottom of the page. None of them conflict with each other, and none of them require you to opt out of the others to use one.

The other practical detail worth knowing before you dive into the individual articles: every one of these five is a drop-in replacement for something you already know how to use. next/image still takes a src and produces an <img> under the hood. next/link still renders an <a>. You're not learning a new mental model for each one — you're learning what extra props each one adds on top of the HTML element you already understand, and why the framework needed to get involved to make those props actually do something.

Key Takeaways

ComponentHTML equivalentProblem it solves
next/font<link rel="stylesheet"> / @font-faceLayout shift and slow web font loading
next/form (<Form>)<form>Full-page reloads on simple form submissions
next/image (<Image>)<img>Unoptimized image size, format, and loading
next/link (<Link>)<a>Slow perceived client-side navigation
next/script (<Script>)<script>Third-party scripts blocking the main thread

These five components exist because Next.js can see things a plain HTML tag can't: the build pipeline, the route tree, the render lifecycle. If you take one thing from this overview before reading the dedicated articles, let it be this — reach for the built-in version by default, and only step outside it when you have a specific, concrete reason a third-party or hand-rolled equivalent needs to do something these five genuinely can't.

Tags :
Share :

Related Posts

Can Next.js Be Used with GraphQL?

Can Next.js Be Used with GraphQL?

Next.js and GraphQL are two powerful technologies that have gained significant traction in the web development community. Next.js, a React-based fram

Dive Deeper
How does Next.js differ from Create React App?

How does Next.js differ from Create React App?

In the world of modern web development, React.js has emerged as a dominant force due to its flexibility, performance, and extensive ecosystem. Two po

Dive Deeper
How does Next.js handle image optimization?

How does Next.js handle image optimization?

In modern web development, image optimization plays a critical role in enhancing user experience and improving site performance. Large, unoptimized i

Dive Deeper