- Components
- Form
- Native Select
Shadcn Native Select Components
A native select element styled with shadcn/ui. Each variant is equally at home in Radix UI and Base UI projects. Browse our collection of 9 Shadcn Native Select variants.
Default
With placeholder
With icon
With helper text
Tell us what‘s your favorite Select framework
Select with error
Selected option is invalid
Required select
Options groups
Overlapping label
Inset label
Unlock premium components
Explore Shadcn Blocks
Ready-made page sections built with the same components.
Shadcn Native Select Component
The Shadcn Native Select is a styled wrapper around the browser's own <select> element. It looks like the rest of your shadcn/ui form controls, but the option list is drawn by the operating system, which means the familiar wheel picker on iOS, the bottom sheet on Android and full keyboard and screen reader support everywhere, without any JavaScript.
Placeholders, option groups, a leading clock icon, error and required states and two floating label layouts cover most of what a form needs from a shadcn native select. It is a plain HTML element styled with shadcn/ui, React and Tailwind CSS instead of a primitive library, so it behaves the same in Radix UI and Base UI projects, renders in server components and submits with regular forms.
What is the Shadcn Native Select Component?
The shadcn/ui Native Select renders a <select> with its default appearance removed, a rounded background and a chevron icon placed on top of it. Options and option groups are the standard <option> and <optgroup> elements, so everything you know about HTML selects still applies: value, defaultValue, onChange, name, required and disabled.
Choose a native select for mobile heavy forms, long forms with many dropdowns and anywhere you want the lightest possible control. When you need custom option content such as icons, avatars or descriptions, use the Select component instead. If users should type to filter a long list, a Combobox is the better choice, and for two to five visible options, a Radio Group is faster to scan.
Anatomy of the Shadcn Native Select
| Part | Description |
|---|---|
| NativeSelect | A wrapper div with the chevron icon and the styled select inside. className goes to the wrapper, all other props go to the select, and size="sm" makes it shorter. |
| NativeSelectOption | A native option. It uses the system Canvas and CanvasText colors, so the open list always has readable contrast regardless of your page theme. |
| NativeSelectOptGroup | A native optgroup with a label that groups related options under a heading. |
9 Shadcn Native Select Variants
Each native select variant listed here is previewed live at the top of this page, together with its source code and install command.
- Default: A full width select with a list of task statuses, the simplest drop-in replacement for a styled dropdown.
- With placeholder: A disabled empty option as the default value, so the field shows a prompt until the user picks something.
- With icon: A clock icon placed at the start of the field for a time range picker, dimmed together with the field when it is disabled.
- With helper text: A muted hint line under the field that tells users what the choice is for.
- Select with error: An invalid state set with
aria-invalid, which turns the border and ring red, plus an error message withrole="alert". - Required select: A label connected to the select through useId, with a red asterisk that visually marks the field as required. Add the required attribute yourself if the form should enforce it.
- Options groups: Frontend and Backend option groups that separate a long list into labelled sections.
- Overlapping and inset labels: Two label layouts with a disabled placeholder option: a label that sits on the top border of the field, and an inset label placed inside a bordered container above the value.
How to Install the Shadcn Native Select Component
Set up shadcn/ui in your project if you have not already, then add the Shadcn UI Kit registry to your components.json once:
{
"registries": {
"@shadcnuikit": "https://shadcnuikit.com/r/{name}.json"
}
}Then install a native select variant by its name:
npx shadcn@latest add @shadcnuikit/native-select1The same command works with pnpm dlx, yarn dlx and bunx --bun. Each variant has a copy button for every package manager, and the code is added to your project as plain React and Tailwind CSS that you can edit freely.
How to Use the Shadcn Native Select Component
Import the parts from your components/ui folder and use them like a normal select. Give the field a name so it is included when the form is submitted.
import { Label } from "@/components/ui/label"
import {
NativeSelect,
NativeSelectOptGroup,
NativeSelectOption,
} from "@/components/ui/native-select"
export function CountryField() {
return (
<div className="grid w-full max-w-xs gap-2">
<Label htmlFor="country">Country</Label>
<NativeSelect
id="country"
name="country"
defaultValue=""
required
className="w-full"
>
<NativeSelectOption value="" disabled>
Select a country
</NativeSelectOption>
<NativeSelectOptGroup label="Europe">
<NativeSelectOption value="de">Germany</NativeSelectOption>
<NativeSelectOption value="fr">France</NativeSelectOption>
</NativeSelectOptGroup>
<NativeSelectOptGroup label="North America">
<NativeSelectOption value="us">United States</NativeSelectOption>
<NativeSelectOption value="ca">Canada</NativeSelectOption>
</NativeSelectOptGroup>
</NativeSelect>
</div>
)
}Why Use the Shadcn Native Select Component
- Best mobile experience: Phones and tablets open their own optimized picker, which is easier to use than any custom dropdown.
- Zero JavaScript: No portal, no positioning logic and no client state, so it works in server components and loads instantly.
- Accessible by default: Keyboard support, typeahead and screen reader announcements come from the browser.
- Works with plain forms: The value is submitted with FormData and supports native validation such as required.
- Matches your design system: Same height, radius, focus ring and invalid styles as the other shadcn/ui inputs.
Common Native Select Use Cases
- Checkout and address forms: Country, state and shipping method fields that must work well on phones.
- Settings pages: Language, time zone and date format preferences.
- Filters and sorting: Compact sort by and page size controls above lists and tables.
- Sign up and onboarding: Company size, role or industry questions with a fixed set of answers.
- Admin forms: Status and category fields in long internal forms where speed matters.
Customizing the Shadcn Native Select
Remember that className is applied to the wrapper, which is w-fit by default. Pass w-full to stretch it, or target the wrapper from a parent with *:data-[slot=native-select-wrapper]:w-full as the variants on this page do. Use size="sm" for dense toolbars, and style the invalid state by setting aria-invalid. The field colors come from your theme tokens, which you can generate with the free Theme Generator.
The open option list itself is drawn by the operating system, so its styling is limited on purpose. If you need a fully custom list, switch to the Select component.
import {
NativeSelect,
NativeSelectOption,
} from "@/components/ui/native-select"
export function PageSizeSelect({ invalid }: { invalid?: boolean }) {
return (
<NativeSelect size="sm" aria-invalid={invalid} className="w-40">
<NativeSelectOption value="10">10 per page</NativeSelectOption>
<NativeSelectOption value="25">25 per page</NativeSelectOption>
</NativeSelect>
)
}Native Select Accessibility and Keyboard Support
A native select is announced as a combo box or popup button by every screen reader, and the chevron icon is marked aria-hidden. Always connect a visible label with htmlFor and id, link helper or error text with aria-describedby, and use aria-invalid for errors so the state is announced, not only shown in red.
Keyboard behavior is provided by the browser and differs between operating systems. The keys below describe the typical behavior in desktop browsers.
| Key | Action |
|---|---|
| Tab | Moves focus to the select. |
| ShiftTab | Moves focus to the previous focusable element. |
| Space | Opens the option list. |
| ArrowDown | Moves to the next option. On some platforms it changes the value directly while the list is closed. |
| ArrowUp | Moves to the previous option. |
| A letter key | Jumps to the next option that starts with that letter. |
| Enter | Selects the highlighted option and closes the open list. |
| Escape | Closes the open list without a change. |
Native Select Best Practices
- Always use a visible label; a placeholder option disappears as soon as a value is picked.
- Use a disabled empty option as the placeholder when there should be no default choice.
- Group long lists with option groups, and keep options in a logical or alphabetical order.
- Keep option text short, because the native list cannot wrap or show descriptions.
- For fewer than five options that users should compare, use a Radio Group instead.
- Switch to a Combobox when the list is long enough that users want to search it.
Components Related to Native Select
Shadcn Native Select FAQ
Looking for something else? Browse all shadcn/ui components or ready-made UI blocks built with them.















