Contributions
How to safely customize Frontfriend components in your project and contribute improvements back to the community
Contributions
Frontfriend components are designed to be owned by you. Once you download a component into your project, the source code lives in your repo and you are free to change it however you want. This page covers the two scenarios you will run into:
- Customizing a component for your team only — keep your changes private without breaking future updates.
- Contributing an improvement back — share a useful change with everyone via the public
frontfriend-contributionsrepository.
1. Customizing Components in Your Project
When you run npx frontfriend download <component>, the component is written into your project (typically components/ui/<name>/). From that moment, the file is yours — but there is a catch.
Do not edit the original component file directly. Running npx frontfriend download again (or updating components in bulk) will overwrite your changes. Use the duplicate-and-rename pattern below instead.
The Duplicate-and-Rename Pattern
The safe way to customize a Frontfriend component is to duplicate it, rename it with a proprietary prefix, and edit the copy. The original component stays untouched and continues to receive updates from Frontfriend.
Step 1 — Pick a prefix for your team
Use a short, consistent prefix derived from your company or product name. Two letters is plenty.
| Company | Prefix | Example component |
|---|---|---|
| Acme Corp | Ac | AcInput |
| Globex | Gx | GxButton |
| Stark Industries | Si | SiCard |
Stick to the same prefix across the whole project so any developer can recognize a customized component at a glance.
Step 2 — Duplicate the component
Take the original component and copy it under a new name:
Step 3 — Rename the exported component
Rename the component itself (and its file) to use your prefix:
Step 4 — Update the barrel export
Step 5 — Use it like any other component
Why This Works
- Frontfriend's CLI looks at the registry name (e.g.
input) to decide what to overwrite. Yourac-inputdirectory is invisible to the CLI, so it is never touched. - You can still pull updates for the original
Inputcomponent without conflicts. - Any developer reading the code immediately knows that anything starting with your prefix is owned by your team, not by Frontfriend.
When to Customize Locally
Use this pattern when the change is:
- Specific to your product — e.g. a domain-specific input that masks a tax code.
- A one-off variant that does not generalize to other Frontfriend users.
- Experimental — you want to try something internally before proposing it.
If the change is generic and useful for everyone, jump to the next section instead.
2. Contributing Back to Frontfriend
When you build something that other Frontfriend teams could benefit from, you can contribute it back through the public frontfriend-contributions repository.
This is the official channel for proposing:
- New components that do not yet exist in the registry.
- Enhancements to existing components (new variants, accessibility fixes, bug fixes, performance improvements).
Contributions are reviewed by the Frontfriend team. Approved contributions are merged into the official registry and distributed to all users via npx frontfriend download.
Repository Structure
The contribution repo is organized as a single, flat contributions folder — no separate "proposal" vs "enhancement" trees, just a meta.json tag that tells the reviewers what kind of change you are submitting.
The meta.json Tag
Every contribution carries a meta.json that tells the reviewers what kind of change it is. The type field is the key signal:
For an enhancement, point at the component you are modifying:
| Field | Required | Description |
|---|---|---|
type | yes | "new" for brand-new components, "enhancement" for changes to existing ones |
name | new only | Component name in kebab-case (e.g. stepper, command-palette) |
target | enhancement only | The existing component being modified (e.g. button) |
framework | yes | "react" or "vue" |
author | yes | Your GitHub handle |
summary | yes | One-sentence description of the change |
dependencies | optional | npm packages required by the component |
registryDependencies | optional | Other Frontfriend components this one depends on |
Drop the prefix when you contribute. The Ac/Gx/Si prefix is only for your private fork. When the same component goes into the public registry, use the canonical, unprefixed name (e.g. Stepper, not AcStepper) so it works for every team.
How to Open a Contribution PR
- Fork the
frontfriend-contributionsrepository on GitHub. - Create a branch named after your change:
feat/stepper,fix/button-loading-a11y, etc. - Add your contribution under
contributions/<framework>/<name>/:- The component source file(s).
- A
meta.jsonwith the fields above. - A
README.mdexplaining the use case and key design decisions. - Optional: usage examples in
examples/.
- Open a Pull Request against
mainand fill out the PR template. - Review and iterate with the Frontfriend maintainers in the PR.
- Once approved, the maintainers merge your change into the official registry (
packages/registry/components/<framework>/). It becomes available to everyone vianpx frontfriend downloadon the next release.
Review Criteria
The Frontfriend team reviews contributions against the same standards as core components:
- Semantic tokens only — no hardcoded colors, sizes, or spacing. See Design Tokens.
- Accessibility — keyboard navigation, ARIA roles, focus management, screen reader support.
- Theming — works in light and dark mode out of the box.
- API consistency — props and naming follow existing component conventions (e.g.
variant,size,asChild). - No third-party styling — Tailwind CSS only, no inline styles or CSS-in-JS.
- Type safety — full TypeScript typings for props and return values.
What Doesn't Belong in Contributions
The contribution repo is for generic, reusable components. Do not submit:
- Components that depend on your product's data shape or backend.
- Components hardcoded with your brand identity.
- Forks of existing components with cosmetic differences only — open a discussion first.
If you are unsure whether your change is a fit, open an issue in the contribution repo before writing code. The maintainers will help you decide whether the change belongs upstream or as a private customization.
Decision Tree
Not sure which path to take? Use this quick reference:
| Situation | Path |
|---|---|
| The change is specific to your product or branding | Local fork with prefix |
| You need it shipped today and cannot wait for review | Local fork with prefix |
| The change is a general improvement (a11y, perf, new variant) | Contribute via PR |
| You built a generic component that does not exist in the registry yet | Contribute via PR |
| You are not sure | Open an issue, ask first |
Next Steps
- CLI Reference — Learn the
downloadcommand in detail. - Design Tokens — The semantic token system your contributions must use.
- Troubleshooting — Common issues and solutions.