Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelog
  1. Home
  2. Blog
  3. Comparisons and alternatives
  4. Shadcn Blocks vs Components: When to Start From Which
Auf Deutsch lesen
  1. Blog
  2. Comparisons and alternatives
  3. Shadcn Blocks vs Components: When to Start From Which
Comparisons and alternatives
Comparisons and alternatives

Shadcn Blocks vs Components: When to Start From Which

SR
Serban Rusu · Founder of Wingo UI
Oct 16, 2026 · 11 min read

On this page

0%
  1. What is the difference between shadcn blocks and components?
    1. Why do the words mean different things on each site?
  2. What does each level save you?
  3. What does a block cost to customize?
  4. How do prop-driven blocks change the math?
    1. Component: a pricing table inside your own page
    2. Block: the whole pricing page
    3. Template: a whole page made of sections
  5. When should you start from components, a block or a template?
  6. How do you drop down a level without starting over?
  7. Shadcn blocks vs templates: where do you get each?
  8. What should you do next?
  9. FAQ
    1. What is the difference between shadcn blocks and components?
    2. Does shadcn/ui have official templates?
    3. Are shadcn blocks free?
    4. Can I update a shadcn block after I edit it?
    5. Should I use blocks or build from components?

TL;DR

A component is one reusable piece, such as a button or a pricing table. A block wires several components into a screen or a section, such as a login page, and a template is a whole page or site. Start from a block or a template when you would change only copy, colors and handlers, and from components when you would rewrite the layout or the states.

Published Oct 16, 2026

Source-copy libraries now come in three sizes: components, blocks and page templates. The shadcn blocks vs components question shows up at the start of every new screen. Do you install the login-04 block and edit it, or add button, card and input and build the form yourself? Do you buy a landing page template, or compose sections? Vendors use the words differently, so this post pins down what each one means, what each level saves you, what it costs once your design moves away from the default, and where to start.

We build Wingo UI, so we are not neutral. Facts about shadcn/ui and other vendors link to the page we read and carry the date we checked, October 16, 2026.

What is the difference between shadcn blocks and components?

A shadcn/ui component is one file you import everywhere, and a block is a set of files that composes components into a screen. The difference is written into the registry: each item in the registry-item.json schema (opens in a new tab) has a type, and the docs describe registry:ui as "UI components and single-file primitives" and registry:block as "complex components with multiple files."

The registry files show what that means in practice. When we fetched the new-york-v4 registry:

  • A component such as button is one registry:ui file. It lands in components/ui/button.tsx and every screen imports it.
  • A block such as login-01 has two files. A registry:page file is written to app/login/page.tsx, a registry:component file to components/login-form.tsx, and the block lists button, card, input, label and field as registry dependencies, so the CLI installs those too.
  • A bigger block such as dashboard-01 writes 11 files (a page, a data.json and nine components), adds seven npm packages (four @dnd-kit packages, @tabler/icons-react, @tanstack/react-table and zod) and pulls in 19 components.

So a block is a composition with an opinion about layout, and sometimes about routing: login-01 decides your login lives at /login. The install command is the same for both: npx shadcn@latest add button or npx shadcn@latest add login-01.

Templates are the third level, and shadcn/ui does not ship them. The official blocks page (opens in a new tab) has no templates section. Searches for shadcn templates or shadcn page templates land on third-party products: whole pages or whole sites built on shadcn/ui, usually downloaded as a project instead of added with the CLI.

Why do the words mean different things on each site?

Each catalog draws the lines in a different place, so the same word covers different sizes:

Source"Component""Block""Template"
shadcn/ui (opens in a new tab)One primitive file (registry:ui)A screen or a large part of one: login, sign-up, sidebar, dashboardNone
shadcnblocks (opens in a new tab)An extra variant of a primitive: buttons, forms, dialogs, data tablesA page section: hero, feature, pricing, contact, application shellA multi-page marketing site for Next.js, most also for Astro, downloaded as a zip
Wingo UIOne file in components/uiA whole app screen (login, pricing, settings, checkout) or a marketing section (hero, FAQ)A whole website page (landing, contact, blog, legal) composed of sections, listed on /templates

