CLI tool
ObservedObserver/streamlit-shadcn-ui avatar
ObservedObserver/streamlit-shadcn-ui

streamlit-shadcn-ui 1.0: shadcn components without iframes, but at a migration cost

Using shadcn-ui components in streamlit

1,151 stars92 forksTypeScriptMIT

At a glance

What is it?
A V2-only release that renders shadcn/ui components in Streamlit's Shadow DOM, removing iframe clipping. It brings a new API and drops the V1 namespace, so existing 0.1.x users must plan a migration.
Who is it for?
Adopt streamlit-shadcn-ui 1.0 if you build Streamlit apps that need shadcn's visual language and you can tolerate a V2-only API with no iframe fallback. Do not adopt it if you rely on the 0.1.x V1 namespace or native Streamlit elements inside component trees, because neither is supported.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What this project actually solves

Streamlit's default widgets have a distinct look, and matching a design system like shadcn/ui normally means fighting CSS or embedding iframes. This package solves that by bringing shadcn components into Streamlit as native V2 components. The README is explicit: components render without an iframe, using Streamlit's isolated Shadow DOM runtime. The practical payoff is that overlays like Select, Dropdown Menu, Popover, Hover Card, Date Picker, and Alert Dialog are not clipped by the Streamlit layout. If you have ever had a dropdown cut off inside a Streamlit container, that is the specific pain this project targets. It is for Python developers who want shadcn's visual polish without writing a separate React frontend or maintaining a custom component from scratch.

The V2 architecture: no iframe, no V1 namespace

Version 1.0 is a deliberate break. The README states it is a V2-only release, backed by Base UI, React 19, Tailwind CSS 4, and Streamlit's isolated Shadow DOM runtime. The production path is documented as Python API to Streamlit Components V2 adapter, then to an owned generated shadcn component, then to a Base UI behavior primitive. The key point is that shadcn owns the palette, radius, typography, focus rings, and interaction styling, while Streamlit provides the surrounding light/dark color scheme, language, and direction. The package does not restyle shadcn to look like Streamlit, which is a clear design stance. The V1 iframe implementation and the streamlit_shadcn_ui.v1 compatibility namespace are not shipped. That means any code written against 0.1.x will not run on 1.0 without changes, and the README says applications that cannot migrate should remain on the last 0.1.x release. This is a hard cut, not a soft deprecation.

Getting started: install, Python version, and first widgets

Installation is a single pip command: pip install streamlit-shadcn-ui. The README lists Python 3.10 or newer and Streamlit 1.60 or newer as requirements. The quick start shows a select, a switch, and a button, all called as plain Python functions. The select returns the original Python values, not display labels, which is a useful detail for code that stores choices as enums or IDs. The README also notes that key is optional for ordinary calls, but you should add a stable key when components are created in a loop, can be reordered, or need identity that survives argument changes. The example uses f"project_{project.id}" as a key. This is a concrete, actionable rule for avoiding state collisions. For more complex layouts, the elements API lets you build a nested tree with context managers, as shown with el.card, el.card_header, and el.card_content, and then read values like email.value and save.clicked.

The elements API: one React tree instead of many components

The most distinctive part of this release is the ui.elements aggregate path. Instead of calling ui.select and ui.button as separate V2 components, you create one nested, stateful React tree from typed Card, layout, content, input, choice, and action nodes. The README example shows a settings form built with with ui.elements(key="settings") as el, then el.card, el.card_header, el.heading, el.input, and el.button. The returned values are accessed as attributes, like email.value and save.clicked. This is a different mental model from the ordinary helper calls, which are independently isolated V2 components. The documentation mentions a technical assessment and a homepage-card use case, so the project is clearly investing in this pattern. However, the README also warns that neither path accepts native Streamlit elements as React children. If you want to embed st.plotly_chart inside a card, you cannot do it through this API. That is a real constraint for mixed apps.

Migration from 0.1.x: what breaks and what the mapping looks like

