Copy-Paste or npm Install? Choosing Components
The decision is about ownership
"Copy the component" and "install the package" describe two different ways code enters a project. Neither is automatically safer or easier. The useful question is what your team wants to own after the component is in the app: its source, its upgrade path, or both.
Copying a component places its source in your repository. You can change it directly and review the diff like other app code. Installing a package gives your app a dependency on code maintained and released elsewhere. You work through the package's public API, and updates arrive as version changes.
Choose based on your team's maintenance habits and the component's change surface. Avoid treating a distribution preference as a universal rule.

What copying gives you
An open-code or copy-paste workflow starts from source files that are added to your project. shadcn/ui describes its approach as open code: users receive component code they can modify, and its CLI distributes those files into projects. The code is in your tree, so you can inspect the implementation, change it, and review its behavior alongside the rest of the app.
That can fit when a component needs substantial product-specific changes, when your team prefers to review source diffs instead of dependency releases, or when the component must be adapted to a repository's existing conventions. It also helps when the app needs a small, deliberate subset of a larger component set.
The tradeoff is maintenance ownership. If upstream changes the component, your local copy does not silently become the new version. Your team must decide whether to compare, port, or defer that change. Keep a note of the original source and version or commit, retain license and attribution notices, and document meaningful local changes. Those records make a future security fix easier to evaluate.
A copied file still depends on the packages it imports. "Copy-paste" does not mean dependency-free. Inspect imports and installation instructions, and add only the packages the component actually needs.
12 production screens. Login and database wired.
The SaaS Dashboard Kit includes login, a database, and a working dashboard. Live demo at saas.otf-kit.dev.
What installing a package gives you
A package workflow keeps the component implementation in a dependency. Your app imports an exported API, and your package manager records the dependency in the manifest and lockfile. npm documents that npm install uses a compatible package-lock.json to reproduce resolved versions when the lockfile satisfies the declared ranges.
This can suit a shared component used across multiple apps, a team that wants one maintained implementation, or a codebase that already reviews dependency updates through a lockfile and pull request. The package boundary can also make ownership clear: application code consumes the supported API, while maintainers own the package internals.
The tradeoff is that a local change inside the installed package is not a durable customization point. Editing files under node_modules can disappear on reinstall or upgrade. Prefer documented props, extension points, wrappers, or a maintained fork. If none can express the required behavior, copying a component may be simpler—but first check whether the package license and project policy permit that route.
A version range alone is not a review. Read release notes, inspect the resolved diff, run the relevant checks, and merge upgrades through the same review process as other code. A lockfile helps record what was installed; it does not tell you whether the update is safe.
Compare the ongoing work, not just the first install
| Question | Copy source into the app | Install a package |
|---|---|---|
| Where is the implementation reviewed? | In the application repository | In the package repository, with the app reviewing version changes |
| How do local changes work? | Edit the owned file and test it | Use the public API, wrapper, extension point, or fork |
| How do upstream fixes arrive? | Your team compares and ports them | Your team evaluates and adopts a release |
| What should the team record? | Source, version or commit, license, and local changes | Package version, lockfile resolution, release notes, and upgrade checks |
This is a workflow comparison, not a claim that one model always has lower risk. A copied component can drift from upstream; a package can change in ways that break an integration. In both cases, keep the origin visible, test the behavior your app relies on, and assign someone responsibility for reviewing changes.
Decide component by component
Start with the component that creates the most maintenance concern. Ask:
- Will the team need to change the implementation, or can the supported API express the design?
- Do multiple applications need the same implementation and upgrade cadence?
- Who will notice and evaluate upstream security and compatibility fixes?
- Does the team have a reliable review path for package updates?
- Does copying comply with the upstream license and your organization's policy?
- Can the component and its transitive dependencies be checked in the project's build and test setup?
If customization is likely and the team is willing to maintain a local source copy, open code may be a good fit. If consistency and shared upgrades matter more, a package can fit better. For a mixed application, different components can have different answers, provided the team records why and knows who owns each copy.
Do not design an imaginary migration command into the plan. Moving from one model to another requires comparing the actual source, APIs, dependencies, and license terms. Make the decision for a real component and verify the destination with a small change before applying the pattern across the app.
Keep agent instructions close to the implementation
When an AI coding agent edits UI code, the same ownership decision matters: should it modify a component in the repository, or call a package API? Put that boundary in versioned project guidance and point the agent to the actual component and verification steps. Keep task-specific work in the prompt. After the change, inspect the diff and run the checks that protect the behavior; a clear instruction file does not replace review.
Tool support differs by product and configuration. For example, OpenCode documents AGENTS.md as its project instruction file. Cursor documents .cursor/rules as version-controlled project rules, and calls .cursorrules a legacy format. Check the current documentation and your team's tool setup before assuming one file is read everywhere.
OTF's delivered kits as of 15 October 2026 are SaaS Dashboard, Fitness, and Arcade. Current kit materials include AGENTS.md, CLAUDE.md, .cursorrules, and between 22 and 27 task prompts depending on the kit. These are starter-repository materials; they do not mean OTF provides a separate component package-and-copy service. The SaaS Dashboard documentation describes its app stack and conventions if you need an editable application foundation.
OTF's OpenCode example reports: "On 13 October 2026, the kit's own type-check passes in a fresh install. Our test change added no type errors." That dated sentence describes the type-check result; do not infer from it that the generated page ran in an app or that broader tests passed.
Make the maintenance owner explicit
Before adopting either format, write down who handles upstream changes, where local modifications are allowed, and how the team verifies updates. For copied files, preserve provenance and review upstream changes deliberately. For packages, keep the manifest and lockfile in review and avoid undocumented edits to installed files. Revisit the choice when the component's ownership or reuse needs change.
The practical answer is not "copy everything" or "install everything." Choose a maintenance path your team can actually follow, then make that path visible to the next developer and the next coding session.
Sources
- shadcn/ui, "Introduction" (checked 15 October 2026).
- shadcn/ui, "Components JSON" (checked 15 October 2026).
- npm, "npm install" (checked 15 October 2026).
- OpenCode, "Rules" (checked 15 October 2026).
- Cursor, "Rules" (checked 15 October 2026).
- OTF, SaaS Dashboard kit documentation (checked 15 October 2026).
- OTF, current kit catalog (checked 15 October 2026).
- OTF, "OpenCode example" (dated 13 October 2026; checked 15 October 2026).
Start with a kit that fits
For an editable app foundation, explore the SaaS Dashboard kit. Or start here to choose a template that fits your project.
Ship the product, not the setup.
- 12 production screens — auth, team, analytics, and settings
- Login and a real database are wired in
- AI configs pre-tuned so your agent extends instead of regenerates
Ship your first screen tonight — free starter in your inbox
The quickstart, the SDK repo and the live kit demos, on this screen and in your inbox.
No spam. Unsubscribe any time.