When someone compares blocks vs templates, check whose vocabulary they use. A shadcnblocks block is usually one section of a page, while a shadcn/ui block is often a whole screen.

What does each level save you?

Each step up saves you layout and wiring decisions, and makes more of them for you.

LevelWhat you getWhat you still writeTypical size
ComponentBehavior, accessibility, states and styling for one controlLayout, data flow, every screen state, copyOne file
BlockA screen or a section with its layout and the parts wired togetherYour data, your handlers, your copy, and whatever the block left out2 to 11 files in the shadcn/ui examples above
TemplateA full page with sections, sample content and navigationContent, links, the backend behind formsA page plus the sections it uses, or a whole project

The work saved is different at each level. A component saves you the hard part of one control: focus trapping in a dialog, the roving tab index in a menu, the price that animates when a toggle flips. A block saves you assembly: which fields go where, the spacing between them, the empty and error states somebody already thought of. A template saves you design decisions across a page: section order, rhythm, which band is gray.

What does a block cost to customize?

A block costs the distance between its flow and yours, and the official shadcn/ui blocks keep that cost visible because they are short markup with fixed copy.

Here is what npx shadcn@latest add login-01 writes, as listed in its registry file:

txt
app/login/page.tsx # registry:page, renders <LoginForm />
components/login-form.tsx # registry:component, about 70 lines
components/ui/button.tsx # plus card, input, label, field

LoginForm accepts only className and the rest of a div's props. The title, the placeholder, "Forgot your password?" and "Login with Google" are strings in the JSX. The <form> has no submit handler, no validation and no error state. That is a fair choice for a free starting point: the file is short, readable and yours. It also means every change is an edit to that file:

  • Copy, colors and spacing: cheap. Change the strings and classes.
  • Behavior: you write it. Submit handling, field errors, a failed sign-in alert, a loading state, a password reset view and a code step are all new code.
  • Updates: you own the merge. The shadcn CLI (opens in a new tab) either keeps your file or overwrites it (--overwrite), and add --diff shows a 2-way diff that cannot say which lines are yours. Our guide to updating shadcn components without losing edits walks through the 3-way merge that fixes this.

If your login is email and password with one social button, login-01 is a few minutes of edits. If you need magic links, two-step codes and password recovery, you write most of the screen yourself, and the block helped with the first 70 lines.

How do prop-driven blocks change the math?

A prop-driven block moves the common changes to the call site, so the file stays as shipped and updates stay cheap. That is how Wingo UI builds its blocks. The trade is size: our Login Page block is 1,617 lines plus a 180-line layout file, against the 70 lines of login-01. You will not read it in one sitting, and rewriting its internals is a bigger job than editing a short form.

What you get for that size is the flow login-01 leaves out, behind props: password, magic link and emailed code methods, a two-step code after the password, a reset view, resend cooldowns and the error alert. A handler that throws an Error shows its message in the form.

tsx
// app/(auth)/login/page.tsx
"use client";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { LoginPage, type SignInValues } from "@/components/blocks/login-page";
async function post(url: string, body: unknown) {
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.message ?? "Something went wrong. Try again.");
}
}
export default function LoginRoute() {
const router = useRouter();
return (
<LoginPage
linkComponent={Link}
methods={["password"]}
twoFactor
providers={[]}
registerHref="/sign-up"
onSignIn={(values: SignInValues) => post("/api/auth/sign-in", values)}
onVerifyCode={(code) => post("/api/auth/two-factor", { code })}
onForgot={(email) => post("/api/auth/forgot", { email })}
onReset={(password) => post("/api/auth/reset", { password })}
onSuccess={() => router.push("/app")}
/>
);
}

The pitfall is the flip side of a finished zero-prop render: every handler you do not pass is simulated. Leave out onVerifyCode and the two-step view accepts 123456. Leave out onForgot and the reset request resolves without sending anything. Before you ship, check that each method and view you turn on has its handler.

Here is one pricing screen at all three levels.

Component: a pricing table inside your own page

