Next.js vs Framer: The Line Is Accounts, Not Design Quality
Where a hosted builder stops: logins, gated downloads, pages derived from your own catalog. With the Lighthouse table this Next.js storefront measured.
Framer is a hosted visual site builder; Next.js is a React framework you deploy yourself. For a marketing site that is pages, a CMS and forms, Framer ships faster and needs no developer. Next.js wins the moment the site needs accounts, gated content, custom checkout, or pages generated from your own data.
First, the name. "Framer" here means the website builder at framer.com, not the animation library — that was Framer Motion, and it has since been renamed motion and is independent of the builder. If you landed here looking for animation in React, this is the wrong comparison; the two products only share a history.
What follows is written from one side of the line. This storefront is a Next.js marketing site with a commerce layer bolted to it: 111 products in src/data/catalog.ts, entitlement-gated zip downloads, a payment webhook. It started as the kind of site Framer builds well, and the specific things that made the builder route impossible are listed below — with the Lighthouse numbers the code route actually produced, because "faster site" is the claim both camps make and only one of us has to prove.
The comparison that matters
| Axis | Framer | Next.js |
|---|---|---|
| Who builds it | Designer, on a canvas | Developer, in a repo |
| First page live | Same day | After a deploy pipeline exists |
| Hosting | Framer's, included | Yours (Vercel, Cloudflare, a container) |
| CMS | Built in | Your choice — MDX files, Sanity, Postgres |
| Code export / self-hosting | Not supported for HTML self-hosting | It is your code |
| Pages from your own data | Collections, within the builder's model | Any shape you can write a function for |
| Accounts, gated files, custom checkout | Not the product | Route handlers, cookies, your database |
Per-page <head> control | Builder's SEO fields | generateMetadata, JSON-LD, your own sitemap.ts |
| Ongoing cost | Subscription | Hosting plus developer time |
| Who can edit copy on Friday afternoon | Anyone | Whoever can open a pull request |
That last row decides more real projects than performance does, and it favours Framer. A marketing team that can ship a page without a deploy is worth a great deal, and "we'd rather own the code" is not a reason to take that away from them.
Where the line actually is
Not design quality, and not speed — a good Framer site is fast and a careless Next.js site is slow. The line is where your content comes from and what sits behind a login.
1. Pages generated from data you own
This site has 111 product pages. None of them were authored. Each is one entry in a typed array, and the entry generates the page, the cards, the OG image, the JSON-LD and the sitemap row:
// src/data/catalog.ts — one product, abbreviated
{
slug: "asoc-sentinel-landing",
name: "ASoc Sentinel",
seoLabel: "Security Software Landing Page Template",
category: "landing",
status: "available",
pricing: "premium",
latestVersion: "1.0.0",
editions: [{ framework: "nextjs", status: "ready", previewUrl: "…" }],
}
A hosted CMS covers the first layer of that — a collection with a template page is exactly what Framer's CMS is for. What it does not cover is the second layer: the category hub pages here are derived from the catalog rather than hand-listed. A function asks "which available products are in this category and have a ready edition of this framework?" and the hub's contents follow.
That mattered because the hand-listed version silently broke. The hubs used to carry explicit slug arrays, and new products stopped being added to them — 24 products ended up on no hub at all, with no inbound links from the site's own navigation tier. The fix was to delete the arrays and compute the membership, and then to make the test suite fail if any available product lands on zero hubs. A content model you cannot write an assertion against is a content model that drifts.
2. Anything behind a login
Buyers here download versioned zips from private storage. The endpoint reads two query params, checks the session, checks the caller's entitlement slots, enforces a per-user hourly limit, writes an audit row, and only then issues a signed URL that expires:
// src/app/api/download/route.ts
export async function GET(req: NextRequest) {
const { searchParams } = req.nextUrl;
const result = await resolveDownload(
{
productSlug: searchParams.get("product"),
framework: searchParams.get("framework"),
ip: clientIp(req),
userAgent: req.headers.get("user-agent"),
},
deps,
);
if (result.status === 302) return NextResponse.redirect(result.url, 302);
// 401 / 403 / 400 / 404 / 429 all answer with generic bodies
}
The rate limit is derived from what the caller bought rather than being a flat number, because a single-template buyer and an all-access buyer have legitimately different first-day behaviour. That is a product rule expressed in a function. There is no settings panel for it, in any builder, and there is no version of this endpoint that is a page.
This is the half of the comparison that is not a preference. If your site needs it, the builder is out — and if it does not, you are choosing between two tools that both work.
3. What you tell Google changed
sitemap.ts here computes lastModified from real dates — the later of a product's newest changelog entry and the date the storefront's rendering last changed — and the test suite asserts every date is midnight UTC, because a build-clock reading never is. Telling Google that 100-plus URLs changed on every deploy is a checkable false claim, and it costs the crawl scheduling that decides whether a page gets indexed at all.
That is a small, specific thing to care about. It is also the kind of control that only exists when the sitemap is a function in your repository.
The performance claim, measured
Both camps say "faster". Here is what this repo scored, full-page Lighthouse, 2026-08-08, recorded in docs/superpowers/LIGHTHOUSE.md:
| Route | Desktop perf | Mobile perf | A11y | SEO |
|---|---|---|---|---|
/ | 100 | 89–91 | 100 | 100 |
/templates | 100 | 92 | 100 | 100 |
/templates/asoc-admin | 100 | 94 | 100 | 100 |
/pricing | 100 | 99 | 100 | 100 |
/docs | 100 | 98 | 100 | 100 |
/blog | 100 | 97 | 100 | 100 |
/tailwind-shop-template | 100 | 96 | 100 | 100 |
Desktop 100 across all eight routes; accessibility and SEO 100 on both form factors. Two things to take from the table rather than the headline:
Mobile is not 100, and the gap is interactivity we chose to keep. Closing it would mean removing a filterable 111-product grid and a preview modal — a product decision dressed up as a perf fix. We did not do it, and the honest version of the number includes that sentence.
Those scores came from fixes you can only make in code. The largest single win was one prop. The first cover image in a page-opening grid was loading="lazy", so the browser did not discover the page's LCP element until layout ran — 1.67 seconds of load delay, and /templates mobile went 85 → 92 when the first card alone became eager. Image sizing is build-time too: covers are pre-built into WebP derivatives by a script, so there is no request-time image optimizer and no per-image hosting spend.
A Framer site would arrive at a good score differently — their pipeline handles images and loading for you, and for a straightforward marketing site that is a genuine advantage over doing it yourself badly. The point of the table is not that code wins; it is that when you own the rendering, a 1.67-second regression is findable and fixable by you, on a Tuesday, without a support ticket.
The lock-in question, stated accurately
Framer's own help centre says a published site cannot be exported as standalone HTML for self-hosting, because the published output is not fully static and depends on hosting-side services. Their article's own advice is that anyone needing full control of hosting or source code may need a different platform. Third-party exporters exist, including one approved plugin that packages a published site into a code project, but an export is a snapshot — not the project you were editing.
So the trade is real and it is not hidden: you are renting the rendering layer in exchange for not building it. That is a fine trade for a site whose job is to explain a product. It is a bad trade for a site that is the product.
Which one to pick
| Your situation | Pick |
|---|---|
| Marketing site, non-technical team owns the copy | Framer |
| Design-led brand site, heavy motion, no login | Framer |
| Campaign or launch page needed this week | Framer |
| Pages generated from your own catalog or database | Next.js |
| Accounts, paid downloads, entitlements, custom checkout | Next.js |
| You need to own the HTML, the headers and the sitemap logic | Next.js |
| A marketing site now, a product later | Next.js, or accept a rebuild |
The last row is the one worth sitting with. "We'll move it later" is a real plan with a real cost: the content moves by hand, the URLs have to be preserved deliberately, and the rankings are at risk during the switch — which is its own project, covered in migrating frameworks without losing rankings.
Troubleshooting the decision
| Objection | Honest answer |
|---|---|
| "Next.js is overkill for a landing page" | Often true. A single page with a form does not need a framework — but a template or starter removes most of the setup that makes it feel like overkill |
| "Framer can't rank" | It can. On-page SEO is content, headings and metadata, and the builder exposes those. What it does not give you is programmatic page generation or sitemap logic |
| "We'll just export the Framer site if we outgrow it" | Self-hosted HTML export is not supported; third-party exporters produce a snapshot, not a project |
| "Our team can't edit a Next.js site" | They can edit Markdown or a CMS. This blog is MDX files, and non-code content lives in typed data files for exactly this reason |
| "Code means better Core Web Vitals" | Only if you do the work. Desktop 100 above came after an image-variant pipeline and an LCP priority fix, not for free |
FAQ
Is Next.js vs Framer even a fair comparison? Only at the marketing-site layer, which is where the searches come from. They are different categories — one is a framework, the other a hosted builder — and they genuinely compete for one job: a company's public site. Past that job the comparison stops meaning anything, because only one of them does accounts, gated files and derived pages at all.
What about Framer vs Framer Motion?
Different products. Framer is the website builder; Framer Motion was the React animation library, now published as motion and usable in any React app, Next.js included. You can use the animation library inside a Next.js site, which is why so many results for this query are actually about that pairing rather than a choice.
Can I use both? Yes, and it is a common split: marketing pages on the builder under the root domain, the application on Next.js under a subdomain or a path. The cost is two codebases, two deploy stories and a shared design system that drifts. It works best when the boundary follows a real one — a brochure site and a product — rather than cutting through one site's navigation.
How much of a Next.js marketing site is boilerplate? Most of the first week: layout, metadata, sitemap, robots, OG images, dark mode, a form endpoint. That is precisely what a template collapses, and it is why the comparison is less lopsided on effort than it looks — the gap between "canvas" and "repo" is widest on day one and narrows fast. The adjacent decisions are covered in Webflow vs Next.js and WordPress vs Next.js.
Templates in this post
ASoc Sentinel (a security-suite landing page), ASoc Signal (an AI voice and image studio site) and ASoc Sterling (a wealth-management marketing site) are the day-one shortcut described above — the layout, metadata, sitemap and dark-mode work already done, in code you own.
Browse the full sets: Next.js landing page templates, Tailwind landing page templates. For the neighbouring builder comparisons, see Webflow vs Next.js and Astro vs Next.js for a marketing site; for moving an existing site across, framework migration without losing rankings.
