Add a third-party package
Use a third-party npm package in a section.
Use an npm package in a section.
Prerequisites
Section titled “Prerequisites”- A section to import the package into — Install scaffolds one.
- An island, for anything that touches the browser — Make a section interactive.
Install the package like any npm dependency:
npm i swiperOnly a published version. pack refuses to produce a submission zip when a
dependency uses a local file:/link: protocol — depend on a real published
version, never a path on your own machine.
Where you import it from matters. A client library — a carousel, a map SDK,
anything that touches window or the DOM — is imported inside a "use client"
island, the same as any other browser-only code:
"use client";
import Swiper from "swiper";
export default function Carousel({ slides }: { slides: { id: string; url: string }[] }) { // …}A server-side import — one that lands in the Renderer or a plain component it
imports, not behind "use client" — must stay pure and deterministic: no reads
of the clock, randomness, or the network at render time. A package built for a
browser runtime (it touches window, schedules a timer, generates an id) does
not belong there; move the usage into an island.
A package that ships its own stylesheet is imported by its bare specifier, from the module that renders it — the Renderer’s import graph (the components and islands it imports, transitively) is what the CSS build bundles and harvests for the section’s stylesheet:
"use client";
import Swiper from "swiper";import "swiper/css"; // ← the sanctioned channel: a bare specifier reaches this section's layerA local .css import from that same render path is a different, banned case
— see no-css-import-from-render-path
for the full distinction between the two, and
no-bare-css-import for why a hand-written
stylesheet can’t reach the package’s CSS with its own @import instead.
Complete diff
Section titled “Complete diff”The install and the fences under Steps — the import inside a "use client"
island, and the package’s own stylesheet by its bare specifier — are the whole change.
Verify
Section titled “Verify”Verify with the author loop — a green
check after the install confirms the package resolves, its CSS (if any)
landed in the section’s layer, and the workspace still carries exactly one copy
of React.
Rules that can fire
Section titled “Rules that can fire”single-react— the package pulls in its own copy of react or react-dom.audit-severity— the package carries a high or critical security advisory.no-client-runtime-in-server— the import lands on the render path and the package reaches for state, an effect, or a browser global.no-nondeterminism— the same import reads the clock or generates randomness at render time.no-css-import-from-render-path— you reach the package’s stylesheet through a local.cssimport instead of its bare specifier.no-bare-css-import— you reach it through an@importin a hand-written stylesheet instead.size-island-bundle— the package lands in an island and pushes that section’s browser bundle past its byte budget.
See also
Section titled “See also”- Islands — writing a
"use client"island; a third-party client library is fine inside one, never in a Renderer. template-kit pack— why afile:/link:dependency blocks a submission.single-react— a package that pulls its own copy of React breaks hydration; the installed tree may carry only one.no-css-import-from-render-path— bare package specifier (legal) vs. a local.cssimport (banned) from a section’s render path.no-bare-css-import— why a hand-written stylesheet can’t reach a package’s CSS with its own@importeither.