The Pricing Table is one component. It owns the plans, the Monthly / Yearly toggle, the rolling prices and the phone carousel. You own the page around it.

tsx
// app/(marketing)/pricing/page.tsx
"use client";
import { PricingTable, type PricingPlan } from "@/components/ui/pricing-table";
const plans: PricingPlan[] = [
{ id: "free", name: "Free", price: 0, features: ["3 projects", "Community support"] },
{
id: "pro",
name: "Pro",
price: { monthly: 12, yearly: 120 },
featured: true,
features: ["Unlimited projects", "Automations", "Priority support"],
cta: { label: "Start free trial", href: "/sign-up?plan=pro" },
note: "14 days free, no card",
},
{ id: "business", name: "Business", price: { monthly: 24, yearly: 240 }, features: ["SSO", "Audit log"] },
];
export default function PricingRoute() {
return (
<main className="mx-auto max-w-5xl px-4 py-16">
<h1 className="text-3xl font-semibold tracking-tight">Pricing</h1>
<PricingTable plans={plans} defaultPeriod="yearly" className="mt-10" />
</main>
);
}
Flip Monthly and Yearly and watch the prices roll. In a narrow frame the plans become a carousel that starts on the featured plan
$ npx wingo-ui@latest add pricing-table
ProPricing table docs

Block: the whole pricing page

The Pricing Page block composes that table with a currency switch, a comparison table, customer quotes, an FAQ and a closing band. Your plans and FAQ go in as data, and turning a section off is a boolean.

tsx
// app/(marketing)/pricing/page.tsx
"use client";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { PricingPage } from "@/components/blocks/pricing-page";
export default function PricingRoute() {
const router = useRouter();
return (
<PricingPage
linkComponent={Link}
header={false}
footer={false}
showTestimonials={false}
currencies={["USD"]}
faqs={[{ question: "Can I cancel anytime?", answer: "Yes. Your plan stays active until the end of the period." }]}
onSelectPlan={(planId, period, currency) =>
router.push(`/sign-up?plan=${planId}&period=${period}&currency=${currency}`)
}
/>
);
}

header={false} and footer={false} let the page sit inside your own site layout, and a single entry in currencies hides the currency switch. Leave out plans and the sample plans show, which is handy while you wire the data and easy to ship by mistake. Return a promise from onSelectPlan and the plan's button keeps its spinner until it settles.

Switch the period and pick a plan: its button spins while onSelectPlan runs. On a phone, the comparison table becomes a plan picker that shows one plan at a time
$ npx wingo-ui@latest add pricing-page
ProPricing Page docs

Template: a whole page made of sections

The Landing Page template sits one level higher. It renders a hero, logos, a feature grid, a product tour, numbers, quotes, a pricing teaser, an FAQ and a closing band, each one a marketing section you can also install on its own, such as the Hero Section.

tsx
// app/(marketing)/page.tsx
"use client";
import Link from "next/link";
import { LandingPage } from "@/components/templates/landing-page";
export default function HomeRoute() {
return (
<LandingPage
linkComponent={Link}
design="minimal"
ctaTone="brand"
showStats={false}
labels={{
heroTitle: "Invoices your clients pay on time",
heroDescription: "Send, track and chase invoices from one inbox.",
}}
/>
);
}

design switches the look of every section at once (classic, bold, editorial or minimal), and per-section overrides such as heroProps still win over it.

Scroll from the header to the footer: the product tour switches with tabs, the gray bands alternate, and the pricing teaser rolls its prices when you flip the period
$ npx wingo-ui@latest add landing-page
ProLanding Page docs

When should you start from components, a block or a template?