The README is honest about the migration cost. It lists the most common source changes: button(text=...) becomes button(label=...), grouped V1 checkboxes become ordinary composition of scalar checkboxes, with ui.card(...) becomes Streamlit layout around a declarative Card, low-level trigger/content helpers and experimental element() trees are removed, and component return values and callbacks replace reliance on raw session-state transport dictionaries. There is a full compatibility matrix in docs/v2-compatibility-matrix.md. This is not a trivial rename. The shift from with ui.card to Streamlit layout means your HTML structure changes, not just the function name. If you have a large 0.1.x codebase, you should budget for a real refactor, not a find-and-replace. The README's advice to stay on 0.1.x if you cannot migrate is the right call, but it also means you miss out on the iframe-free rendering and overlay fixes.

Limitations and edge cases: what the README does not promise

The README does not claim every shadcn component is available, but the component list is broad: select, dropdown_menu, radio_group, button, link_button, breadcrumb, pagination, checkbox, input, textarea, input_otp, slider, switch, toggle, toggle_group, calendar, date_picker, tabs, accordion, collapsible, popover, hover_card, alert_dialog, alert, avatar, badge, badges, card, metric_card, aspect_ratio, progress, scroll_area, separator, skeleton, and table. Missing from that list are data-heavy components like data_table or chart components, which are common in shadcn ecosystems. The README also does not mention theming customization beyond what shadcn provides. The architecture section says the package does not restyle shadcn to look like Streamlit, so if you want to change radius or primary color, you likely need to edit the generated frontend source, which is not documented in the README. Another limitation is the Python version floor: 3.10 and Streamlit 1.60 are recent, so teams on older LTS environments may be blocked. The V2-only nature also means no fallback if Streamlit's V2 runtime has a bug in your specific browser.

Alternatives and how they differ

The obvious alternative is to use Streamlit's built-in components with custom CSS. That approach is simpler and requires no extra dependency, but it does not give you shadcn's behavior primitives like dropdown menus or hover cards, and you still face the clipping problem. Another alternative is to build a custom Streamlit component yourself in React, which gives you full control but requires maintaining a separate frontend build, a task this package removes. The README references Base UI as the behavior layer, so a third alternative is to use Base UI directly in a bespoke component, but then you lose the shadcn styling that this package owns. The key difference is that streamlit-shadcn-ui bundles both the styling and the behavior, while the alternatives force you to choose one or write your own integration. If your app is pure Streamlit and you only need minor visual tweaks, custom CSS is lighter. If you need shadcn's full interaction set, this package is more direct.

Maintenance and upgrade cost

The project is under active development, with releases 1.0.0, 1.0.1, and 1.1.0 all in August 2026. The changelog is tracked in CHANGELOG.md, and the 1.1.0 release notes are in docs/releases/1.1.0.md. The README lists development commands like ./scripts/frontend_v2.sh and ./scripts/verify_v2_release_source.sh, which suggests a reproducible build process. The license is MIT, so there are no copyleft obligations, but you are responsible for tracking upstream changes to shadcn, Base UI, React, and Tailwind, since the package pins its own generated source. The architecture keeps the component path recognizable and upgradable, but that is a claim, not a guarantee. For a production app, you should pin the streamlit-shadcn-ui version and test after each upgrade, because the API changed significantly between 0.1.x and 1.0, and future major versions could do the same. The README's migration guide is a good sign, but it also means the project is willing to break things.

Editorial conclusion

Adopt streamlit-shadcn-ui 1.0 if you build Streamlit apps that need shadcn's visual language and you can tolerate a V2-only API with no iframe fallback. Do not adopt it if you rely on the 0.1.x V1 namespace or native Streamlit elements inside component trees, because neither is supported. Before committing, verify that your Python and Streamlit versions meet the 3.10 and 1.60 minimums, run the compatibility matrix against your existing code, and test the overlay behavior (Select, Dropdown Menu, Popover) in your target browser, since the Shadow DOM and top-layer approach may interact differently with your layout.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Community notes

Community notes