Start at the highest level where you would change only content, copy, colors and handlers. If you would rewrite the layout or the states, start one level down.

  • Start from a block for solved screens. Sign-in, sign-up, pricing, settings, checkout and error pages work the same way in most products, and they have many states (errors, loading, codes, empty lists) that are easy to forget. Our shadcn login page and shadcn pricing page guides list those states in detail.
  • Start from a template for marketing pages. A landing, contact or FAQ page has a fixed design and changing content. A template gets the rhythm right, and you replace the words.
  • Start from components for the core of your product. The editor, the board, the dashboard that only your app has. A block designed for someone else's product will fight you there, and the components carry the hard parts anyway.
  • Start from components when your design system is far from the default. If your spacing, type scale and radius differ from the block's, you will touch every line of it.
  • Start from a block for a prototype, even a poor match. A working screen shows you which states you need within an afternoon. Then decide whether to keep it or rebuild it from components.

Most real apps mix all three: a template for the home page, blocks for auth and pricing, and components for the product itself.

How do you drop down a level without starting over?

Use the pieces a block is built from, so leaving the block does not mean leaving its design. The Login Page block exports its layout as AuthFrame: a form column that fills a phone screen, with a hero beside it from 1024px. An invite or sign-up page can put its own form in the frame and still match the login screen. AuthFrame is a client component itself, so the page below can stay a server component.

tsx
// app/(auth)/invite/page.tsx
import { AuthFrame } from "@/components/blocks/login-page-frame";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
export default function InviteRoute() {
return (
<AuthFrame
layout="split"
heroLabel="About Acme"
hero={<p className="text-lg font-medium">Your team is already here.</p>}
>
<form action="/api/invites/accept" method="post" className="flex flex-col gap-4">
<h1 className="text-2xl font-semibold tracking-tight">Join Acme</h1>
<Input name="name" label="Full name" autoComplete="name" required />
<Input name="password" type="password" label="Password" autoComplete="new-password" required />
<Button type="submit" fullWidth>
Accept invite
</Button>
</form>
</AuthFrame>
);
}

Templates work the same way. If the landing page is mostly right, keep it and override a section through its *Props. If it is far off, compose the sections you want yourself with npx wingo-ui@latest add hero-section faq-section cta-section.

Shadcn blocks vs templates: where do you get each?

The official shadcn/ui registry is the free option with no templates, shadcnblocks has the largest catalog of sections and templates, and Wingo UI ships fewer, prop-driven blocks. Checked on October 16, 2026.

SourceComponentsBlocksTemplatesPriceHow it installs
shadcn/ui (opens in a new tab)61 registry:ui items in the new-york-v4 registry97: 70 chart variants, 16 sidebars, 5 login, 5 sign-up, 1 dashboardNoneFree, MITnpx shadcn@latest add
shadcnblocks (opens in a new tab)2,154+2,310+ in the paid plans (2,478 listed on its blocks page)21, all for Next.js 16 and most also for Astro 6; one is free$149, $299 or $399 one-time; templates in the $299 and $399 plans, or from $79 eachBlocks with the shadcn CLI; templates as a zip
Wingo UI22624 screen blocks and 20 marketing sections4575 of 352 items free; Pro $8 a month, $80 a year or $150 lifetimenpx wingo-ui@latest add, updates with a 3-way merge

The Wingo UI numbers come from our registry, release 1.9.0. The Login Page, Pricing Page, Pricing Table and Landing Page are Pro; the contact and FAQ page templates are free, along with basics such as button, input and card.

Where the others are the better pick:

  • You want free, short files you will edit anyway: the official shadcn blocks. They are small enough to read in a minute, and the license costs nothing.
  • You need a large choice of marketing sections, or an Astro site: shadcnblocks has far more variants than the other two and ships Astro editions of most of its templates.
  • You want blocks you configure through props, that behave on phones and that you can update after editing: that is the case Wingo UI is built for. For the wider field, our shadcn alternatives guide compares 14 libraries, and the Comparisons and alternatives category has the head to head posts.

What should you do next?

Take the screen you are about to build and apply the rule above: would you change only content and handlers, or the layout too? If it is a solved screen, open the Login Page or Pricing Page docs and try the props in the playground before you install anything. Both are part of Wingo UI Pro, see pricing. If you want to start from free pieces, npx wingo-ui@latest add button input card gives you the components the blocks are built on.

Components in this post

  • Login Page

    A React login page with password, magic link or code sign-in, Google, Apple and Microsoft buttons, two-step codes and password recovery.

    Pro
  • Pricing Page

    A React SaaS pricing page: plans with monthly or yearly and USD or EUR switches, a comparison table, quotes, an FAQ and a closing call.

    Pro
  • Landing Page

    A SaaS home page: hero with a drawn product shot, logos, bento features, product tour, numbers, quotes, pricing teaser, FAQ and CTA.

    Pro
  • Pricing table

    A React pricing table: plans side by side with a monthly / yearly switch whose prices roll, a featured plan and a full comparison table.

    Pro

FAQ

What is the difference between shadcn blocks and components?

A shadcn/ui component is a single file, such as button.tsx, that you install once and import everywhere. A block is a multi-file item that composes components into a screen: login-01 writes app/login/page.tsx and components/login-form.tsx, and installs button, card, input, label and field as dependencies.

Does shadcn/ui have official templates?

No. As of October 16, 2026, the official registry has 97 blocks (70 chart variants, 16 sidebars, 5 login, 5 sign-up and 1 dashboard) and no page templates. Full templates come from third parties such as shadcnblocks, which lists 21 (one of them free), or from libraries such as Wingo UI.

Are shadcn blocks free?

The official blocks on ui.shadcn.com are free and MIT licensed, like the components. Third-party block libraries that install through the shadcn CLI are often paid: shadcnblocks starts at $149 one-time as of October 16, 2026.

Can I update a shadcn block after I edit it?

Not automatically. The shadcn CLI either keeps your file or overwrites it, and add --diff shows a 2-way diff that cannot tell your edits from upstream changes. A 3-way merge per file keeps both, and npx wingo-ui@latest update runs that merge for Wingo UI items.

Should I use blocks or build from components?

Use a block when its flow matches yours and you would mostly change copy, colors and handlers. Build from components when you would rewrite the layout or the states, because editing someone else's screen that far costs more than composing your own.

  • shadcn/ui
  • Blocks
  • Templates
  • Comparisons
  • React

Share

SR

About the author

Serban Rusu

Founder of Wingo UI

Serban Rusu founded Wingo UI. He builds its component library, CLI and MCP server, and writes about React interfaces for phones and AI coding agents.

More from Serban
Keep reading

Related posts

All posts
Comparisons and alternatives

Tailwind Plus Alternatives for React Apps in 2026

Tailwind Plus alternatives after sign-ups closed in September 2026: free and paid React kits compared on license, price, code format, updates and mobile.

SRSerban Rusu·Oct 13, 2026·9 min read
Comparisons and alternatives

v0 vs Claude Code for UI: Ownership, Screens and Cost

v0 vs Claude Code for UI, checked in October 2026: who owns the code, how each keeps sign-in, pricing and settings screens consistent, and what you pay.

SRSerban Rusu·Oct 9, 2026·12 min read
Build it: screens and apps

Nextjs SaaS Landing Page: What Each Section Must Prove

Build a nextjs saas landing page section by section: what the hero, proof, features, pricing and FAQ must prove, what to cut, and how each reads on a phone.

SRSerban Rusu·Oct 16, 2026·11 min read
Newsletter

Get new posts by email

New guides, tutorials and comparisons from the Wingo UI blog, sent when they are published.

No spam. Unsubscribe at any time.

WingoUI

Animated, configurable, mobile-first React components and blocks. Copy the source, make it yours, and let your coding agent build with it.

Product

  • Components
  • Templates
  • Pricing
  • AI agents
  • Theme generator

Resources

  • Docs
  • Blog
  • Changelog
  • Changelog RSS
  • llms.txt

Legal

  • Terms
  • Privacy
  • Refunds
  • License
  • Imprint

Component categories

  • Buttons & Actions
  • Inputs
  • Forms
  • Navigation
  • Overlays
  • Feedback
  • Data Display
  • Tables & Lists
  • Charts & Stats
  • Layout
  • Media
  • AI Kit
  • Text & Effects
  • Mobile
  • Commerce
  • Marketing Sections
  • Blocks
  • Hooks & Utilities

© 2026 Wingo UI

Wingo UI